UNPKG

@abaplint/core

Version:
160 lines (159 loc) 6.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmptyStructure = exports.EmptyStructureConf = void 0; const issue_1 = require("../issue"); const Structures = require("../abap/3_structures/structures"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const _irule_1 = require("./_irule"); const _statement_1 = require("../abap/2_statements/statements/_statement"); class EmptyStructureConf extends _basic_rule_config_1.BasicRuleConfig { constructor() { super(...arguments); /** Checks for empty LOOP blocks */ this.loop = true; /** Allow empty LOOP if subrc is checked after the loop */ this.loopAllowIfSubrc = true; /** Checks for empty IF blocks */ this.if = true; /** Checks for empty WHILE blocks */ this.while = true; /** Checks for empty CASE blocks */ this.case = true; /** Checks for empty SELECT blockss */ this.select = true; /** Checks for empty DO blocks */ this.do = true; /** Checks for empty AT blocks */ this.at = true; /** Checks for empty TRY blocks */ this.try = true; /** Checks for empty WHEN blocks */ this.when = true; // todo, other category containing ELSE } } exports.EmptyStructureConf = EmptyStructureConf; class EmptyStructure extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new EmptyStructureConf(); } getMetadata() { return { key: "empty_structure", title: "Find empty blocks", shortDescription: `Checks that the code does not contain empty blocks.`, extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#no-empty-if-branches`, tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile], badExample: `IF foo = bar. ENDIF. DO 2 TIMES. ENDDO.`, goodExample: `LOOP AT itab WHERE qty = 0 OR date > sy-datum. ENDLOOP. result = xsdbool( sy-subrc = 0 ).`, }; } getDescription(name) { return "Empty block, add code: " + name; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { const issues = []; const stru = file.getStructure(); if (stru === undefined) { return []; } const statements = file.getStatements(); for (const statement of statements) { if (statement.get() instanceof _statement_1.Unknown) { return []; // contains parser errors } } const candidates = []; if (this.getConfig().while === true) { candidates.push(...stru.findAllStructuresRecursive(Structures.While)); } if (this.getConfig().case === true) { candidates.push(...stru.findAllStructuresRecursive(Structures.Case)); } if (this.getConfig().select === true) { candidates.push(...stru.findAllStructuresRecursive(Structures.Select)); } if (this.getConfig().do === true) { candidates.push(...stru.findAllStructuresRecursive(Structures.Do)); } if (this.getConfig().at === true) { candidates.push(...stru.findAllStructuresRecursive(Structures.At)); candidates.push(...stru.findAllStructuresRecursive(Structures.AtFirst)); candidates.push(...stru.findAllStructuresRecursive(Structures.AtLast)); } for (const l of candidates) { if (l.getChildren().length === 2) { const token = l.getFirstToken(); const issue = issue_1.Issue.atToken(file, token, this.getDescription(l.get().constructor.name), this.getMetadata().key, this.conf.severity); issues.push(issue); } } if (this.getConfig().try === true) { const tries = stru.findAllStructuresRecursive(Structures.Try); for (const t of tries) { const normal = t.findDirectStructure(Structures.Body); if (normal === undefined) { const token = t.getFirstToken(); const issue = issue_1.Issue.atToken(file, token, this.getDescription(t.get().constructor.name), this.getMetadata().key, this.conf.severity); issues.push(issue); } } } if (this.getConfig().loop === true) { const loops = stru.findAllStructuresRecursive(Structures.Loop); for (const loop of loops) { if (loop.getChildren().length === 2) { const endloopStatement = loop.getLastChild(); const endloopIndex = statements.findIndex((s) => s === endloopStatement); const afterEndloop = statements[endloopIndex + 1]; if (afterEndloop !== undefined && afterEndloop.concatTokens().toUpperCase().includes("SY-SUBRC")) { continue; } const token = loop.getFirstToken(); const issue = issue_1.Issue.atToken(file, token, this.getDescription(loop.get().constructor.name), this.getMetadata().key, this.conf.severity); issues.push(issue); } } } if (this.getConfig().if === true) { const tries = stru.findAllStructuresRecursive(Structures.If) .concat(stru.findAllStructuresRecursive(Structures.Else)) .concat(stru.findAllStructuresRecursive(Structures.ElseIf)); for (const t of tries) { const normal = t.findDirectStructure(Structures.Body); if (normal === undefined) { const token = t.getFirstToken(); const issue = issue_1.Issue.atToken(file, token, this.getDescription(t.get().constructor.name), this.getMetadata().key, this.conf.severity); issues.push(issue); } } } if (this.getConfig().when === true) { const tries = stru.findAllStructuresRecursive(Structures.When); for (const t of tries) { if (t.getChildren().length === 1) { const token = t.getFirstToken(); const message = this.getDescription(t.get().constructor.name); const issue = issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity); issues.push(issue); } } } return issues; } } exports.EmptyStructure = EmptyStructure; //# sourceMappingURL=empty_structure.js.map