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 23014x 23014x 23014x 1x 11508x 11508x 11508x 11508x 11508x 34389x 34389x 34389x 34389x 34389x 34389x 34389x 34389x 34389x 34389x 11508x 11508x 11262x 11262x 11508x 11508x 235x 235x 11508x 11508x 256x 256x 256x 256x     256x 256x 256x 1401x 1401x 1224x 1224x 177x 177x 177x 1401x 2x 2x 2x 177x 177x 177x 1401x 3x 3x 3x 177x 1401x 1401x 1401x 109x 1401x 43x 43x 25x 25x 25x 25x 25x 25x 1401x     1401x 256x 256x 256x 11508x 11508x  
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;
  }
 
}