All files / src/rules types_naming.ts

100% Statements 88/88
100% Branches 24/24
100% Functions 6/6
100% Lines 88/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 881x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22239x 22239x 22239x 22239x 1x 11120x 11120x 11120x 11120x 11120x 33205x 33205x 33205x 33205x 33205x 33205x 33205x 33205x 33205x 33205x 11120x 11120x 10557x 10557x 11120x 11120x 266x 266x 11120x 11120x 285x 285x 285x 285x 285x 3x 3x 282x 285x 1593x 1593x 1593x 49x 1593x 1544x 36x 33x 33x 36x 1544x 1508x 36x 36x 1508x 1472x 1472x 85x 1593x 3x 3x 82x 82x 82x 1593x 41x 41x 41x 41x 41x 41x 1593x 1593x 282x 282x 282x 11120x 11120x
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 {BasicRuleConfig} from "./_basic_rule_config";
import {ExpressionNode} from "../abap/nodes";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
import {TypePool} from "../objects";
 
export class TypesNamingConf extends BasicRuleConfig {
  /** The pattern for TYPES, case insensitive */
  public pattern: string = "^TY_.+$";
}
 
export class TypesNaming extends ABAPRule {
 
  private conf = new TypesNamingConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "types_naming",
      title: "TYPES naming conventions",
      shortDescription: `Allows you to enforce a pattern for TYPES definitions`,
      extendedInformation: `Does not run for TYPE POOLS`,
      tags: [RuleTag.Naming, RuleTag.SingleFile],
      badExample: `TYPES foo TYPE i.`,
      goodExample: `TYPES ty_foo TYPE i.`,
    };
  }
 
  public getConfig(): TypesNamingConf {
    return this.conf;
  }
 
  public setConfig(conf: TypesNamingConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: ABAPObject) {
    const issues: Issue[] = [];
    const testRegex = new RegExp(this.conf.pattern, "i");
    let nesting = 0;
 
    if (obj instanceof TypePool) {
      return [];
    }
 
    for (const stat of file.getStatements()) {
      let expr: ExpressionNode | undefined = undefined;
 
      if (stat.get() instanceof Statements.Type && nesting === 0) {
        expr = stat.findFirstExpression(Expressions.NamespaceSimpleName);
      } else if (stat.get() instanceof Statements.TypeBegin
          || stat.get() instanceof Statements.TypeEnumBegin) {
        if (nesting === 0) {
          expr = stat.findFirstExpression(Expressions.NamespaceSimpleName);
        }
        nesting = nesting + 1;
      } else if (stat.get() instanceof Statements.TypeEnd
          || stat.get() instanceof Statements.TypeEnumEnd) {
        nesting = nesting - 1;
        continue;
      } else {
        continue;
      }
 
      if (expr === undefined) {
        continue;
      }
 
      const token = expr.getFirstToken();
 
      if (testRegex.exec(token.getStr())) {
        continue;
      } else {
        const message = "Bad TYPES naming, expected \"" + this.conf.pattern + "\", got \"" + token.getStr() + "\"";
        const issue = Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity);
        issues.push(issue);
      }
 
    }
 
    return issues;
  }
 
}