@abaplint/core
Version:
abaplint - Core API
189 lines • 8.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DoubleSpace = exports.DoubleSpaceConf = void 0;
const issue_1 = require("../issue");
const _abap_rule_1 = require("./_abap_rule");
const _basic_rule_config_1 = require("./_basic_rule_config");
const tokens_1 = require("../abap/1_lexer/tokens");
const nodes_1 = require("../abap/nodes");
const _statement_1 = require("../abap/2_statements/statements/_statement");
const statements_1 = require("../abap/2_statements/statements");
const position_1 = require("../position");
const edit_helper_1 = require("../edit_helper");
const _irule_1 = require("./_irule");
class DoubleSpaceConf extends _basic_rule_config_1.BasicRuleConfig {
constructor() {
super(...arguments);
/** Check for double space after keywords */
this.keywords = true;
/** list of keywords to skip, case insensitive */
this.skipKeywords = ["CHANGING", "EXPORTING", "OTHERS"];
/** Check for double space after start parenthesis */
this.startParen = true;
/** Check for double space before end parenthesis */
this.endParen = true;
/** Check for double space after colon/chaining operator */
this.afterColon = true;
}
}
exports.DoubleSpaceConf = DoubleSpaceConf;
class DoubleSpace extends _abap_rule_1.ABAPRule {
constructor() {
super(...arguments);
this.conf = new DoubleSpaceConf();
}
getMetadata() {
return {
key: "double_space",
title: "Double space",
shortDescription: `Checks that only a single space follows certain common statements.`,
tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
badExample: `DATA foo TYPE i.`,
goodExample: `DATA foo TYPE i.`,
};
}
getMessage() {
return "Remove double space";
}
getConfig() {
return this.conf;
}
setConfig(conf) {
this.conf = conf;
if (this.conf.skipKeywords === undefined) {
this.conf.skipKeywords = new DoubleSpaceConf().skipKeywords;
}
}
runParsed(file) {
let issues = [];
for (const s of file.getStatements()) {
if (s.get() instanceof _statement_1.NativeSQL) {
continue;
}
if (this.conf.keywords === true
&& !(s.get() instanceof _statement_1.Unknown)
&& !(s.get() instanceof statements_1.MethodDef)
&& !(s.get() instanceof _statement_1.MacroCall)
&& !(s.get() instanceof statements_1.Events)
&& !(s.get() instanceof _statement_1.MacroContent)) {
issues = issues.concat(this.checkKeywords(s, file));
}
issues = issues.concat(this.checkParen(s, file));
}
issues = issues.concat(this.checkAfterColon(file));
return issues;
}
checkAfterColon(file) {
const issues = [];
let cPosition = undefined;
if (this.conf.afterColon !== true) {
return [];
}
for (const s of file.getStatements()) {
const colon = s.getColon();
if (colon === undefined) {
continue;
}
else if (cPosition !== undefined && cPosition.getCol() === colon.getCol()) {
continue;
}
cPosition = colon.getStart();
for (const t of s.getTokens()) {
if (t.getRow() !== cPosition.getRow()) {
return [];
}
else if (t.getCol() < cPosition.getCol()) {
continue;
}
if (t.getCol() > cPosition.getCol() + 2) {
const issueStartPos = new position_1.Position(cPosition.getRow(), cPosition.getCol() + 2);
const issueEndPos = new position_1.Position(t.getRow(), t.getCol());
const fix = edit_helper_1.EditHelper.deleteRange(file, issueStartPos, issueEndPos);
issues.push(issue_1.Issue.atRange(file, issueStartPos, issueEndPos, this.getMessage(), this.getMetadata().key, this.conf.severity, fix));
}
break;
}
}
return issues;
}
checkParen(s, file) {
const issues = [];
let prev = undefined;
for (const t of s.getTokens()) {
if (prev === undefined) {
prev = t;
continue;
}
if (this.getConfig().startParen === true
&& prev.getRow() === t.getRow()
&& prev instanceof tokens_1.ParenLeftW
&& !(t instanceof tokens_1.Comment)
&& prev.getEnd().getCol() + 1 < t.getCol()) {
const issueStartPos = new position_1.Position(prev.getRow(), prev.getCol() + 2);
const issueEndPos = new position_1.Position(t.getRow(), t.getCol());
const fix = edit_helper_1.EditHelper.deleteRange(file, issueStartPos, issueEndPos);
if (this.pragmaInRange(s.getPragmas(), issueStartPos, issueEndPos) === false) {
issues.push(issue_1.Issue.atRange(file, issueStartPos, issueEndPos, this.getMessage(), this.getMetadata().key, this.conf.severity, fix));
}
}
if (this.getConfig().endParen === true
&& prev.getRow() === t.getRow()
&& !(prev instanceof tokens_1.ParenLeftW)
&& (t instanceof tokens_1.WParenRightW || t instanceof tokens_1.WParenRight)
&& prev.getEnd().getCol() + 1 < t.getCol()) {
const issueStartPos = new position_1.Position(prev.getEnd().getRow(), prev.getEnd().getCol() + 1);
const issueEndPos = new position_1.Position(t.getRow(), t.getCol());
const fix = edit_helper_1.EditHelper.deleteRange(file, issueStartPos, issueEndPos);
if (this.pragmaInRange(s.getPragmas(), issueStartPos, issueEndPos) === false) {
issues.push(issue_1.Issue.atRange(file, issueStartPos, issueEndPos, this.getMessage(), this.getMetadata().key, this.conf.severity, fix));
}
}
prev = t;
}
return issues;
}
pragmaInRange(pragmas, start, end) {
let ret = false;
for (const p of pragmas) {
if (p.getStart().isBetween(start, end)) {
ret = true;
}
}
return ret;
}
checkKeywords(s, file) {
const issues = [];
let prev = undefined;
if (s.getColon() !== undefined || s.getPragmas().length > 0) {
// for chained statments just give up
return [];
}
for (const n of s.getTokenNodes()) {
if (prev === undefined) {
prev = n;
continue;
}
const upper = prev.get().getStr().toUpperCase();
if (prev instanceof nodes_1.TokenNodeRegex
|| upper === "("
|| upper === ")"
|| this.getConfig().skipKeywords.some(e => e.toUpperCase() === upper)) {
// not a keyword, continue
prev = n;
continue;
}
if (prev.get().getStart().getRow() === n.get().getStart().getRow()
&& prev.get().getEnd().getCol() + 1 < n.get().getStart().getCol()) {
const issueStartPos = new position_1.Position(prev.get().getEnd().getRow(), prev.get().getEnd().getCol() + 1);
const issueEndPos = new position_1.Position(n.get().getRow(), n.get().getCol());
const fix = edit_helper_1.EditHelper.deleteRange(file, issueStartPos, issueEndPos);
issues.push(issue_1.Issue.atRange(file, issueStartPos, issueEndPos, this.getMessage(), this.getMetadata().key, this.conf.severity, fix));
return issues;
}
prev = n;
}
return [];
}
}
exports.DoubleSpace = DoubleSpace;
//# sourceMappingURL=double_space.js.map