All files / src/rules types_naming.ts

100% Statements 84/84
100% Branches 23/23
100% Functions 6/6
100% Lines 84/84

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 841x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 15305x 15305x 15305x 15305x 1x 7653x 7653x 7653x 7653x 7653x 22826x 22826x 22826x 22826x 22826x 22826x 22826x 22826x 7653x 7653x 7346x 7346x 7653x 7653x 139x 139x 7653x 7653x 157x 157x 157x 157x 157x 1x 1x 156x 157x 854x 854x 854x 30x 854x 12x 11x 11x 12x 824x 12x 12x 812x 800x 800x 42x 854x 1x 1x 41x 41x 41x 854x 29x 854x 12x 12x 12x 12x 854x 854x 156x 156x 156x 7653x 7653x
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 */
  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],
    };
  }
 
  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) {
        if (nesting === 0) {
          expr = stat.findFirstExpression(Expressions.NamespaceSimpleName);
        }
        nesting = nesting + 1;
      } else if (stat.get() instanceof Statements.TypeEnd) {
        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;
  }
 
}