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 88 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 21989x 21989x 21989x 21989x 1x 10995x 10995x 10995x 10995x 10995x 32836x 32836x 32836x 32836x 32836x 32836x 32836x 32836x 32836x 32836x 10995x 10995x 10444x 10444x 10995x 10995x 260x 260x 10995x 10995x 279x 279x 279x 279x 279x 3x 3x 276x 279x 1547x 1547x 1547x 48x 1547x 1499x 34x 31x 31x 34x 1499x 1465x 34x 34x 1465x 1431x 1431x 82x 1547x 3x 3x 79x 79x 79x 1547x 38x 1547x 41x 41x 41x 41x 1547x 1547x 276x 276x 276x 10995x 10995x | 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; } } |