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 22610x 22610x 22610x 1x 11306x 11306x 11306x 11306x 11306x 33784x 33784x 33784x 33784x 33784x 33784x 33784x 33784x 33784x 33784x 11306x 11306x 11063x 11063x 11306x 11306x 232x 232x 11306x 11306x 253x 253x 253x 253x     253x 253x 253x 1396x 1396x 1219x 1219x 177x 177x 177x 1396x 2x 2x 2x 177x 177x 177x 1396x 3x 3x 3x 177x 1396x 1396x 1396x 109x 1396x 43x 43x 25x 25x 25x 25x 25x 25x 1396x     1396x 253x 253x 253x 11306x 11306x  
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;
  }
 
}