@abaplint/core
Version:
abaplint - Core API
129 lines • 5.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FunctionalWriting = exports.FunctionalWritingConf = void 0;
const issue_1 = require("../issue");
const _abap_rule_1 = require("./_abap_rule");
const Statements = require("../abap/2_statements/statements");
const Expressions = require("../abap/2_statements/expressions");
const _basic_rule_config_1 = require("./_basic_rule_config");
const objects_1 = require("../objects");
const _irule_1 = require("./_irule");
const ddic_1 = require("../ddic");
const edit_helper_1 = require("../edit_helper");
class FunctionalWritingConf extends _basic_rule_config_1.BasicRuleConfig {
constructor() {
super(...arguments);
/** Ignore functional writing in exception classes, local + global */
this.ignoreExceptions = true;
}
}
exports.FunctionalWritingConf = FunctionalWritingConf;
class FunctionalWriting extends _abap_rule_1.ABAPRule {
constructor() {
super(...arguments);
this.conf = new FunctionalWritingConf();
}
getMetadata() {
return {
key: "functional_writing",
title: "Use functional writing",
shortDescription: `Detects usage of call method when functional style calls can be used.`,
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-functional-to-procedural-calls
https://docs.abapopenchecks.org/checks/07/`,
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
badExample: `CALL METHOD zcl_class=>method( ).
CALL METHOD cl_abap_typedescr=>describe_by_name
EXPORTING
p_name = 'NAME'
RECEIVING
p_descr_ref = lr_typedescr
EXCEPTIONS
type_not_found = 1
OTHERS = 2.`,
goodExample: `zcl_class=>method( ).
cl_abap_typedescr=>describe_by_name(
EXPORTING
p_name = 'NAME'
RECEIVING
p_descr_ref = lr_typedescr
EXCEPTIONS
type_not_found = 1
OTHERS = 2 ).`,
};
}
getMessage() {
return "Use functional writing style for method calls";
}
getConfig() {
return this.conf;
}
setConfig(conf) {
this.conf = conf;
}
runParsed(file, obj) {
var _a, _b;
const issues = [];
let exception = false;
if (obj.getType() === "INTF") {
return [];
}
let definition = undefined;
if (obj instanceof objects_1.Class) {
definition = obj.getClassDefinition();
}
const ddic = new ddic_1.DDIC(this.reg);
for (const statNode of file.getStatements()) {
if (statNode.get() instanceof Statements.ClassImplementation
&& definition
&& ddic.isException(definition, obj)
&& this.conf.ignoreExceptions) {
exception = true;
}
else if (statNode.get() instanceof Statements.EndClass) {
exception = false;
}
else if (exception === false && statNode.get() instanceof Statements.Call) {
if (((_a = statNode.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.MethodCallChain) {
continue;
}
const dynamic = (_b = statNode.findDirectExpression(Expressions.MethodSource)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.Dynamic);
if (dynamic !== undefined) {
continue;
}
issues.push(this.createIssueForStatementNode(file, statNode));
}
}
return issues;
}
createIssueForStatementNode(file, statNode) {
const fixString = this.buildFixString(statNode);
const fix = edit_helper_1.EditHelper.replaceRange(file, statNode.getStart(), statNode.getEnd(), fixString);
return issue_1.Issue.atStatement(file, statNode, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
}
buildFixString(statNode) {
// Note: line breaks from source are lost
const methodSource = statNode.findDirectExpression(Expressions.MethodSource);
let methodSourceStr = methodSource === null || methodSource === void 0 ? void 0 : methodSource.concatTokens();
const methodBody = statNode.findDirectExpression(Expressions.MethodCallBody);
let methodBodyStr = "";
if (methodBody) {
const methodCallParam = methodBody.findDirectExpression(Expressions.MethodCallParam);
if (methodCallParam && methodCallParam.getFirstToken().getStr() === "(") {
// has parameters and parantheses
methodBodyStr = `${methodBody.concatTokens()}.`;
}
else {
// has parameters, but parentheses are missing
methodSourceStr = `${methodSourceStr}( `;
methodBodyStr = `${methodBody.concatTokens()} ).`;
}
}
else {
// no body means no parentheses and no parameters
methodBodyStr = "( ).";
}
return methodSourceStr + methodBodyStr;
}
}
exports.FunctionalWriting = FunctionalWriting;
//# sourceMappingURL=functional_writing.js.map