UNPKG

@abaplint/core

Version:
143 lines (142 loc) 5.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChangeIfToCase = exports.ChangeIfToCaseConf = void 0; const issue_1 = require("../issue"); const Expressions = require("../abap/2_statements/expressions"); const Statements = require("../abap/2_statements/statements"); const Structures = require("../abap/3_structures/structures"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const _irule_1 = require("./_irule"); class ChangeIfToCaseConf extends _basic_rule_config_1.BasicRuleConfig { constructor() { super(...arguments); /** skip specific names, case insensitive regular expression * @uniqueItems true */ this.skipNames = []; } } exports.ChangeIfToCaseConf = ChangeIfToCaseConf; class ChangeIfToCase extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new ChangeIfToCaseConf(); } getMetadata() { return { key: "change_if_to_case", title: "Change IF to CASE", shortDescription: `Finds IF constructs that can be changed to CASE`, // eslint-disable-next-line max-len extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions If the first comparison is a boolean compare, no issue is reported.`, tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide], badExample: `IF l_fcat-fieldname EQ 'FOO'. ELSEIF l_fcat-fieldname = 'BAR' OR l_fcat-fieldname = 'MOO'. ENDIF.`, goodExample: `CASE l_fcat-fieldname. WHEN 'FOO'. WHEN 'BAR' OR 'MOO'. ENDCASE.`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { var _a; const issues = []; const stru = file.getStructure(); if (stru === undefined) { return issues; } for (const i of stru.findAllStructuresRecursive(Structures.If)) { const conds = []; const ifStatement = i.findDirectStatement(Statements.If); if (ifStatement === undefined) { continue; } if (ifStatement.concatTokens().match(/ (abap_true|abap_false)\s*\./i)) { continue; } conds.push(ifStatement === null || ifStatement === void 0 ? void 0 : ifStatement.findDirectExpression(Expressions.Cond)); for (const ei of i.findDirectStructures(Structures.ElseIf)) { conds.push((_a = ei.findDirectStatement(Statements.ElseIf)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Cond)); } if (conds.length === 1) { continue; } const issue = this.analyze(conds); if (issue === true) { const message = "Change IF to CASE"; issues.push(issue_1.Issue.atStatement(file, ifStatement, message, this.getMetadata().key, this.getConfig().severity)); } } return issues; } analyze(conds) { var _a, _b, _c, _d, _e; const tuples = []; for (const c of conds) { if (c === undefined) { continue; } if (c.findFirstExpression(Expressions.CondSub)) { return false; } else if (c.findDirectTokenByText("AND") || c.findDirectTokenByText("EQUIV")) { return false; } for (const compare of c.findAllExpressions(Expressions.Compare)) { const op = (_a = compare.findDirectExpression(Expressions.CompareOperator)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase(); if (compare.getChildren().length !== 3) { return false; } else if (op !== "=" && op !== "EQ") { return false; } const left = (_c = (_b = compare.getChildren()[0]) === null || _b === void 0 ? void 0 : _b.concatTokens()) === null || _c === void 0 ? void 0 : _c.toUpperCase(); const right = (_e = (_d = compare.getChildren()[2]) === null || _d === void 0 ? void 0 : _d.concatTokens()) === null || _e === void 0 ? void 0 : _e.toUpperCase(); tuples.push({ left, right }); } } if (tuples.length === 1) { return false; } let chain = ""; if (tuples[0].left === tuples[1].left) { chain = tuples[0].left; } else if (tuples[0].left === tuples[1].right) { chain = tuples[0].left; } else if (tuples[0].right === tuples[1].right) { chain = tuples[0].right; } else if (tuples[0].right === tuples[1].left) { chain = tuples[0].right; } else { return false; } for (const skip of this.getConfig().skipNames || []) { const reg = new RegExp(skip, "i"); if (chain.match(reg)) { return false; } } for (const t of tuples) { if (t.left !== chain && t.right !== chain) { return false; } } return true; } } exports.ChangeIfToCase = ChangeIfToCase; //# sourceMappingURL=change_if_to_case.js.map