All files / src/rules unnecessary_chaining.ts

95.45% Statements 84/88
93.75% Branches 30/32
100% Functions 6/6
95.45% Lines 84/88

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 891x 1x 1x 1x 1x 1x 1x 1x 1x 22556x 22556x 22556x 1x 11279x 11279x 11279x 11279x 11279x 33700x 33700x 33700x 33700x 33700x 33700x 33700x 33700x 33700x 33700x 11279x 11279x 11039x 11039x 11279x 11279x 229x 229x 11279x 11279x 250x 250x 250x 250x     250x 250x 250x 1387x 1387x 1213x 1213x 174x 174x 174x 1387x 2x 2x 2x 174x 174x 174x 1387x 3x 3x 3x 174x 1387x 1387x 1387x 107x 1387x 42x 42x 25x 25x 25x 25x 25x 25x 1387x     1387x 250x 250x 250x 11279x 11279x  
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {EditHelper} from "../edit_helper";
import {Comment} from "../abap/2_statements/statements/_statement";
import {StatementNode} from "../abap/nodes";
 
export class UnnecessaryChainingConf extends BasicRuleConfig {
  public maxIssuesPerFile: number | undefined = 10;
}
 
export class UnnecessaryChaining extends ABAPRule {
 
  private conf = new UnnecessaryChainingConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "unnecessary_chaining",
      title: "Unnecessary Chaining",
      shortDescription: `Find unnecessary chaining, all statements are checked`,
      extendedInformation: ``,
      tags: [RuleTag.SingleFile, RuleTag.Quickfix],
      badExample: `WRITE: bar.`,
      goodExample: `WRITE bar.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: UnnecessaryChainingConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    let max = this.getConfig().maxIssuesPerFile;
    if (max === undefined || max < 1) {
      max = 10;
    }
 
    const statements = file.getStatements();
    for (let i = 0; i < statements.length; i++) {
      const colon = statements[i].getColon();
      if (colon === undefined) {
        continue;
      }
 
      let j = 1;
      let nextStatement = statements[i + j];
      while (nextStatement?.get() instanceof Comment) {
        j++;
        nextStatement = statements[i + j];
      }
 
      j = 1;
      let prevStatement: StatementNode | undefined = statements[i - j];
      while (prevStatement?.get() instanceof Comment) {
        j++;
        prevStatement = statements[i - j];
      }
 
      const next = nextStatement?.getColon();
      const prev = prevStatement?.getColon();
      if (next !== undefined && colon.getStart().equals(next.getStart())) {
        continue;
      } else if (prev !== undefined && colon.getStart().equals(prev.getStart())) {
        continue;
      }
 
      const fix = EditHelper.deleteRange(file, colon.getStart(), colon.getEnd());
      const message = "Unnecessary chaining";
      const issue = Issue.atToken(file, colon, message, this.getMetadata().key, this.conf.severity, fix);
      issues.push(issue);
 
      if (issues.length >= max) {
        break;
      }
    }
 
    return issues;
  }
 
}