@abaplint/core
Version:
abaplint - Core API
151 lines • 6.26 kB
JavaScript
"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