UNPKG

@abaplint/core

Version:
129 lines 5.36 kB
"use strict"; 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