Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11508x 11508x 11508x 11508x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 34377x 11508x 11508x 11006x 11006x 11508x 11508x 235x 235x 11508x 11508x 276x 276x 276x 276x 12x 12x 264x 264x 276x 9x 9x 255x 255x 255x 255x 255x 255x 255x 255x 255x 255x 11508x 11508x 1530x 1530x 1530x 82x 82x 38x 38x 82x 1x 1x 81x 81x 81x 82x 37x 37x 82x 1x 1x 80x 80x 82x 11x 11x 11x 11x 11x 80x 82x 1x 1x 1x 1x 82x 1530x 1530x 1530x 11508x 11508x | import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import * as Structures from "../abap/3_structures/structures";
import * as Expressions from "../abap/2_statements/expressions";
import * as Statements from "../abap/2_statements/statements";
import {StructureNode} from "../abap/nodes";
import {IStructure} from "../abap/3_structures/structures/_structure";
import {IStatement, Unknown} from "../abap/2_statements/statements/_statement";
import {IRuleMetadata, RuleTag} from "./_irule";
import {EditHelper} from "../edit_helper";
import {ABAPFile} from "../abap/abap_file";
export class BeginEndNamesConf extends BasicRuleConfig {
}
export class BeginEndNames extends ABAPRule {
private conf = new BeginEndNamesConf();
public getMetadata(): IRuleMetadata {
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: [RuleTag.Syntax, RuleTag.Quickfix, 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.`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: BeginEndNamesConf) {
this.conf = conf;
}
public runParsed(file: ABAPFile) {
const output: Issue[] = [];
const struc = file.getStructure();
if (struc === undefined) {
return [];
}
const containsUnknown = file.getStatements().some(s => s.get() instanceof 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;
}
private test(stru: StructureNode, type: new() => IStructure, b: new() => IStatement, e: new() => IStatement, file: ABAPFile): Issue[] {
const output: Issue[] = [];
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 = EditHelper.replaceRange(file, last.getStart(), last.getEnd(), first.getStr());
const message = "BEGIN END names must match";
const issue = 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.atToken(file, first, message, this.getMetadata().key, this.conf.severity);
output.push(issue);
}
}
return output;
}
} |