@abaplint/core
Version:
abaplint - Core API
119 lines (118 loc) • 4.22 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;
if (node.getChildren().length !== 4) {
return [];
}
const ifBody = node.findDirectStructure(Structures.Body);
if (node.findDirectStructure(Structures.ElseIf)) {
return [];
}
const elseBody = (_a = node.findDirectStructure(Structures.Else)) === null || _a === void 0 ? void 0 : _a.findDirectStructure(Structures.Body);
if (elseBody === undefined || ifBody === undefined) {
return [];
}
{
const ifFirst = ifBody.getFirstChild();
const elseFirst = elseBody.getFirstChild();
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];
}
}
{
const ifLast = ifBody.getLastChild();
const elseLast = elseBody.getLastChild();
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