UNPKG

@abaplint/core

Version:
151 lines 6.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageExistsRule = exports.MessageExistsConf = void 0; const Expressions = require("../abap/2_statements/expressions"); const Statements = require("../abap/2_statements/statements"); const issue_1 = require("../issue"); const _basic_rule_config_1 = require("./_basic_rule_config"); const ddic_1 = require("../ddic"); const _irule_1 = require("./_irule"); const nodes_1 = require("../abap/nodes"); const _abap_object_1 = require("../objects/_abap_object"); const syntax_1 = require("../abap/5_syntax/syntax"); class MessageExistsConf extends _basic_rule_config_1.BasicRuleConfig { constructor() { super(...arguments); this.checkPlaceholders = true; } } exports.MessageExistsConf = MessageExistsConf; class MessageExistsRule { constructor() { this.conf = new MessageExistsConf(); } getMetadata() { return { key: "message_exists", title: "Check MESSAGE exists", shortDescription: `In message statements, check that the message class + id exist`, tags: [_irule_1.RuleTag.Syntax], }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } initialize(reg) { this.msagReferences = reg.getMSAGReferences(); this.reg = reg; // the SyntaxLogic builds the references for (const obj of reg.getObjects()) { if (obj instanceof _abap_object_1.ABAPObject) { new syntax_1.SyntaxLogic(reg, obj).run(); } } return this; } run(obj) { const issues = []; if (obj instanceof _abap_object_1.ABAPObject) { for (const file of obj.getABAPFiles()) { const struc = file.getStructure(); if (struc === undefined) { return []; } issues.push(...this.checkReportStatement(file)); issues.push(...this.checkSource(file)); } } return issues; } //////////////////////////////// checkReportStatement(file) { const issues = []; for (const statement of file.getStatements()) { if (!(statement.get() instanceof Statements.Report)) { continue; } const expression = statement.findFirstExpression(Expressions.MessageClass); if (expression) { const issue = this.checkClass(expression, file); if (issue) { issues.push(issue); } } } return issues; } checkClass(node, file) { const token = node.getFirstToken(); const name = token.getStr(); if (this.reg.getObject("MSAG", name) === undefined && new ddic_1.DDIC(this.reg).inErrorNamespace(name) === true) { const message = "Message class \"" + name + "\" not found"; return issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity); } return undefined; } checkSource(file) { const issues = []; const references = this.msagReferences.listByFilename(file.getFilename()); for (const statement of file.getStatements()) { if (statement.get() instanceof Statements.Raise || statement.get() instanceof Statements.Message) { for (const ref of references) { // always max one message reference per statement? chained statements? if (ref.token.getStart().isBetween(statement.getStart(), statement.getEnd())) { const msag = this.reg.getObject("MSAG", ref.messageClass); if (msag === undefined) { if (new ddic_1.DDIC(this.reg).inErrorNamespace(ref.messageClass) === true) { const message = "Message class \"" + ref.messageClass + "\" not found"; issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity)); } continue; } const text = msag.getByNumber(ref.number); if (text === undefined) { const message = "Message number \"" + ref.number + "\" not found in class \"" + ref.messageClass + "\""; issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity)); continue; } if (this.getConfig().checkPlaceholders === true) { const count = this.countWith(statement); const textCount = text.getPlaceholderCount(); if (count !== textCount) { const message = `Message ${ref.number}, expected ${textCount} WITH parameters`; issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity)); } } } } } } return issues; } countWith(statement) { const raiseWith = statement.findDirectExpression(Expressions.RaiseWith); if (raiseWith) { return raiseWith.getChildren().length - 1; } let count = 0; let afterWith = false; for (const expression of statement.getChildren()) { if (expression instanceof nodes_1.TokenNode && expression.concatTokens().toUpperCase() === "WITH") { afterWith = true; continue; } if (afterWith === true) { if (expression instanceof nodes_1.ExpressionNode) { count++; } else { break; } } } return count; } } exports.MessageExistsRule = MessageExistsRule; //# sourceMappingURL=message_exists.js.map