UNPKG

@abaplint/core

Version:
271 lines • 11.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParserMissingSpace = exports.ParserMissingSpaceConf = void 0; const Expressions = require("../abap/2_statements/expressions"); const issue_1 = require("../issue"); const position_1 = require("../position"); const _abap_rule_1 = require("./_abap_rule"); const nodes_1 = require("../abap/nodes"); const _basic_rule_config_1 = require("./_basic_rule_config"); const _irule_1 = require("./_irule"); // todo: this rule needs refactoring class ParserMissingSpaceConf extends _basic_rule_config_1.BasicRuleConfig { } exports.ParserMissingSpaceConf = ParserMissingSpaceConf; class ParserMissingSpace extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new ParserMissingSpaceConf(); } getMetadata() { return { key: "parser_missing_space", title: "Parser Error, missing space", shortDescription: `In special cases the ABAP language allows for not having spaces before or after string literals. This rule makes sure the spaces are consistently required across the language.`, tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.SingleFile], badExample: `IF ( foo = 'bar').`, goodExample: `IF ( foo = 'bar' ).`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { const issues = []; let start = new position_1.Position(0, 0); for (const statement of file.getStatements()) { const missing = this.missingSpace(statement); if (missing) { const message = "Missing space between string or character literal and parentheses"; start = missing; const issue = issue_1.Issue.atPosition(file, start, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } return issues; } missingSpace(statement) { const found = statement.findAllExpressionsMulti([ Expressions.CondSub, Expressions.SQLCond, Expressions.ValueBodyLine, Expressions.NewObject, Expressions.Cond, Expressions.ComponentCond, Expressions.Source, Expressions.ComponentCondSub, Expressions.MethodCallParam ], true); let pos = undefined; for (const f of found) { const type = f.get(); if (type instanceof Expressions.Cond) { pos = this.checkCond(f); } else if (type instanceof Expressions.Source) { pos = this.checkSource(f); } else if (type instanceof Expressions.CondSub) { pos = this.checkCondSub(f); } else if (type instanceof Expressions.ComponentCond) { pos = this.checkComponentCond(f); } else if (type instanceof Expressions.ComponentCondSub) { pos = this.checkComponentCondSub(f); } else if (type instanceof Expressions.SQLCond) { pos = this.checkSQLCond(f); } else if (type instanceof Expressions.ValueBodyLine) { pos = this.checkValueBodyLine(f); } else if (type instanceof Expressions.NewObject) { pos = this.checkNewObject(f); } else if (type instanceof Expressions.MethodCallParam) { pos = this.checkMethodCallParam(f); } if (pos) { return pos; } } return undefined; } checkSQLCond(cond) { const children = cond.getChildren(); for (let i = 0; i < children.length; i++) { if (children[i].get() instanceof Expressions.SQLCond) { const current = children[i]; const prev = children[i - 1].getLastToken(); const next = children[i + 1].getFirstToken(); if (prev.getStr() === "(" && prev.getRow() === current.getFirstToken().getRow() && prev.getCol() + 1 === current.getFirstToken().getStart().getCol()) { return current.getFirstToken().getStart(); } if (next.getStr() === ")" && next.getRow() === current.getLastToken().getRow() && next.getCol() === current.getLastToken().getEnd().getCol()) { return current.getLastToken().getEnd(); } } } return undefined; } checkNewObject(cond) { const children = cond.getChildren(); { const first = children[children.length - 2].getLastToken(); const second = children[children.length - 1].getFirstToken(); if (first.getRow() === second.getRow() && first.getEnd().getCol() === second.getStart().getCol()) { return second.getStart(); } } return undefined; } checkCondSub(cond) { const children = cond.getChildren(); for (let i = 0; i < children.length; i++) { if (children[i].get() instanceof Expressions.Cond) { const current = children[i]; const prev = children[i - 1].getLastToken(); const next = children[i + 1].getFirstToken(); if (prev.getStr() === "(" && prev.getRow() === current.getFirstToken().getRow() && prev.getCol() + 1 === current.getFirstToken().getStart().getCol()) { return current.getFirstToken().getStart(); } if (next.getStr() === ")" && next.getRow() === current.getLastToken().getRow() && next.getCol() === current.getLastToken().getEnd().getCol()) { return current.getLastToken().getEnd(); } } } return undefined; } checkComponentCondSub(cond) { const children = cond.getChildren(); for (let i = 0; i < children.length; i++) { if (children[i].get() instanceof Expressions.ComponentCond) { const current = children[i]; const prev = children[i - 1].getLastToken(); const next = children[i + 1].getFirstToken(); if (prev.getStr() === "(" && prev.getRow() === current.getFirstToken().getRow() && prev.getCol() + 1 === current.getFirstToken().getStart().getCol()) { return current.getFirstToken().getStart(); } if (next.getStr() === ")" && next.getRow() === current.getLastToken().getRow() && next.getCol() === current.getLastToken().getEnd().getCol()) { return current.getLastToken().getEnd(); } } } return undefined; } checkComponentCond(cond) { const children = cond.getAllTokens(); for (let i = 0; i < children.length - 1; i++) { const current = children[i]; const next = children[i + 1]; if (next.getStr().startsWith("'") && next.getRow() === current.getRow() && next.getCol() === current.getEnd().getCol()) { return current.getEnd(); } } return undefined; } checkValueBodyLine(vb) { var _a, _b; const children = vb.getChildren(); for (let i = 0; i < children.length; i++) { const current = children[i]; if (current instanceof nodes_1.TokenNode) { const prev = (_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.getLastToken(); const next = (_b = children[i + 1]) === null || _b === void 0 ? void 0 : _b.getFirstToken(); if (current.getFirstToken().getStr() === "(" && next && next.getRow() === current.getLastToken().getRow() && next.getCol() === current.getLastToken().getEnd().getCol()) { return current.getFirstToken().getStart(); } if (current.getFirstToken().getStr() === ")" && prev && prev.getRow() === current.getFirstToken().getRow() && prev.getEnd().getCol() === current.getFirstToken().getStart().getCol()) { return current.getLastToken().getEnd(); } } } return undefined; } checkCond(cond) { const children = cond.getAllTokens(); for (let i = 0; i < children.length - 1; i++) { const current = children[i]; const next = children[i + 1]; if (next.getStr().startsWith("'") && next.getRow() === current.getRow() && next.getCol() === current.getEnd().getCol()) { return current.getEnd(); } } return undefined; } checkSource(cond) { var _a, _b; const children = cond.getAllTokens(); if (children.length < 2) { return undefined; } if (children.length >= 4 && children[0].getStr().toUpperCase() === "CONV") { const directChildren = cond.getChildren(); const first = (_a = directChildren[2]) === null || _a === void 0 ? void 0 : _a.getLastToken(); const second = (_b = directChildren[3]) === null || _b === void 0 ? void 0 : _b.getFirstToken(); if (first && first.getStr() === "(" && second && first.getRow() === second.getRow() && first.getCol() + 1 === second.getStart().getCol()) { return second.getStart(); } } { const nextLast = children[children.length - 2]; const last = children[children.length - 1]; if (nextLast.getStr().startsWith("'") && nextLast.getRow() === last.getRow() && nextLast.getEnd().getCol() === last.getStart().getCol()) { return last.getEnd(); } } return undefined; } checkMethodCallParam(call) { const children = call.getChildren(); { const first = children[0].getFirstToken(); const second = children[1].getFirstToken(); if (first.getRow() === second.getRow() && first.getCol() + 1 === second.getStart().getCol()) { return second.getStart(); } } { const first = children[children.length - 2].getLastToken(); const second = children[children.length - 1].getFirstToken(); if (first.getRow() === second.getRow() && first.getEnd().getCol() === second.getStart().getCol()) { return second.getStart(); } } return undefined; } } exports.ParserMissingSpace = ParserMissingSpace; //# sourceMappingURL=parser_missing_space.js.map