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 106 107 108 109 110 111 112 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11088x 11088x 11088x 11088x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 33134x 11088x 11088x 10568x 10568x 11088x 11088x 244x 244x 11088x 11088x 294x 294x 294x 294x 12x 12x 282x 282x 294x 10x 10x 272x 272x 272x 272x 272x 272x 272x 272x 272x 272x 11088x 11088x 1632x 1632x 1632x 83x 83x 83x 83x 83x 83x 39x 39x 83x 1x 1x 82x 82x 82x 83x 38x 38x 83x 1x 1x 81x 81x 83x 11x 11x 11x 11x 11x 81x 83x 1x 1x 1x 1x 83x 1632x 1632x 1632x 11088x 11088x | 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)) {
const beginStatement = sub.findDirectStatement(b);
const endStatement = sub.findDirectStatement(e);
if (beginStatement === undefined || endStatement === undefined) {
continue;
}
let begin = beginStatement.findFirstExpression(Expressions.NamespaceSimpleName);
if (begin === undefined) {
begin = beginStatement.findFirstExpression(Expressions.DefinitionName);
}
if (begin === undefined) {
continue;
}
const first = begin.getFirstToken();
let end = endStatement.findFirstExpression(Expressions.NamespaceSimpleName);
if (end === undefined) {
end = endStatement.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;
}
}
|