UNPKG

@abaplint/core

Version:
107 lines (106 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UseLineExists = exports.UseLineExistsConf = void 0; const issue_1 = require("../issue"); const Statements = require("../abap/2_statements/statements"); const Expressions = require("../abap/2_statements/expressions"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const version_1 = require("../version"); const _irule_1 = require("./_irule"); const _statement_1 = require("../abap/2_statements/statements/_statement"); class UseLineExistsConf extends _basic_rule_config_1.BasicRuleConfig { } exports.UseLineExistsConf = UseLineExistsConf; class UseLineExists extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new UseLineExistsConf(); } getMetadata() { return { key: "use_line_exists", title: "Use line_exists", shortDescription: `Use line_exists, from 740sp02 and up`, extendedInformation: ` https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-line_exists-to-read-table-or-loop-at Not reported if the READ TABLE statement contains BINARY SEARCH.`, tags: [_irule_1.RuleTag.Upport, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile], badExample: `READ TABLE my_table TRANSPORTING NO FIELDS WITH KEY key = 'A'. IF sy-subrc = 0. ENDIF.`, goodExample: `IF line_exists( my_table[ key = 'A' ] ). ENDIF.`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file, obj) { const issues = []; if (obj.getType() === "INTF") { return []; } const vers = this.reg.getConfig().getVersion(); if (vers === version_1.Version.OpenABAP) { return []; } else if (vers < version_1.Version.v740sp02 && vers !== version_1.Version.Cloud) { return []; } const statements = file.getStatements(); for (let i = 0; i < statements.length; i++) { const statement = statements[i]; if (!(statement.get() instanceof Statements.ReadTable)) { continue; } const concat = statement.concatTokens().toUpperCase(); if (concat.includes(" TRANSPORTING NO FIELDS") === true && concat.includes(" BINARY SEARCH") === false && this.checksSubrc(i, statements) === true && this.usesTabix(i, statements) === false) { issues.push(issue_1.Issue.atStatement(file, statement, "Use line_exists", this.getMetadata().key, this.conf.severity)); } } return issues; } /////////////////////// checksSubrc(index, statements) { for (let i = index + 1; i < statements.length; i++) { const statement = statements[i]; if (statement.get() instanceof _statement_1.Comment) { continue; } for (const c of statement.findAllExpressions(Expressions.Cond)) { for (const s of c.findAllExpressions(Expressions.Source)) { if (s.concatTokens().toUpperCase() === "SY-SUBRC") { return true; } } } return false; } return false; } // this is a heuristic, data flow analysis is required to get the correct result usesTabix(index, statements) { for (let i = index + 1; i < index + 5; i++) { const statement = statements[i]; if (statement === undefined) { break; } else if (statement.get() instanceof _statement_1.Comment) { continue; } else if (statement.concatTokens().toUpperCase().includes(" SY-TABIX")) { return true; } } return false; } } exports.UseLineExists = UseLineExists; //# sourceMappingURL=use_line_exists.js.map