@abaplint/core
Version:
abaplint - Core API
188 lines • 7.75 kB
JavaScript
;
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