@abaplint/core
Version:
abaplint - Core API
148 lines (147 loc) • 5.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IdenticalContents = exports.IdenticalContentsConf = void 0;
const Structures = require("../abap/3_structures/structures");
const issue_1 = require("../issue");
const _basic_rule_config_1 = require("./_basic_rule_config");
const _abap_rule_1 = require("./_abap_rule");
const _irule_1 = require("./_irule");
const nodes_1 = require("../abap/nodes");
const _statement_1 = require("../abap/2_statements/statements/_statement");
class IdenticalContentsConf extends _basic_rule_config_1.BasicRuleConfig {
}
exports.IdenticalContentsConf = IdenticalContentsConf;
class IdenticalContents extends _abap_rule_1.ABAPRule {
constructor() {
super(...arguments);
this.conf = new IdenticalContentsConf();
}
getMetadata() {
return {
key: "identical_contents",
title: "Identical contents",
shortDescription: `Find identical contents in blocks inside IFs, both in the beginning and in the end.`,
extendedInformation: `
Prerequsites: code is pretty printed with identical cAsE
Chained statments are ignored`,
tags: [_irule_1.RuleTag.SingleFile],
badExample: `IF foo = bar.
WRITE 'bar'.
WRITE 'world'.
ELSE.
WRITE 'foo'.
WRITE 'world'.
ENDIF.`,
goodExample: `IF foo = bar.
WRITE 'bar'.
ELSE.
WRITE 'foo'.
ENDIF.
WRITE 'world'.`,
};
}
getConfig() {
return this.conf;
}
setConfig(conf) {
this.conf = conf;
}
runParsed(file) {
let issues = [];
const structure = file.getStructure();
if (structure === undefined) {
return [];
}
for (const statement of file.getStatements()) {
if (statement.get() instanceof _statement_1.Unknown) {
return []; // contains parser errors
}
}
for (const i of structure.findAllStructuresRecursive(Structures.If)) {
issues = issues.concat(this.analyzeIf(file, i));
}
return issues;
}
////////////////
analyzeIf(file, node) {
var _a;
const ifBody = node.findDirectStructure(Structures.Body);
const elseIfBodies = node.findDirectStructures(Structures.ElseIf) || [];
const elseBody = (_a = node.findDirectStructure(Structures.Else)) === null || _a === void 0 ? void 0 : _a.findDirectStructure(Structures.Body);
if (elseBody === undefined) {
return [];
}
const ifFirst = ifBody === null || ifBody === void 0 ? void 0 : ifBody.getFirstChild();
const elseFirst = elseBody === null || elseBody === void 0 ? void 0 : elseBody.getFirstChild();
const ifLast = ifBody === null || ifBody === void 0 ? void 0 : ifBody.getLastChild();
const elseLast = elseBody === null || elseBody === void 0 ? void 0 : elseBody.getLastChild();
if (elseIfBodies.length > 0) {
let firstMatch = true;
let lastMatch = true;
for (const elseif of elseIfBodies) {
const elseifBody = elseif.findDirectStructure(Structures.Body);
const elseifFirst = elseifBody === null || elseifBody === void 0 ? void 0 : elseifBody.getFirstChild();
const elseifLast = elseifBody === null || elseifBody === void 0 ? void 0 : elseifBody.getLastChild();
if (ifFirst === undefined
|| ifLast === undefined
|| elseLast === undefined
|| elseFirst === undefined) {
return [];
}
if (elseifFirst === undefined
|| ifFirst.concatTokens() !== elseifFirst.concatTokens()
|| elseFirst.concatTokens() !== elseifFirst.concatTokens()) {
firstMatch = false;
}
if (elseifLast === undefined
|| ifLast.concatTokens() !== elseifLast.concatTokens()
|| elseLast.concatTokens() !== elseifLast.concatTokens()) {
lastMatch = false;
}
}
if (firstMatch === true || lastMatch === true) {
const message = "Identical contents";
const issue = issue_1.Issue.atToken(file, node.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
return [issue];
}
return [];
}
else if (elseBody === undefined || ifBody === undefined) {
return [];
}
{
if (ifFirst === undefined || elseFirst === undefined || this.isChained(ifFirst)) {
return [];
}
else if (ifFirst.concatTokens() === elseFirst.concatTokens()) {
const message = "Identical contents";
const issue = issue_1.Issue.atToken(file, node.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
return [issue];
}
}
{
if (ifLast === undefined || elseLast === undefined || this.isChained(ifLast)) {
return [];
}
else if (ifLast.concatTokens() === elseLast.concatTokens()) {
const message = "Identical contents";
const issue = issue_1.Issue.atToken(file, node.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
return [issue];
}
}
return [];
}
isChained(node) {
if (node === undefined) {
return false;
}
else if (node instanceof nodes_1.StatementNode) {
return node.getColon() !== undefined;
}
else {
return this.isChained(node.getFirstStatement());
}
}
}
exports.IdenticalContents = IdenticalContents;
//# sourceMappingURL=identical_contents.js.map