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 113 114 115 116 117 118 119 120 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 14698x 14698x 14698x 14698x 14698x 14698x 58040x 58040x 58040x 58040x 58040x 58040x 58040x 58040x 58040x 14698x 14698x 14120x 14120x 14698x 14698x 264x 264x 14698x 14698x 281x 281x 281x 14698x 14698x 383x 156x 156x 227x 383x 24x 24x 203x 203x 203x 203x 203x 203x 203x 203x 203x 14698x 14698x 230x 230x 230x 230x 6x 6x 224x 224x 224x 230x 1181x 1181x 4x 4x 2x 2x 2x 2x 2x 4x 4x 1181x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 1181x 1129x 1129x 1181x 2x 2x 19x 19x 19x 19x 19x 13x 13x 13x 13x 13x 13x 13x 13x 19x 1181x 224x 14698x | import {IRule, IRuleMetadata} from "./_irule";
import {Issue} from "../issue";
import {BasicRuleConfig} from "./_basic_rule_config";
import {ITextElements} from "../objects/_abap_object";
import {IObject} from "../objects/_iobject";
import {IRegistry} from "../_iregistry";
import {Parameter, SelectOption, Include, SelectionScreen} from "../abap/2_statements/statements";
import {FieldSub, IncludeName} from "../abap/2_statements/expressions";
import {Program} from "../objects";
import {ABAPFile} from "../abap/abap_file";
export class SelectionScreenTextsMissingConf extends BasicRuleConfig {
}
export class SelectionScreenTextsMissing implements IRule {
private reg: IRegistry;
private conf = new SelectionScreenTextsMissingConf();
public getMetadata(): IRuleMetadata {
return {
key: "selection_screen_texts_missing",
title: "Selection screen texts missing",
shortDescription: `Checks that selection screen parameters and select-options have selection texts`,
extendedInformation: `Excludes parameters and select-options that:
* are inside a "SELECTION-SCREEN BEGIN OF LINE" block
* have the addition "NO-DISPLAY"`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: SelectionScreenTextsMissingConf) {
this.conf = conf;
}
public initialize(reg: IRegistry) {
this.reg = reg;
return this;
}
public run(obj: IObject): Issue[] {
if (!(obj instanceof Program)) {
return [];
}
if (obj.isInclude()) {
return [];
}
const selTexts = obj.getSelectionTexts();
const output: Issue[] = [];
const checked = new Set<string>();
this.checkFile(obj.getMainABAPFile(), selTexts, output, checked);
return output;
}
private checkFile(file: ABAPFile | undefined, selTexts: ITextElements,
output: Issue[], checked: Set<string>, mainProgName: string | undefined = undefined) {
if (file === undefined) {
return;
}
if (checked.has(file.getFilename())) {
return;
}
checked.add(file.getFilename());
let inLine = false;
for (const stat of file.getStatements()) {
const s = stat.get();
if (s instanceof SelectionScreen) {
const tokens = stat.concatTokens().toUpperCase();
if (tokens.includes("BEGIN OF LINE")) {
inLine = true;
} else if (tokens.includes("END OF LINE")) {
// known issue: doesn't support BEGIN and END OF LINE span across several includes (not seen a lot in the wild)
inLine = false;
}
continue;
}
if (s instanceof Include) {
const nameNode = stat.findFirstExpression(IncludeName);
if (nameNode) {
const inclName = nameNode.getFirstToken().getStr().toUpperCase();
const inclObj = this.reg.getObject("PROG", inclName) as Program | undefined;
if (inclObj) {
this.checkFile(inclObj.getMainABAPFile(), selTexts, output, checked, mainProgName ?? file.getFilename());
}
}
continue;
}
if (inLine || !(s instanceof Parameter || s instanceof SelectOption)) {
continue;
}
if (stat.concatTokens().toUpperCase().includes("NO-DISPLAY")) {
continue;
}
const fieldNode = stat.findFirstExpression(FieldSub);
if (fieldNode) {
const fieldName = fieldNode.getFirstToken().getStr().toUpperCase();
if (selTexts[fieldName] === undefined) {
const suffix = mainProgName ? `, ${mainProgName}` : ``;
output.push(Issue.atToken(
file,
fieldNode.getFirstToken(),
`Selection text missing for "${fieldName}"${suffix}`,
this.getMetadata().key,
this.conf.severity));
}
}
}
}
}
|