UNPKG

@abaplint/core

Version:
188 lines • 7.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ManyParentheses = exports.ManyParenthesesConf = void 0; const Expressions = require("../abap/2_statements/expressions"); const Statements = require("../abap/2_statements/statements"); const issue_1 = require("../issue"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const _irule_1 = require("./_irule"); const nodes_1 = require("../abap/nodes"); const edit_helper_1 = require("../edit_helper"); class ManyParenthesesConf extends _basic_rule_config_1.BasicRuleConfig { } exports.ManyParenthesesConf = ManyParenthesesConf; class ManyParentheses extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new ManyParenthesesConf(); } getMetadata() { return { key: "many_parentheses", title: "Too many parentheses", shortDescription: `Searches for expressions where extra parentheses can safely be removed`, tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix], badExample: ` IF ( destination IS INITIAL ). ENDIF. IF foo = boo AND ( bar = lar AND moo = loo ). ENDIF. `, goodExample: ` IF destination IS INITIAL. ENDIF. IF foo = boo AND bar = lar AND moo = loo. ENDIF. `, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { const issues = []; const structure = file.getStructure(); if (structure === undefined) { return []; } for (const cond of structure.findAllExpressionsMulti([Expressions.Cond, Expressions.ComponentCond])) { issues.push(...this.analyze(file, cond)); } for (const sub of structure.findAllExpressionsMulti([Expressions.CondSub, Expressions.ComponentCondSub])) { let cond = []; if (sub.get() instanceof Expressions.CondSub) { cond = sub.findDirectExpressions(Expressions.Cond); } else { cond = sub.findDirectExpressions(Expressions.ComponentCond); } if (cond.length !== 1) { continue; } if (cond[0].getChildren().length === 1) { const message = "Too many parentheses, simple"; const children = sub.getChildren(); let startToken = sub.getFirstToken(); let fixText = sub.getChildren()[1].concatTokens(); if (startToken.getStr().toUpperCase() === "NOT") { startToken = children[1].getFirstToken(); fixText = sub.getChildren()[2].concatTokens(); } const fix = edit_helper_1.EditHelper.replaceRange(file, startToken.getStart(), sub.getLastToken().getEnd(), fixText); const issue = issue_1.Issue.atToken(file, startToken, message, this.getMetadata().key, this.conf.severity, fix); issues.push(issue); } } for (const m of structure.findAllStatements(Statements.Move)) { issues.push(...this.analyzeMove(file, m)); } for (const m of structure.findAllStatements(Statements.Select)) { issues.push(...this.analyzeInto(file, m)); } return issues; } //////////////////// analyzeInto(file, m) { const into = m.findFirstExpression(Expressions.SQLIntoList); if (into === undefined) { return []; } const second = into.getAllTokens()[1]; if (second === undefined || second.getStr() !== "(") { return []; } const concat = into.concatTokens(); if (concat.endsWith(")") === true && concat.includes(",") === false) { const issue = issue_1.Issue.atStatement(file, m, "Too many parentheses", this.getMetadata().key, this.conf.severity); return [issue]; } return []; } analyzeMove(file, m) { const issues = []; const children = m.getChildren(); const last = children[children.length - 2]; const lastChildren = last.getChildren(); if (lastChildren.length === 3 && lastChildren[0].getFirstToken().getStr() === "(" && lastChildren[2].getFirstToken().getStr() === ")") { const issue = issue_1.Issue.atToken(file, last.getFirstToken(), "Too many parentheses", this.getMetadata().key, this.conf.severity); issues.push(issue); } return issues; } analyze(file, cond) { var _a, _b; const issues = []; let comparator = ""; let found = false; for (const c of cond.getChildren()) { let current = ""; if (c instanceof nodes_1.TokenNode) { current = c.get().getStr().toUpperCase(); } else if (c instanceof nodes_1.ExpressionNode && (c.get() instanceof Expressions.CondSub || c.get() instanceof Expressions.ComponentCondSub)) { if (c.getFirstToken().getStr().toUpperCase() === "NOT") { return []; } let i = c.findDirectExpression(Expressions.Cond); if (i === undefined) { i = c.findDirectExpression(Expressions.ComponentCond); } if (i === undefined) { return []; } current = this.findComparator(i); if (current !== "") { found = true; // dont report for the simple case that contains quick fixes } } else if (c instanceof nodes_1.ExpressionNode && c.get() instanceof Expressions.Compare && ((_a = c.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Source && c.getChildren().length === 3) { const concat = (_b = c.getFirstChild()) === null || _b === void 0 ? void 0 : _b.concatTokens(); if ((concat === null || concat === void 0 ? void 0 : concat.startsWith("(")) && concat.endsWith(")")) { const message = "Parentheses can be removed"; const issue = issue_1.Issue.atToken(file, c.getFirstToken(), message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } if (comparator === "") { comparator = current; } else if (comparator !== "" && current !== "" && comparator !== current) { return []; } } if (comparator !== "" && comparator !== "MIXED" && found === true) { const message = "Too many parentheses, complex"; const issue = issue_1.Issue.atToken(file, cond.getFirstToken(), message, this.getMetadata().key, this.conf.severity); issues.push(issue); } return issues; } findComparator(cond) { let comparator = ""; const children = cond.getChildren(); for (const c of children) { if (c instanceof nodes_1.TokenNode) { const current = c.get().getStr().toUpperCase(); if (comparator === "") { comparator = current; } else if (current !== comparator) { return "MIXED"; } } } return comparator; } } exports.ManyParentheses = ManyParentheses; //# sourceMappingURL=many_parentheses.js.map