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