All files / src/rules if_in_if.ts

94.87% Statements 37/39
89.47% Branches 17/19
100% Functions 6/6
94.87% Lines 37/39

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 97 981x 1x 1x 1x 1x       1x     1x   7265x     21662x                                     3x       7008x       114x       139x   139x 10x     129x 129x 12x     117x 117x   117x 14x   5x     9x 9x 4x     5x 5x 2x     3x 3x       3x 3x           3x 3x 3x     117x      
import {Issue} from "../issue";
import * as Structures from "../abap/3_structures/structures";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
 
export class IfInIfConf extends BasicRuleConfig {
}
 
export class IfInIf extends ABAPRule {
 
  private conf = new IfInIfConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "if_in_if",
      title: "IF in IF",
      shortDescription: `Detects nested ifs which can be refactored to a single condition using AND.`,
      extendedInformation: `https://docs.abapopenchecks.org/checks/01/
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#keep-the-nesting-depth-low`,
      badExample: `IF condition1.
  IF condition2.
    ...
  ENDIF.
ENDIF.`,
      goodExample: `IF ( condition1 ) AND ( condition2 ).
  ...
ENDIF.`,
      tags: [RuleTag.Styleguide, RuleTag.SingleFile],
    };
  }
 
  private getMessage(): string {
    return "IF in IF. Use IF cond1 AND cond2 instead";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: IfInIfConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: ABAPObject) {
    const issues: Issue[] = [];
 
    if (obj.getType() === "INTF") {
      return [];
    }
 
    const stru = file.getStructure();
    if (stru === undefined) {
      return [];
    }
 
    let possible = stru.findAllStructures(Structures.If);
    possible = possible.concat(stru.findAllStructures(Structures.Else));
 
    for (const i of possible) {
      if (i.findDirectStructures(Structures.ElseIf).length > 0
          || i.findDirectStructures(Structures.Else).length > 0) {
        continue;
      }
 
      const blist = i.findDirectStructures(Structures.Body);
      if (blist.length === 0) {
        continue;
      }
 
      const nlist = blist[0].findDirectStructures(Structures.Normal);
      if (nlist.length !== 1) {
        continue;
      }
 
      const niflist = nlist[0].findDirectStructures(Structures.If);
      Iif (niflist.length !== 1) {
        continue;
      }
 
      const nestedIf = niflist[0];
      Iif (i.get() instanceof Structures.If
          && (nestedIf.findDirectStructures(Structures.ElseIf).length > 0
          || nestedIf.findDirectStructures(Structures.Else).length > 0)) {
        continue;
      }
 
      const token = i.getFirstToken();
      const issue = Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
      issues.push(issue);
    }
 
    return issues;
  }
 
}