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 22903x 22903x 22903x 22903x 1x 11452x 11452x 11452x 11452x 11452x 34257x 34257x 34257x 34257x 34257x 34257x 34257x 34257x 34257x 34257x 11452x 11452x 10927x 10927x 11452x 11452x 247x 247x 11452x 11452x 275x 275x 275x 275x 275x 3x 3x 272x 275x 1537x 1537x 1537x 52x 1537x 1485x 40x 37x 37x 40x 1485x 1445x 40x 40x 1445x 1405x 1405x 92x 1537x 3x 3x 89x 89x 89x 1537x 45x 1537x 44x 44x 44x 44x 1537x 1537x 272x 272x 272x 11452x 11452x
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;
  }
 
}