UNPKG

@abaplint/core

Version:
94 lines 4.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BeginEndNames = exports.BeginEndNamesConf = void 0; const issue_1 = require("../issue"); const _abap_rule_1 = require("./_abap_rule"); const _basic_rule_config_1 = require("./_basic_rule_config"); const Structures = require("../abap/3_structures/structures"); const Expressions = require("../abap/2_statements/expressions"); const Statements = require("../abap/2_statements/statements"); const _statement_1 = require("../abap/2_statements/statements/_statement"); const _irule_1 = require("./_irule"); const edit_helper_1 = require("../edit_helper"); class BeginEndNamesConf extends _basic_rule_config_1.BasicRuleConfig { } exports.BeginEndNamesConf = BeginEndNamesConf; class BeginEndNames extends _abap_rule_1.ABAPRule { constructor() { super(...arguments); this.conf = new BeginEndNamesConf(); } getMetadata() { return { key: "begin_end_names", title: "Check BEGIN END names", shortDescription: `Check BEGIN OF and END OF names match, plus there must be statements between BEGIN and END`, tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile], badExample: `DATA: BEGIN OF stru, field TYPE i, END OF structure_not_the_same.`, goodExample: `DATA: BEGIN OF stru, field TYPE i, END OF stru.`, }; } getConfig() { return this.conf; } setConfig(conf) { this.conf = conf; } runParsed(file) { const output = []; const struc = file.getStructure(); if (struc === undefined) { return []; } const containsUnknown = file.getStatements().some(s => s.get() instanceof _statement_1.Unknown); if (containsUnknown === true) { return []; } output.push(...this.test(struc, Structures.Data, Statements.DataBegin, Statements.DataEnd, file)); output.push(...this.test(struc, Structures.ClassData, Statements.ClassDataBegin, Statements.ClassDataEnd, file)); output.push(...this.test(struc, Structures.Constants, Statements.ConstantBegin, Statements.ConstantEnd, file)); output.push(...this.test(struc, Structures.Statics, Statements.StaticBegin, Statements.StaticEnd, file)); output.push(...this.test(struc, Structures.TypeEnum, Statements.TypeEnumBegin, Statements.TypeEnumEnd, file)); output.push(...this.test(struc, Structures.Types, Statements.TypeBegin, Statements.TypeEnd, file)); return output; } test(stru, type, b, e, file) { const output = []; for (const sub of stru.findAllStructuresRecursive(type)) { let begin = sub.findDirectStatements(b)[0].findFirstExpression(Expressions.NamespaceSimpleName); if (begin === undefined) { begin = sub.findDirectStatements(b)[0].findFirstExpression(Expressions.DefinitionName); } if (begin === undefined) { continue; } const first = begin.getFirstToken(); let end = sub.findDirectStatements(e)[0].findFirstExpression(Expressions.NamespaceSimpleName); if (end === undefined) { end = sub.findDirectStatements(e)[0].findFirstExpression(Expressions.DefinitionName); } if (end === undefined) { continue; } const last = end.getFirstToken(); if (first.getStr().toUpperCase() !== last.getStr().toUpperCase()) { const fix = edit_helper_1.EditHelper.replaceRange(file, last.getStart(), last.getEnd(), first.getStr()); const message = "BEGIN END names must match"; const issue = issue_1.Issue.atToken(file, first, message, this.getMetadata().key, this.conf.severity, fix); output.push(issue); } if (sub.getChildren().length === 2) { const message = "There must be statements between BEGIN and END"; const issue = issue_1.Issue.atToken(file, first, message, this.getMetadata().key, this.conf.severity); output.push(issue); } } return output; } } exports.BeginEndNames = BeginEndNames; //# sourceMappingURL=begin_end_names.js.map