@abaplint/core 2.85.54 → 2.86.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/abap/5_syntax/expressions/source.js +7 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/avoid_use.js +6 -1
- package/build/src/rules/check_text_elements.js +13 -10
- package/build/src/rules/downport.js +23 -7
- package/build/src/rules/index.js +1 -0
- package/build/src/rules/many_parentheses.js +19 -0
- package/build/src/rules/nrob_consistency.js +60 -0
- package/package.json +1 -1
|
@@ -23,6 +23,7 @@ const corresponding_body_1 = require("./corresponding_body");
|
|
|
23
23
|
const _builtin_1 = require("../_builtin");
|
|
24
24
|
const attribute_chain_1 = require("./attribute_chain");
|
|
25
25
|
const dereference_1 = require("./dereference");
|
|
26
|
+
const _typed_identifier_1 = require("../../types/_typed_identifier");
|
|
26
27
|
/*
|
|
27
28
|
* Type interference, valid scenarios:
|
|
28
29
|
* typed = VALUE #( ... ). right hand side must follow left hand type
|
|
@@ -170,11 +171,16 @@ class Source {
|
|
|
170
171
|
const typeExpression = node.findFirstExpression(Expressions.TypeNameOrInfer);
|
|
171
172
|
const typeToken = typeExpression === null || typeExpression === void 0 ? void 0 : typeExpression.getFirstToken();
|
|
172
173
|
const typeName = typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStr();
|
|
173
|
-
if (typeName === "#" && inferredType) {
|
|
174
|
+
if (typeName === "#" && inferredType && typeToken) {
|
|
174
175
|
const found = basic.lookupQualifiedName(inferredType.getQualifiedName());
|
|
175
176
|
if (found) {
|
|
176
177
|
scope.addReference(typeToken, found, _reference_1.ReferenceType.InferredType, filename);
|
|
177
178
|
}
|
|
179
|
+
else if (inferredType instanceof basic_1.CharacterType) {
|
|
180
|
+
// character is bit special it does not have a qualified name eg "TYPE c LENGTH 6"
|
|
181
|
+
const tid = new _typed_identifier_1.TypedIdentifier(typeToken, filename, inferredType);
|
|
182
|
+
scope.addReference(typeToken, tid, _reference_1.ReferenceType.InferredType, filename);
|
|
183
|
+
}
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
186
|
determineType(node, scope, filename, targetType) {
|
package/build/src/registry.js
CHANGED
|
@@ -41,7 +41,9 @@ Macros: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenmacros_gu
|
|
|
41
41
|
|
|
42
42
|
STATICS: use CLASS-DATA instead
|
|
43
43
|
|
|
44
|
-
DESCRIBE TABLE LINES: use lines() instead (quickfix exists)
|
|
44
|
+
DESCRIBE TABLE LINES: use lines() instead (quickfix exists)
|
|
45
|
+
|
|
46
|
+
TEST-SEAMS: https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use-test-seams-as-temporary-workaround`,
|
|
45
47
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
|
|
46
48
|
};
|
|
47
49
|
}
|
|
@@ -79,6 +81,9 @@ DESCRIBE TABLE LINES: use lines() instead (quickfix exists)`,
|
|
|
79
81
|
else if (this.conf.statics && statement instanceof Statements.StaticEnd) {
|
|
80
82
|
isStaticsBlock = false;
|
|
81
83
|
}
|
|
84
|
+
else if (this.conf.statics && statement instanceof Statements.TestSeam) {
|
|
85
|
+
message = "TEST-SEAM";
|
|
86
|
+
}
|
|
82
87
|
else if (this.conf.statics && statement instanceof Statements.Static && isStaticsBlock === false) {
|
|
83
88
|
message = "STATICS";
|
|
84
89
|
}
|
|
@@ -43,17 +43,20 @@ class CheckTextElements {
|
|
|
43
43
|
}
|
|
44
44
|
let texts;
|
|
45
45
|
let mainName = undefined;
|
|
46
|
-
const mains = this.graph.listMainForInclude(file.getFilename());
|
|
47
|
-
if (mains.length === 1) {
|
|
48
|
-
// todo, this only checks the first main
|
|
49
|
-
mainName = mains[0];
|
|
50
|
-
const main1 = this.reg.findObjectForFile(this.reg.getFileByName(mains[0]));
|
|
51
|
-
texts = main1.getTexts();
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
texts = obj.getTexts();
|
|
55
|
-
}
|
|
56
46
|
const expressions = stru.findAllExpressionsMulti([Expressions.TextElement, Expressions.TextElementString]);
|
|
47
|
+
// optimize: no need to find main and texts if there are no expressions to check
|
|
48
|
+
if (expressions.length > 0) {
|
|
49
|
+
const mains = this.graph.listMainForInclude(file.getFilename());
|
|
50
|
+
if (mains.length === 1) {
|
|
51
|
+
// todo, this only checks the first main
|
|
52
|
+
mainName = mains[0];
|
|
53
|
+
const main1 = this.reg.findObjectForFile(this.reg.getFileByName(mains[0]));
|
|
54
|
+
texts = main1.getTexts();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
texts = obj.getTexts();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
57
60
|
for (const e of expressions) {
|
|
58
61
|
if (e.get() instanceof Expressions.TextElement) {
|
|
59
62
|
const token = e.findFirstExpression(Expressions.TextElementKey).getFirstToken();
|
|
@@ -933,7 +933,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
933
933
|
return { body, end };
|
|
934
934
|
}
|
|
935
935
|
outlineSwitch(node, lowFile, highSyntax) {
|
|
936
|
-
var _a, _b, _c;
|
|
936
|
+
var _a, _b, _c, _d;
|
|
937
937
|
for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {
|
|
938
938
|
const firstToken = i.getFirstToken();
|
|
939
939
|
if (firstToken.getStr().toUpperCase() !== "SWITCH") {
|
|
@@ -941,8 +941,10 @@ ${indentation} output = ${topTarget}.`;
|
|
|
941
941
|
}
|
|
942
942
|
let type = this.findType(i, lowFile, highSyntax);
|
|
943
943
|
if (type === undefined) {
|
|
944
|
-
if (node.get() instanceof Statements.Move
|
|
945
|
-
|
|
944
|
+
if (node.get() instanceof Statements.Move
|
|
945
|
+
&& node.findDirectExpression(Expressions.Source) === i
|
|
946
|
+
&& ((_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.TargetField)) !== undefined) {
|
|
947
|
+
type = "LIKE " + ((_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
|
|
946
948
|
}
|
|
947
949
|
if (type === undefined) {
|
|
948
950
|
continue;
|
|
@@ -959,9 +961,9 @@ ${indentation} output = ${topTarget}.`;
|
|
|
959
961
|
if (switchBody === undefined) {
|
|
960
962
|
continue;
|
|
961
963
|
}
|
|
962
|
-
for (const l of ((
|
|
964
|
+
for (const l of ((_c = switchBody === null || switchBody === void 0 ? void 0 : switchBody.findDirectExpression(Expressions.Let)) === null || _c === void 0 ? void 0 : _c.findDirectExpressions(Expressions.InlineFieldDefinition)) || []) {
|
|
963
965
|
name = l.getFirstToken().getStr();
|
|
964
|
-
body += indentation + `DATA(${name}) = ${(
|
|
966
|
+
body += indentation + `DATA(${name}) = ${(_d = switchBody.findFirstExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens()}.\n`;
|
|
965
967
|
}
|
|
966
968
|
body += `DATA ${uniqueName} ${type}.\n`;
|
|
967
969
|
let firstSource = false;
|
|
@@ -1267,6 +1269,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1267
1269
|
return undefined;
|
|
1268
1270
|
}
|
|
1269
1271
|
outlineCond(node, lowFile, highSyntax) {
|
|
1272
|
+
var _a, _b;
|
|
1270
1273
|
for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {
|
|
1271
1274
|
if (i.getFirstToken().getStr().toUpperCase() !== "COND") {
|
|
1272
1275
|
continue;
|
|
@@ -1276,10 +1279,23 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1276
1279
|
continue;
|
|
1277
1280
|
}
|
|
1278
1281
|
const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1279
|
-
|
|
1282
|
+
let type = this.findType(i, lowFile, highSyntax);
|
|
1283
|
+
if (type === undefined) {
|
|
1284
|
+
if (node.get() instanceof Statements.Move
|
|
1285
|
+
&& node.findDirectExpression(Expressions.Source) === i
|
|
1286
|
+
&& ((_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.TargetField)) !== undefined) {
|
|
1287
|
+
type = "LIKE " + ((_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
|
|
1288
|
+
}
|
|
1289
|
+
if (type === undefined) {
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
type = "TYPE " + type;
|
|
1295
|
+
}
|
|
1280
1296
|
const indent = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1281
1297
|
const bodyCode = this.buildCondBody(body, uniqueName, indent, lowFile, highSyntax);
|
|
1282
|
-
const abap = `DATA ${uniqueName}
|
|
1298
|
+
const abap = `DATA ${uniqueName} ${type}.\n` + bodyCode;
|
|
1283
1299
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
|
|
1284
1300
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);
|
|
1285
1301
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
package/build/src/rules/index.js
CHANGED
|
@@ -101,6 +101,7 @@ __exportStar(require("./no_aliases"), exports);
|
|
|
101
101
|
__exportStar(require("./no_chained_assignment"), exports);
|
|
102
102
|
__exportStar(require("./no_public_attributes"), exports);
|
|
103
103
|
__exportStar(require("./no_yoda_conditions"), exports);
|
|
104
|
+
__exportStar(require("./nrob_consistency"), exports);
|
|
104
105
|
__exportStar(require("./object_naming"), exports);
|
|
105
106
|
__exportStar(require("./obsolete_statement"), exports);
|
|
106
107
|
__exportStar(require("./omit_parameter_name"), exports);
|
|
@@ -68,9 +68,28 @@ ENDIF.
|
|
|
68
68
|
for (const m of structure.findAllStatements(Statements.Move)) {
|
|
69
69
|
issues.push(...this.analyzeMove(file, m));
|
|
70
70
|
}
|
|
71
|
+
for (const m of structure.findAllStatements(Statements.Select)) {
|
|
72
|
+
issues.push(...this.analyzeInto(file, m));
|
|
73
|
+
}
|
|
71
74
|
return issues;
|
|
72
75
|
}
|
|
73
76
|
////////////////////
|
|
77
|
+
analyzeInto(file, m) {
|
|
78
|
+
const into = m.findFirstExpression(Expressions.SQLIntoStructure);
|
|
79
|
+
if (into === undefined) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const second = into.getAllTokens()[1];
|
|
83
|
+
if (second === undefined || second.getStr() !== "(") {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const concat = into.concatTokens();
|
|
87
|
+
if (concat.endsWith(")") === true && concat.includes(",") === false) {
|
|
88
|
+
const issue = issue_1.Issue.atStatement(file, m, "Too many parentheses", this.getMetadata().key, this.conf.severity);
|
|
89
|
+
return [issue];
|
|
90
|
+
}
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
74
93
|
analyzeMove(file, m) {
|
|
75
94
|
const issues = [];
|
|
76
95
|
const children = m.getChildren();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NROBConsistency = exports.NROBConsistencyConf = void 0;
|
|
4
|
+
const _irule_1 = require("./_irule");
|
|
5
|
+
const issue_1 = require("../issue");
|
|
6
|
+
const Objects = require("../objects");
|
|
7
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
8
|
+
class NROBConsistencyConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
9
|
+
}
|
|
10
|
+
exports.NROBConsistencyConf = NROBConsistencyConf;
|
|
11
|
+
class NROBConsistency {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.conf = new NROBConsistencyConf();
|
|
14
|
+
}
|
|
15
|
+
getMetadata() {
|
|
16
|
+
return {
|
|
17
|
+
key: "nrob_consistency",
|
|
18
|
+
title: "Number range consistency",
|
|
19
|
+
shortDescription: `Consistency checks for number ranges`,
|
|
20
|
+
extendedInformation: `Issue reported if percentage warning is over 50%
|
|
21
|
+
|
|
22
|
+
Issue reported if the referenced domain is not found(taking error namespace into account)`,
|
|
23
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
getConfig() {
|
|
27
|
+
return this.conf;
|
|
28
|
+
}
|
|
29
|
+
setConfig(conf) {
|
|
30
|
+
this.conf = conf;
|
|
31
|
+
}
|
|
32
|
+
initialize(reg) {
|
|
33
|
+
this.reg = reg;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
run(obj) {
|
|
37
|
+
if (!(obj instanceof Objects.NumberRange)) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const issues = [];
|
|
41
|
+
const id = obj.getIdentifier();
|
|
42
|
+
if (id === undefined) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
if (obj.getPercentage() || 0 > 50) {
|
|
46
|
+
const message = "Percentage more than 50";
|
|
47
|
+
issues.push(issue_1.Issue.atIdentifier(id, message, this.getMetadata().key, this.getConfig().severity));
|
|
48
|
+
}
|
|
49
|
+
const domain = obj.getDomain();
|
|
50
|
+
if (domain
|
|
51
|
+
&& this.reg.getObject("DOMA", domain) === undefined
|
|
52
|
+
&& this.reg.inErrorNamespace(domain) === true) {
|
|
53
|
+
const message = "Domain " + domain + " not found";
|
|
54
|
+
issues.push(issue_1.Issue.atIdentifier(id, message, this.getMetadata().key, this.getConfig().severity));
|
|
55
|
+
}
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.NROBConsistency = NROBConsistency;
|
|
60
|
+
//# sourceMappingURL=nrob_consistency.js.map
|