All files / src/rules selection_screen_texts_missing.ts

95.83% Statements 92/96
89.47% Branches 17/19
100% Functions 7/7
95.83% Lines 92/96

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 971x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11760x 11760x 11760x 11760x 11760x 11760x 35106x 35106x 35106x 35106x 35106x 35106x 11760x 11760x 11241x 11241x 11760x 11760x 239x 239x 11760x 11760x 250x 250x 250x 11760x 11760x 326x 143x 143x 183x 326x 4x 4x 179x 179x 179x 179x 179x 179x 179x 179x 179x 11760x 11760x 182x     182x 182x     182x 182x 182x 998x 998x 15x 15x 15x 15x 10x 10x 10x 10x 10x 10x 10x 15x 998x 3x 3x 3x 3x 3x 3x 3x 3x 3x 998x 182x 11760x  
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} 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`,
    };
  }
 
  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>) {
    if (file === undefined) {
      return;
    }
 
    if (checked.has(file.getFilename())) {
      return;
    }
    checked.add(file.getFilename());
 
    for (const stat of file.getStatements()) {
      const s = stat.get();
      if (s instanceof Parameter || s instanceof SelectOption) {
        const fieldNode = stat.findFirstExpression(FieldSub);
        if (fieldNode) {
          const fieldName = fieldNode.getFirstToken().getStr().toUpperCase();
          if (selTexts[fieldName] === undefined) {
            output.push(Issue.atToken(
              file,
              fieldNode.getFirstToken(),
              `Selection text missing for "${fieldName}"`,
              this.getMetadata().key,
              this.conf.severity));
          }
        }
      } else 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);
          }
        }
      }
    }
  }
}