@abaplint/core 2.86.1 → 2.86.4
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/registry.js +1 -1
- package/build/src/rules/downport.js +27 -19
- package/build/src/rules/no_aliases.js +6 -0
- package/build/src/rules/unnecessary_chaining.js +7 -3
- package/build/src/rules/unused_types.js +2 -21
- package/build/src/rules/unused_variables.js +2 -2
- package/package.json +2 -2
package/build/src/registry.js
CHANGED
|
@@ -894,26 +894,23 @@ ${indentation} output = ${topTarget}.`;
|
|
|
894
894
|
return undefined;
|
|
895
895
|
}
|
|
896
896
|
outlineFor(forLoop, indentation, lowFile, highSyntax) {
|
|
897
|
-
var _a, _b, _c, _d
|
|
897
|
+
var _a, _b, _c, _d;
|
|
898
898
|
let body = "";
|
|
899
899
|
let end = "";
|
|
900
900
|
const loopSource = (_a = forLoop.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
901
901
|
const loopTargetField = (_b = forLoop.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
902
|
-
if (forLoop.findDirectTokenByText("UNTIL")
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
const
|
|
906
|
-
body += indentation +
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const name = (_f = forLoop.findFirstExpression(Expressions.Field)) === null || _f === void 0 ? void 0 : _f.concatTokens();
|
|
913
|
-
body += indentation + "DATA " + name + " TYPE i.\n";
|
|
902
|
+
if (forLoop.findDirectTokenByText("UNTIL")
|
|
903
|
+
|| forLoop.findDirectTokenByText("WHILE")) {
|
|
904
|
+
const fieldDef = forLoop.findDirectExpression(Expressions.InlineFieldDefinition);
|
|
905
|
+
const field = (_c = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.findFirstExpression(Expressions.Field)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
906
|
+
body += indentation + "DATA " + field + " TYPE i.\n";
|
|
907
|
+
const second = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.getChildren()[2];
|
|
908
|
+
if ((second === null || second === void 0 ? void 0 : second.get()) instanceof Expressions.Source) {
|
|
909
|
+
body += indentation + field + " = " + second.concatTokens() + ".\n";
|
|
910
|
+
}
|
|
911
|
+
const not = forLoop.findDirectTokenByText("UNTIL") ? " NOT" : "";
|
|
914
912
|
const cond = forLoop.findFirstExpression(Expressions.Cond);
|
|
915
|
-
body += indentation + `WHILE ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
|
|
916
|
-
const field = (_h = (_g = forLoop.findDirectExpression(Expressions.InlineFieldDefinition)) === null || _g === void 0 ? void 0 : _g.findFirstExpression(Expressions.Field)) === null || _h === void 0 ? void 0 : _h.concatTokens();
|
|
913
|
+
body += indentation + `WHILE${not} ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
|
|
917
914
|
end += ` ${field} = ${field} + 1.\n`;
|
|
918
915
|
end += indentation + "ENDWHILE";
|
|
919
916
|
}
|
|
@@ -922,7 +919,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
922
919
|
end = "ENDLOOP";
|
|
923
920
|
}
|
|
924
921
|
else if (loopTargetField === undefined) {
|
|
925
|
-
const loopTargetFieldSymbol = (
|
|
922
|
+
const loopTargetFieldSymbol = (_d = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _d === void 0 ? void 0 : _d.concatTokens();
|
|
926
923
|
body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\n`;
|
|
927
924
|
end = "ENDLOOP";
|
|
928
925
|
}
|
|
@@ -1269,6 +1266,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1269
1266
|
return undefined;
|
|
1270
1267
|
}
|
|
1271
1268
|
outlineCond(node, lowFile, highSyntax) {
|
|
1269
|
+
var _a, _b;
|
|
1272
1270
|
for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {
|
|
1273
1271
|
if (i.getFirstToken().getStr().toUpperCase() !== "COND") {
|
|
1274
1272
|
continue;
|
|
@@ -1278,13 +1276,23 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1278
1276
|
continue;
|
|
1279
1277
|
}
|
|
1280
1278
|
const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1281
|
-
|
|
1279
|
+
let type = this.findType(i, lowFile, highSyntax);
|
|
1282
1280
|
if (type === undefined) {
|
|
1283
|
-
|
|
1281
|
+
if (node.get() instanceof Statements.Move
|
|
1282
|
+
&& node.findDirectExpression(Expressions.Source) === i
|
|
1283
|
+
&& ((_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.TargetField)) !== undefined) {
|
|
1284
|
+
type = "LIKE " + ((_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
|
|
1285
|
+
}
|
|
1286
|
+
if (type === undefined) {
|
|
1287
|
+
continue;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
else {
|
|
1291
|
+
type = "TYPE " + type;
|
|
1284
1292
|
}
|
|
1285
1293
|
const indent = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1286
1294
|
const bodyCode = this.buildCondBody(body, uniqueName, indent, lowFile, highSyntax);
|
|
1287
|
-
const abap = `DATA ${uniqueName}
|
|
1295
|
+
const abap = `DATA ${uniqueName} ${type}.\n` + bodyCode;
|
|
1288
1296
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
|
|
1289
1297
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);
|
|
1290
1298
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -19,6 +19,7 @@ class NoAliases extends _abap_rule_1.ABAPRule {
|
|
|
19
19
|
key: "no_aliases",
|
|
20
20
|
title: "No ALIASES",
|
|
21
21
|
shortDescription: `Detects use of the ALIAS statement`,
|
|
22
|
+
extendedInformation: `Only one issue is reported for chained statements`,
|
|
22
23
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
23
24
|
};
|
|
24
25
|
}
|
|
@@ -31,9 +32,14 @@ class NoAliases extends _abap_rule_1.ABAPRule {
|
|
|
31
32
|
runParsed(file) {
|
|
32
33
|
const issues = [];
|
|
33
34
|
const message = "Do not use ALIASES";
|
|
35
|
+
let prev = undefined;
|
|
34
36
|
for (const stat of file.getStatements()) {
|
|
35
37
|
if (stat.get() instanceof Statements.Aliases) {
|
|
38
|
+
if (prev && prev.getColon() === stat.getColon()) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
36
41
|
issues.push(issue_1.Issue.atStatement(file, stat, message, this.getMetadata().key, this.conf.severity));
|
|
42
|
+
prev = stat;
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
return issues;
|
|
@@ -33,7 +33,6 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
|
|
|
33
33
|
this.conf = conf;
|
|
34
34
|
}
|
|
35
35
|
runParsed(file) {
|
|
36
|
-
var _a;
|
|
37
36
|
const issues = [];
|
|
38
37
|
const statements = file.getStatements();
|
|
39
38
|
for (let i = 0; i < statements.length; i++) {
|
|
@@ -41,15 +40,20 @@ class UnnecessaryChaining extends _abap_rule_1.ABAPRule {
|
|
|
41
40
|
if (colon === undefined) {
|
|
42
41
|
continue;
|
|
43
42
|
}
|
|
44
|
-
// find the next non Comment statement
|
|
45
43
|
let j = 1;
|
|
46
44
|
let nextStatement = statements[i + j];
|
|
47
45
|
while ((nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.get()) instanceof _statement_1.Comment) {
|
|
48
46
|
j++;
|
|
49
47
|
nextStatement = statements[i + j];
|
|
50
48
|
}
|
|
49
|
+
j = 1;
|
|
50
|
+
let prevStatement = statements[i - j];
|
|
51
|
+
while ((prevStatement === null || prevStatement === void 0 ? void 0 : prevStatement.get()) instanceof _statement_1.Comment) {
|
|
52
|
+
j--;
|
|
53
|
+
prevStatement = statements[i - j];
|
|
54
|
+
}
|
|
51
55
|
const next = nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.getColon();
|
|
52
|
-
const prev =
|
|
56
|
+
const prev = prevStatement === null || prevStatement === void 0 ? void 0 : prevStatement.getColon();
|
|
53
57
|
if (next !== undefined && colon.getStart().equals(next.getStart())) {
|
|
54
58
|
continue;
|
|
55
59
|
}
|
|
@@ -36,25 +36,6 @@ class WorkArea {
|
|
|
36
36
|
return this.workarea.length;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
/*
|
|
40
|
-
function removeDuplicates(list: readonly TypedIdentifier[]): readonly TypedIdentifier[] {
|
|
41
|
-
const deduplicated: TypedIdentifier[] = [];
|
|
42
|
-
for (const result of list) {
|
|
43
|
-
let cont = false;
|
|
44
|
-
for (const d of deduplicated) {
|
|
45
|
-
if (result.getStart().equals(d.getStart())) {
|
|
46
|
-
cont = true;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (cont === true) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
deduplicated.push(result);
|
|
54
|
-
}
|
|
55
|
-
return deduplicated;
|
|
56
|
-
}
|
|
57
|
-
*/
|
|
58
39
|
class UnusedTypesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
59
40
|
constructor() {
|
|
60
41
|
super(...arguments);
|
|
@@ -149,7 +130,6 @@ class UnusedTypes {
|
|
|
149
130
|
}
|
|
150
131
|
}
|
|
151
132
|
checkNode(node, obj, add) {
|
|
152
|
-
var _a;
|
|
153
133
|
const ret = [];
|
|
154
134
|
if (add === true) {
|
|
155
135
|
const types = node.getData().types;
|
|
@@ -158,7 +138,8 @@ class UnusedTypes {
|
|
|
158
138
|
if (obj.containsFile(identifier.getFilename()) === false) {
|
|
159
139
|
continue;
|
|
160
140
|
}
|
|
161
|
-
else if (
|
|
141
|
+
else if (this.conf.skipNames
|
|
142
|
+
&& this.conf.skipNames.length > 0
|
|
162
143
|
&& this.conf.skipNames.some((a) => a.toUpperCase() === name)) {
|
|
163
144
|
continue;
|
|
164
145
|
}
|
|
@@ -138,7 +138,6 @@ Unused variables are not reported if the object contains syntax errors. Errors f
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
buildWorkarea(node, obj) {
|
|
141
|
-
var _a;
|
|
142
141
|
const stype = node.getIdentifier().stype;
|
|
143
142
|
if (stype === _scope_type_1.ScopeType.OpenSQL) {
|
|
144
143
|
return;
|
|
@@ -150,7 +149,8 @@ Unused variables are not reported if the object contains syntax errors. Errors f
|
|
|
150
149
|
const vars = node.getData().vars;
|
|
151
150
|
for (const name in vars) {
|
|
152
151
|
const meta = vars[name].getMeta();
|
|
153
|
-
if (
|
|
152
|
+
if (this.conf.skipNames
|
|
153
|
+
&& this.conf.skipNames.length > 0
|
|
154
154
|
&& this.conf.skipNames.some((a) => a.toUpperCase() === name)) {
|
|
155
155
|
continue;
|
|
156
156
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.86.
|
|
3
|
+
"version": "2.86.4",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://abaplint.org",
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@microsoft/api-extractor": "^7.
|
|
48
|
+
"@microsoft/api-extractor": "^7.20.0",
|
|
49
49
|
"@types/chai": "^4.3.0",
|
|
50
50
|
"@types/mocha": "^9.1.0",
|
|
51
51
|
"@types/node": "^17.0.23",
|