All files / src/rules types_naming.ts

100% Statements 88/88
100% Branches 25/25
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 21787x 21787x 21787x 21787x 1x 10894x 10894x 10894x 10894x 10894x 32535x 32535x 32535x 32535x 32535x 32535x 32535x 32535x 32535x 32535x 10894x 10894x 10347x 10347x 10894x 10894x 258x 258x 10894x 10894x 277x 277x 277x 277x 277x 3x 3x 274x 277x 1537x 1537x 1537x 48x 1537x 1489x 34x 31x 31x 34x 1489x 1455x 34x 34x 1455x 1421x 1421x 82x 1537x 3x 3x 79x 79x 79x 1537x 38x 1537x 41x 41x 41x 41x 1537x 1537x 274x 274x 274x 10894x 10894x
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;
  }
 
}