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 20677x 20677x 20677x 20677x 1x 10339x 10339x 10339x 10339x 10339x 30847x 30847x 30847x 30847x 30847x 30847x 30847x 30847x 30847x 10339x 10339x 1x 1x 10339x 10339x 9826x 9826x 10339x 10339x 241x 241x 10339x 10339x 254x 254x 254x 254x 254x 1445x 1445x 1445x 1445x 1445x 1445x 1445x 1445x 1445x 45x 1445x 1400x 1400x 1400x 1400x 1400x 1400x 34x 34x 1445x 1445x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1445x 254x 254x 254x 10339x 10339x
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;
  }
 
}