@abaplint/core
Version:
abaplint - Core API
152 lines • 6.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalVariableNames = exports.LocalVariableNamesConf = void 0;
const issue_1 = require("../issue");
const _abap_rule_1 = require("./_abap_rule");
const Structures = require("../abap/3_structures/structures");
const Statements = require("../abap/2_statements/statements");
const Expressions = require("../abap/2_statements/expressions");
const _naming_rule_config_1 = require("./_naming_rule_config");
const name_validator_1 = require("../utils/name_validator");
const _irule_1 = require("./_irule");
class LocalVariableNamesConf extends _naming_rule_config_1.NamingRuleConfig {
constructor() {
super(...arguments);
/** The pattern for local variable names */
this.expectedData = "^L._.+$";
/** The pattern for local constant names */
this.expectedConstant = "^LC_.+$";
/** The pattern for field symbol names */
this.expectedFS = "^<L._.+>$";
}
}
exports.LocalVariableNamesConf = LocalVariableNamesConf;
class LocalVariableNames extends _abap_rule_1.ABAPRule {
constructor() {
super(...arguments);
this.conf = new LocalVariableNamesConf();
}
getMetadata() {
return {
key: "local_variable_names",
title: "Local variable naming conventions",
shortDescription: `
Allows you to enforce a pattern, such as a prefix, for local variables, constants and field symbols.
Regexes are case-insensitive.`,
tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.SingleFile],
badExample: `FORM bar.
DATA foo.
ENDFORM.`,
goodExample: `FORM bar.
DATA lv_foo.
ENDFORM.`,
};
}
getDescription(expected, actual) {
return this.conf.patternKind === "required" ?
"Local variable name does not match pattern " + expected + ": " + actual :
"Local variable name must not match pattern " + expected + ": " + actual;
}
getConfig() {
return this.conf;
}
setConfig(conf) {
this.conf = conf;
}
runParsed(file) {
const ret = [];
if (this.conf.patternKind === undefined) {
this.conf.patternKind = "required";
}
const stru = file.getStructure();
if (stru === undefined) {
return [];
}
// inside METHOD, FORM, FUNCTION MODULE
for (const node of stru.findAllStructures(Structures.Form)) {
ret.push(...this.checkLocals(node, file));
}
for (const node of stru.findAllStructures(Structures.Method)) {
ret.push(...this.checkLocals(node, file));
}
for (const node of stru.findAllStructures(Structures.FunctionModule)) {
ret.push(...this.checkLocals(node, file));
}
return ret;
}
checkLocals(structure, file) {
let ret = [];
// data, field symbols
for (const dat of structure.findAllStatements(Statements.Data)) {
const parent = structure.findParent(dat);
if (parent && parent.get() instanceof Structures.Data) {
continue; // inside DATA BEGIN OF
}
const found = dat.findFirstExpression(Expressions.DefinitionName);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedData));
}
}
// inline data
for (const dat of structure.findAllExpressions(Expressions.InlineData)) {
const found = dat.findFirstExpression(Expressions.TargetField);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedData));
}
}
// data structures, data begin of, first level
const dataStructures = structure.findAllStructures(Structures.Data);
for (const struc of dataStructures) {
// ignore nested DATA BEGIN
const stat = struc.findFirstStatement(Statements.DataBegin);
const found = stat === null || stat === void 0 ? void 0 : stat.findFirstExpression(Expressions.DefinitionName);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedData));
}
}
for (const fieldsymbol of structure.findAllStatements(Statements.FieldSymbol)) {
const found = fieldsymbol.findFirstExpression(Expressions.FieldSymbol);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedFS));
}
}
// inline field symbols
for (const fieldsymbol of structure.findAllExpressions(Expressions.InlineFS)) {
const found = fieldsymbol.findFirstExpression(Expressions.TargetFieldSymbol);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedFS));
}
}
const constants = structure.findAllStatements(Statements.Constant);
for (const constant of constants) {
const parent = structure.findParent(constant);
if (parent && parent.get() instanceof Structures.Constants) {
continue; // inside DATA BEGIN OF
}
const found = constant.findFirstExpression(Expressions.DefinitionName);
if (found) {
const token = found.getFirstToken();
ret = ret.concat(this.checkName(token, file, this.conf.expectedConstant));
}
}
return ret;
}
checkName(token, file, expected) {
const ret = [];
const regex = new RegExp(expected, "i");
const name = token.getStr();
if (name_validator_1.NameValidator.violatesRule(name, regex, this.conf)) {
const message = this.getDescription(expected, name);
const issue = issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity);
ret.push(issue);
}
return ret;
}
}
exports.LocalVariableNames = LocalVariableNames;
//# sourceMappingURL=local_variable_names.js.map