UNPKG

@abaplint/core

Version:
121 lines (119 loc) • 6.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UseBoolExpression = exports.UseBoolExpressionConf = void 0; const issue_1 = require("../issue"); const Statements = require("../abap/2_statements/statements"); const Expressions = require("../abap/2_statements/expressions"); const Structures = require("../abap/3_structures/structures"); 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 edit_helper_1 = require("../edit_helper"); // note this rule assumes abap_true and abap_false is used for boolean variables // some other rule will in the future find assignments to abap_bool that are not abap_true/abap_false/abap_undefined class UseBoolExpressionConf extends _basic_rule_config_1.BasicRuleConfig { } exports.UseBoolExpressionConf = UseBoolExpressionConf; class UseBoolExpression extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new UseBoolExpressionConf(); } getMetadata() { return { key: "use_bool_expression", title: "Use boolean expression", shortDescription: `Use boolean expression, xsdbool from 740sp08 and up, boolc from 702 and up`, extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use-xsdbool-to-set-boolean-variables`, tags: [_irule_1.RuleTag.Upport, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile], badExample: `IF line IS INITIAL. has_entries = abap_false. ELSE. has_entries = abap_true. ENDIF. DATA(fsdf) = COND #( WHEN foo <> bar THEN abap_true ELSE abap_false ).`, goodExample: `DATA(has_entries) = xsdbool( line IS NOT INITIAL ). DATA(fsdf) = xsdbool( foo <> bar ).`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; const issues = []; const stru = file.getStructure(); const version = this.reg.getConfig().getVersion(); if (stru === undefined || (version < version_1.Version.v702 && version !== version_1.Version.Cloud)) { return []; } for (const i of stru.findAllStructures(Structures.If)) { if (i.findDirectStructure(Structures.ElseIf) !== undefined) { continue; } const bodyNodes = (_a = i.findDirectStructure(Structures.Body)) === null || _a === void 0 ? void 0 : _a.findAllStatementNodes(); if (bodyNodes === undefined || bodyNodes.length !== 1) { continue; } const bodyStatement = bodyNodes[0]; if (!(bodyStatement.get() instanceof Statements.Move)) { continue; } const elseNodes = (_c = (_b = i.findDirectStructure(Structures.Else)) === null || _b === void 0 ? void 0 : _b.findDirectStructure(Structures.Body)) === null || _c === void 0 ? void 0 : _c.findAllStatementNodes(); if (elseNodes === undefined || elseNodes.length !== 1) { continue; } const elseStatement = elseNodes[0]; if (!(elseStatement.get() instanceof Statements.Move)) { continue; } let bodyTarget = (_d = bodyStatement.findFirstExpression(Expressions.Target)) === null || _d === void 0 ? void 0 : _d.concatTokens(); if (bodyTarget === null || bodyTarget === void 0 ? void 0 : bodyTarget.startsWith("DATA(")) { bodyTarget = bodyTarget.substr(5, bodyTarget.length - 6); } const elseTarget = (_e = elseStatement.findFirstExpression(Expressions.Target)) === null || _e === void 0 ? void 0 : _e.concatTokens(); if (bodyTarget === undefined || elseTarget === undefined || bodyTarget.toUpperCase() !== elseTarget.toUpperCase()) { continue; } const bodySource = (_f = bodyStatement.findFirstExpression(Expressions.Source)) === null || _f === void 0 ? void 0 : _f.concatTokens().toUpperCase(); const elseSource = (_g = elseStatement.findFirstExpression(Expressions.Source)) === null || _g === void 0 ? void 0 : _g.concatTokens().toUpperCase(); if ((bodySource === "ABAP_TRUE" && elseSource === "ABAP_FALSE") || (bodySource === "ABAP_FALSE" && elseSource === "ABAP_TRUE")) { const func = (this.reg.getConfig().getVersion() >= version_1.Version.v740sp08 || this.reg.getConfig().getVersion() === version_1.Version.Cloud) ? "xsdbool" : "boolc"; const negate = bodySource === "ABAP_FALSE"; const message = `Use ${func} instead of IF` + (negate ? ", negate expression" : ""); const start = i.getFirstToken().getStart(); const end = i.getLastToken().getEnd(); const statement = bodyTarget + " = " + func + "( " + (negate ? "NOT ( " : "") + ((_j = (_h = i.findFirstStatement(Statements.If)) === null || _h === void 0 ? void 0 : _h.findFirstExpression(Expressions.Cond)) === null || _j === void 0 ? void 0 : _j.concatTokens()) + (negate ? " )" : "") + " )."; const fix = edit_helper_1.EditHelper.replaceRange(file, start, end, statement); issues.push(issue_1.Issue.atRange(file, start, end, message, this.getMetadata().key, this.conf.severity, fix)); } } if (version >= version_1.Version.v740sp08 || version === version_1.Version.Cloud) { for (const b of stru.findAllExpressions(Expressions.CondBody)) { const concat = b.concatTokens().toUpperCase(); if (concat.endsWith(" THEN ABAP_TRUE ELSE ABAP_FALSE") || concat.endsWith(" THEN ABAP_TRUE") || concat.endsWith(" THEN ABAP_FALSE ELSE ABAP_TRUE")) { const message = "Use xsdbool"; // eslint-disable-next-line max-len issues.push(issue_1.Issue.atRange(file, b.getFirstToken().getStart(), b.getLastToken().getEnd(), message, this.getMetadata().key, this.conf.severity)); } } } return issues; } } exports.UseBoolExpression = UseBoolExpression; //# sourceMappingURL=use_bool_expression.js.map