All files / src/rules short_case.ts

97.26% Statements 71/73
93.33% Branches 14/15
100% Functions 7/7
97.26% Lines 71/73

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 731x 1x 1x 1x 1x 1x 1x 1x 1x 21011x 21011x 21011x 21011x 21011x 21011x 21011x 21011x 21011x 21011x 1x 10506x 10506x 10506x 10506x 31339x 31339x 31339x 31339x 31339x 31339x 31339x 31339x 31339x 31339x 10506x 10506x 3x 3x 10506x 10506x 9971x 9971x 10506x 10506x 254x 254x 10506x 10506x 271x 271x 271x 271x 12x 12x 259x 271x 8x 8x     8x 8x 4x 1x 1x 3x 3x 3x 8x 259x 259x 259x 10506x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import * as Structures from "../abap/3_structures/structures";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class ShortCaseConf extends BasicRuleConfig {
  /** The smallest number of WHEN branches which will trigger a violation.
   * Example: if length = 1, at least 2 branches are required
   */
  public length: number = 1;
  /** List of inputs for CASE which are allowed
   * @uniqueItems true
  */
  public allow: string[] = [];
}
 
export class ShortCase extends ABAPRule {
  private conf = new ShortCaseConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "short_case",
      title: "Short CASE",
      shortDescription: `Checks for CASE statements which have fewer than the specified number of branches`,
      extendedInformation: `Short CASE constructs can be changed to IF`,
      tags: [RuleTag.SingleFile],
      badExample: "CASE moo.\nWHEN 'X'.\nENDCASE.",
      goodExample: "IF moo = 'X'.\nENDIF.",
    };
  }
 
  private getMessage(): string {
    return "CASE construct too short, it must have a minimum of " + (this.conf.length + 1) + " WHEN branches";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: ShortCaseConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    const struc = file.getStructure();
    if (struc === undefined) {
      return [];
    }
 
    for (const c of struc.findAllStructures(Structures.Case)) {
      const clist = c.findDirectStatements(Statements.Case);
      if (clist.length > 0 && this.conf.allow && this.conf.allow.find((e) => { return e === clist[0].getTokens()[1].getStr(); })) {
        continue;
      }
 
      if (c.findDirectStructures(Structures.When).length <= this.conf.length) {
        if (c.findAllExpressions(Expressions.Or).length > 0) {
          continue;
        }
        const issue = Issue.atToken(file, c.getFirstToken(), this.getMessage(), this.getMetadata().key, this.conf.severity);
        issues.push(issue);
      }
    }
 
    return issues;
  }
}