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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 29428x 1x 14731x 14731x 14731x 14731x 14731x 14731x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 156907x 14731x 14731x 40x 40x 40x 40x 14731x 14731x 14120x 14120x 14731x 14731x 312x 312x 312x 14731x 14731x 15043x 15043x 15043x 15043x 15043x 15043x 15043x 14731x 14731x 341x 16x 16x 341x 341x 341x 160x 160x 89x 89x 71x 71x 341x 341x 338x 75x 41x 41x 34x 34x 338x 341x 341x 341x 14731x 14731x 341x 341x 341x 341x 71x 71x 36x 36x 71x 11x 11x 71x 24x 24x 71x 71x 71x 341x 341x 14731x 14731x 71x 71x 71x 40x 40x 40x 71x 71x 71x 14731x 14731x | import {Issue} from "../issue";
import {NamingRuleConfig} from "./_naming_rule_config";
import {NameValidator} from "../utils/name_validator";
import {ABAPRule} from "./_abap_rule";
import {Identifier} from "../abap/4_file_information/_identifier";
import {InfoAttribute, AttributeLevel} from "../abap/4_file_information/_abap_file_information";
import {RuleTag} from "./_irule";
import {ABAPObject} from "../objects/_abap_object";
import {DDIC} from "../ddic";
import {ABAPFile} from "../abap/abap_file";
export class ClassAttributeNamesConf extends NamingRuleConfig {
/** Ignore global exception classes */
public ignoreExceptions: boolean = true;
/** Ignore local classes */
public ignoreLocal: boolean = true;
/** Ignore interfaces */
public ignoreInterfaces: boolean = false;
/** The pattern for static variable names */
public statics: string = "^G._.+$";
/** The pattern for instance variable names */
public instance: string = "^M._.+$";
/** The pattern for constant variable names */
public constants: string = "";
}
export class ClassAttributeNames extends ABAPRule {
private conf = new ClassAttributeNamesConf();
private regex = this.compile();
public getMetadata() {
return {
key: "class_attribute_names",
title: "Class attributes naming",
shortDescription: `Allows you to enforce a pattern, such as a prefix, for class variable names.`,
tags: [RuleTag.Naming, RuleTag.SingleFile],
badExample: `CLASS zcl_foo DEFINITION PUBLIC.
PUBLIC SECTION.
DATA counter TYPE i.
ENDCLASS.`,
goodExample: `CLASS zcl_foo DEFINITION PUBLIC.
PUBLIC SECTION.
DATA mv_counter TYPE i.
ENDCLASS.`,
};
}
private getDescription(actual: string, expected: string): string {
return this.conf.patternKind === "required" ?
"Class attribute name \"" + actual + "\" does not match pattern " + expected :
"Class attribute name \"" + actual + "\" must not match pattern " + expected;
}
public getConfig() {
return this.conf;
}
public setConfig(conf: ClassAttributeNamesConf) {
this.conf = conf;
this.regex = this.compile();
}
private compile() {
return {
statics: new RegExp(this.conf.statics, "i"),
instance: new RegExp(this.conf.instance, "i"),
constants: new RegExp(this.conf.constants, "i"),
ignorePatterns: NameValidator.compileIgnorePatterns(this.conf),
};
}
public runParsed(file: ABAPFile, obj: ABAPObject): Issue[] {
if (this.conf.patternKind === undefined) {
this.conf.patternKind = "required";
}
let attributes: InfoAttribute[] = [];
const ddic = new DDIC(this.reg);
for (const classDef of file.getInfo().listClassDefinitions()) {
if ((classDef.isLocal && this.conf.ignoreLocal)
|| (ddic.isException(classDef, obj) && this.conf.ignoreExceptions)) {
continue;
}
attributes = attributes.concat(classDef.attributes);
}
if (this.conf.ignoreInterfaces === false) {
for (const intfDef of file.getInfo().listInterfaceDefinitions()) {
if (intfDef.isLocal && this.conf.ignoreLocal) {
continue;
}
attributes = attributes.concat(intfDef.attributes);
}
}
return this.checkAttributes(attributes);
}
private checkAttributes(attr: InfoAttribute[] | undefined): Issue[] {
if (attr === undefined) {
return [];
}
let ret: Issue[] = [];
for (const a of attr) {
switch (a.level) {
case AttributeLevel.Instance:
ret = ret.concat(this.checkName(a.identifier, this.conf.instance, this.regex.instance));
break;
case AttributeLevel.Static:
ret = ret.concat(this.checkName(a.identifier, this.conf.statics, this.regex.statics));
break;
case AttributeLevel.Constant:
ret = ret.concat(this.checkName(a.identifier, this.conf.constants, this.regex.constants));
break;
default:
break;
}
}
return ret;
}
private checkName(attr: Identifier, expected: string, regex: RegExp): Issue[] {
const ret: Issue[] = [];
const name = attr.getName();
if (NameValidator.violatesRule(name, regex, this.conf, this.regex.ignorePatterns)) {
const issue = Issue.atIdentifier(attr, this.getDescription(name, expected), this.getMetadata().key, this.conf.severity);
ret.push(issue);
}
return ret;
}
}
|