All files / src/rules fully_type_itabs.ts

100% Statements 77/77
100% Branches 17/17
100% Functions 5/5
100% Lines 77/77

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 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11720x 11720x 11720x 11720x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 35001x 11720x 11720x 11175x 11175x 11720x 11720x 253x 253x 11720x 11720x 280x 280x 280x 1568x 1328x 1328x 240x 240x 1568x 212x 212x 28x 28x 28x 1568x 3x 3x 3x 3x 3x 3x 3x 3x 1568x 1x 25x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1568x 280x 280x 11720x 11720x  
import {BasicRuleConfig} from "./_basic_rule_config";
import {ABAPRule} from "./_abap_rule";
import {Issue} from "../issue";
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class FullyTypeITabsConf extends BasicRuleConfig {
}
 
export class FullyTypeITabs extends ABAPRule {
  private conf = new FullyTypeITabsConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "fully_type_itabs",
      title: "Fully type internal tables",
      shortDescription: `No implict table types or table keys`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use-the-right-table-type
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#avoid-default-key`,
      badExample: `DATA lt_foo TYPE TABLE OF ty.
DATA lt_bar TYPE STANDARD TABLE OF ty.`,
      goodExample: `DATA lt_foo TYPE STANDARD TABLE OF ty WITH EMPTY KEY.`,
      tags: [RuleTag.SingleFile],
    };
  }
 
  public getConfig(): FullyTypeITabsConf {
    return this.conf;
  }
 
  public setConfig(conf: FullyTypeITabsConf): void {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile): Issue[] {
    const issues: Issue[] = [];
 
    for (const statement of file.getStatements()) {
      if (!(statement.get() instanceof Statements.Data || statement.get() instanceof Statements.Type)) {
        continue;
      }
 
      const tt = statement.findFirstExpression(Expressions.TypeTable);
      if (tt === undefined) {
        continue;
      }
 
      const concat = tt.concatTokens().toUpperCase();
 
      if (concat.includes("TYPE TABLE OF")) {
        const message = "Specify table type";
        issues.push(
          Issue.atPosition(
            file,
            tt.getFirstToken().getStart(),
            message,
            this.getMetadata().key,
            this.conf.severity));
      } else if (concat.includes(" TABLE FOR ")) {
        continue;
      } else if (concat.includes(" WITH ") === false && concat.includes(" RANGE OF ") === false) {
        const message = "Specify table key";
        issues.push(
          Issue.atPosition(
            file,
            tt.getFirstToken().getStart(),
            message,
            this.getMetadata().key,
            this.conf.severity));
      }
    }
    return issues;
  }
 
}