All files / src/rules nesting.ts

100% Statements 82/82
100% Branches 24/24
100% Functions 7/7
100% Lines 82/82

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 821x 1x 1x 1x 1x 1x 1x 21989x 21989x 21989x 21989x 1x 10995x 10995x 10995x 10995x 10995x 32796x 32796x 32796x 32796x 32796x 32796x 32796x 32796x 32796x 10995x 10995x 1x 1x 10995x 10995x 10444x 10444x 10995x 10995x 260x 260x 10995x 10995x 272x 272x 272x 272x 272x 1542x 1542x 1542x 1542x 1542x 1542x 1542x 1542x 1542x 46x 1542x 1496x 1496x 1496x 1496x 1496x 1496x 35x 35x 1542x 1542x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1542x 272x 272x 272x 10995x 10995x
import {Issue} from "../issue";
import * as Statements from "../abap/2_statements/statements";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class NestingConf extends BasicRuleConfig {
  /** Maximum allowed nesting depth */
  public depth: number = 5;
}
 
export class Nesting extends ABAPRule {
 
  private conf = new NestingConf();
 
  public getMetadata() {
    return {
      key: "nesting",
      title: "Check nesting depth",
      shortDescription: `Checks for methods exceeding a maximum nesting depth`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#keep-the-nesting-depth-low
https://docs.abapopenchecks.org/checks/74/`,
      tags: [RuleTag.Styleguide, RuleTag.SingleFile],
    };
  }
 
  private getDescription(max: string): string {
    return "Reduce nesting depth to max " + max;
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: NestingConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    let depth: number = 0;
 
    for (const statement of file.getStatements()) {
      const type = statement.get();
 
      if (type instanceof Statements.If
        || type instanceof Statements.Case
        || type instanceof Statements.While
        || type instanceof Statements.Loop
        || type instanceof Statements.SelectLoop
        || type instanceof Statements.Do
        || type instanceof Statements.Try) {
        depth = depth + 1;
      } else if (type instanceof Statements.EndIf
        || type instanceof Statements.EndCase
        || type instanceof Statements.EndWhile
        || type instanceof Statements.EndLoop
        || type instanceof Statements.EndSelect
        || type instanceof Statements.EndDo
        || type instanceof Statements.EndTry) {
        depth = depth - 1;
      }
 
      if (depth > this.conf.depth) {
        const pos = statement.getFirstToken().getStart();
        const issue = Issue.atPosition(
          file,
          pos,
          this.getDescription(this.conf.depth.toString()),
          this.getMetadata().key,
          this.conf.severity);
        issues.push(issue);
        break; // only one finding per file
      }
    }
 
    return issues;
  }
 
}