@abaplint/core 2.94.5 → 2.94.7
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/abaplint.d.ts +4 -2
- package/build/src/abap/5_syntax/_builtin.js +2 -1
- package/build/src/abap/5_syntax/spaghetti_scope.js +9 -0
- package/build/src/abap/5_syntax/statements/modify_database.js +11 -6
- package/build/src/objects/table.js +1 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/change_if_to_case.js +6 -1
- package/build/src/rules/modify_only_own_db_tables.js +47 -28
- package/build/src/rules/omit_parameter_name.js +11 -5
- package/build/src/rules/static_call_via_instance.js +8 -0
- package/package.json +4 -4
package/build/abaplint.d.ts
CHANGED
|
@@ -3502,6 +3502,7 @@ export declare interface ISpaghettiScopeNode {
|
|
|
3502
3502
|
findScopeForVariable(name: string): IScopeIdentifier | undefined;
|
|
3503
3503
|
findWriteReference(pos: Position): TypedIdentifier | undefined;
|
|
3504
3504
|
findTableReference(pos: Position): string | undefined;
|
|
3505
|
+
findTableVoidReference(pos: Position): boolean;
|
|
3505
3506
|
}
|
|
3506
3507
|
|
|
3507
3508
|
export declare class Issue {
|
|
@@ -3563,11 +3564,11 @@ declare interface ISyntaxSettings {
|
|
|
3563
3564
|
version?: Version;
|
|
3564
3565
|
/** Report error for objects in this regex namespace. Types not in namespace will be void. Case insensitive */
|
|
3565
3566
|
errorNamespace: string;
|
|
3566
|
-
/** List of full named global constants
|
|
3567
|
+
/** List of full named global constants (regex not possible)
|
|
3567
3568
|
* @uniqueItems true
|
|
3568
3569
|
*/
|
|
3569
3570
|
globalConstants?: string[];
|
|
3570
|
-
/** List of full named global macros
|
|
3571
|
+
/** List of full named global macros (regex not possible)
|
|
3571
3572
|
* @uniqueItems true
|
|
3572
3573
|
*/
|
|
3573
3574
|
globalMacros?: string[];
|
|
@@ -5101,6 +5102,7 @@ export declare class SpaghettiScopeNode extends ScopeData implements ISpaghettiS
|
|
|
5101
5102
|
findVariable(name: string): TypedIdentifier | undefined;
|
|
5102
5103
|
findWriteReference(pos: Position): TypedIdentifier | undefined;
|
|
5103
5104
|
findTableReference(pos: Position): string | undefined;
|
|
5105
|
+
findTableVoidReference(pos: Position): boolean;
|
|
5104
5106
|
findScopeForVariable(name: string): IScopeIdentifier | undefined;
|
|
5105
5107
|
}
|
|
5106
5108
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BuiltIn = void 0;
|
|
3
|
+
exports.BuiltIn = exports.BuiltInMethod = void 0;
|
|
4
4
|
/* eslint-disable max-len */
|
|
5
5
|
const _typed_identifier_1 = require("../types/_typed_identifier");
|
|
6
6
|
const basic_1 = require("../types/basic");
|
|
@@ -84,6 +84,7 @@ class BuiltInMethod extends _identifier_1.Identifier {
|
|
|
84
84
|
return undefined;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
exports.BuiltInMethod = BuiltInMethod;
|
|
87
88
|
class BuiltIn {
|
|
88
89
|
constructor() {
|
|
89
90
|
this.row = 1;
|
|
@@ -171,6 +171,15 @@ class SpaghettiScopeNode extends ScopeData {
|
|
|
171
171
|
}
|
|
172
172
|
return undefined;
|
|
173
173
|
}
|
|
174
|
+
findTableVoidReference(pos) {
|
|
175
|
+
for (const r of this.getData().references) {
|
|
176
|
+
if (r.referenceType === _reference_1.ReferenceType.TableVoidReference
|
|
177
|
+
&& r.position.getStart().equals(pos)) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
174
183
|
// TODO, this method can be deleted? its only used in tests?
|
|
175
184
|
findScopeForVariable(name) {
|
|
176
185
|
let search = this;
|
|
@@ -5,6 +5,7 @@ const Expressions = require("../../2_statements/expressions");
|
|
|
5
5
|
const dynamic_1 = require("../expressions/dynamic");
|
|
6
6
|
const database_table_1 = require("../expressions/database_table");
|
|
7
7
|
const source_1 = require("../expressions/source");
|
|
8
|
+
const _reference_1 = require("../_reference");
|
|
8
9
|
class ModifyDatabase {
|
|
9
10
|
runSyntax(node, scope, filename) {
|
|
10
11
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
@@ -12,14 +13,18 @@ class ModifyDatabase {
|
|
|
12
13
|
}
|
|
13
14
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
14
15
|
if (dbtab !== undefined) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
if (node.getChildren().length === 5) {
|
|
17
|
+
const found = scope.findVariable(dbtab.concatTokens());
|
|
18
|
+
if (found) {
|
|
19
|
+
scope.addReference(dbtab.getFirstToken(), found, _reference_1.ReferenceType.DataWriteReference, filename);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
else {
|
|
26
|
+
new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
25
30
|
new source_1.Source().runSyntax(s, scope, filename);
|
|
@@ -121,7 +121,7 @@ class Table extends _abstract_object_1.AbstractObject {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
else if (comptype === "S" && field.FIELDNAME.startsWith(".INCLU-")) {
|
|
124
|
-
const lookup = ddic.lookupTableOrView(field.
|
|
124
|
+
const lookup = ddic.lookupTableOrView(field.PRECFIELD);
|
|
125
125
|
if (lookup.object) {
|
|
126
126
|
references.push({ object: lookup.object });
|
|
127
127
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -29,7 +29,9 @@ class ChangeIfToCase extends _abap_rule_1.ABAPRule {
|
|
|
29
29
|
title: "Change IF to CASE",
|
|
30
30
|
shortDescription: `Finds IF constructs that can be changed to CASE`,
|
|
31
31
|
// eslint-disable-next-line max-len
|
|
32
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions
|
|
32
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions
|
|
33
|
+
|
|
34
|
+
If the first comparison is a boolean compare, no issue is reported.`,
|
|
33
35
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
|
|
34
36
|
badExample: `IF l_fcat-fieldname EQ 'FOO'.
|
|
35
37
|
ELSEIF l_fcat-fieldname = 'BAR'
|
|
@@ -60,6 +62,9 @@ ENDCASE.`,
|
|
|
60
62
|
if (ifStatement === undefined) {
|
|
61
63
|
continue;
|
|
62
64
|
}
|
|
65
|
+
if (ifStatement.concatTokens().match(/ (abap_true|abap_false)\s*\./i)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
63
68
|
conds.push(ifStatement === null || ifStatement === void 0 ? void 0 : ifStatement.findDirectExpression(Expressions.Cond));
|
|
64
69
|
for (const ei of i.findDirectStructures(Structures.ElseIf)) {
|
|
65
70
|
conds.push((_a = ei.findDirectStatement(Statements.ElseIf)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Cond));
|
|
@@ -4,9 +4,10 @@ exports.ModifyOnlyOwnDBTables = exports.ModifyOnlyOwnDBTablesConf = void 0;
|
|
|
4
4
|
const Statements = require("../abap/2_statements/statements");
|
|
5
5
|
const Expressions = require("../abap/2_statements/expressions");
|
|
6
6
|
const issue_1 = require("../issue");
|
|
7
|
-
const _abap_rule_1 = require("./_abap_rule");
|
|
8
7
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
9
8
|
const _irule_1 = require("./_irule");
|
|
9
|
+
const _abap_object_1 = require("../objects/_abap_object");
|
|
10
|
+
const syntax_1 = require("../abap/5_syntax/syntax");
|
|
10
11
|
class ModifyOnlyOwnDBTablesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
@@ -16,9 +17,8 @@ class ModifyOnlyOwnDBTablesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
exports.ModifyOnlyOwnDBTablesConf = ModifyOnlyOwnDBTablesConf;
|
|
19
|
-
class ModifyOnlyOwnDBTables
|
|
20
|
+
class ModifyOnlyOwnDBTables {
|
|
20
21
|
constructor() {
|
|
21
|
-
super(...arguments);
|
|
22
22
|
this.conf = new ModifyOnlyOwnDBTablesConf();
|
|
23
23
|
}
|
|
24
24
|
getMetadata() {
|
|
@@ -26,8 +26,8 @@ class ModifyOnlyOwnDBTables extends _abap_rule_1.ABAPRule {
|
|
|
26
26
|
key: "modify_only_own_db_tables",
|
|
27
27
|
title: "Modify only own DB tables",
|
|
28
28
|
shortDescription: `Modify only own DB tables`,
|
|
29
|
-
extendedInformation:
|
|
30
|
-
tags: [_irule_1.RuleTag.Security
|
|
29
|
+
extendedInformation: `https://docs.abapopenchecks.org/checks/26/`,
|
|
30
|
+
tags: [_irule_1.RuleTag.Security],
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
getConfig() {
|
|
@@ -36,33 +36,52 @@ class ModifyOnlyOwnDBTables extends _abap_rule_1.ABAPRule {
|
|
|
36
36
|
setConfig(conf) {
|
|
37
37
|
this.conf = conf;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
initialize(reg) {
|
|
40
|
+
this.reg = reg;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
run(obj) {
|
|
40
44
|
var _a;
|
|
41
|
-
|
|
42
|
-
const struc = file.getStructure();
|
|
43
|
-
if (struc === undefined) {
|
|
45
|
+
if (!(obj instanceof _abap_object_1.ABAPObject)) {
|
|
44
46
|
return [];
|
|
45
47
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
let spaghetti = undefined;
|
|
49
|
+
const output = [];
|
|
50
|
+
for (const file of obj.getABAPFiles()) {
|
|
51
|
+
const struc = file.getStructure();
|
|
52
|
+
if (struc === undefined) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const regExp = new RegExp(this.getConfig().ownTables, "i");
|
|
56
|
+
for (const s of file.getStatements()) {
|
|
57
|
+
const g = s.get();
|
|
58
|
+
if (g instanceof Statements.DeleteDatabase
|
|
59
|
+
|| g instanceof Statements.UpdateDatabase
|
|
60
|
+
|| g instanceof Statements.InsertDatabase
|
|
61
|
+
|| g instanceof Statements.ModifyDatabase) {
|
|
62
|
+
const databaseTable = s.findFirstExpression(Expressions.DatabaseTable);
|
|
63
|
+
if (databaseTable === undefined) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (((_a = databaseTable.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
|
|
67
|
+
if (this.getConfig().reportDynamic === true) {
|
|
68
|
+
output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const concat = databaseTable.concatTokens().toUpperCase();
|
|
73
|
+
if (regExp.test(concat) === false) {
|
|
74
|
+
// must contain a ReferenceType.TableVoidReference
|
|
75
|
+
if (spaghetti === undefined) {
|
|
76
|
+
spaghetti = new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti;
|
|
77
|
+
}
|
|
78
|
+
const start = databaseTable.getFirstToken().getStart();
|
|
79
|
+
const scope = spaghetti.lookupPosition(start, file.getFilename());
|
|
80
|
+
const found = scope === null || scope === void 0 ? void 0 : scope.findTableVoidReference(start);
|
|
81
|
+
if (found) {
|
|
82
|
+
output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
|
|
83
|
+
}
|
|
60
84
|
}
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
const concat = databaseTable.concatTokens().toUpperCase();
|
|
64
|
-
if (regExp.test(concat) === false && concat !== "SCREEN") {
|
|
65
|
-
output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
|
|
66
85
|
}
|
|
67
86
|
}
|
|
68
87
|
}
|
|
@@ -10,6 +10,7 @@ const syntax_1 = require("../abap/5_syntax/syntax");
|
|
|
10
10
|
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
11
11
|
const method_definition_1 = require("../abap/types/method_definition");
|
|
12
12
|
const edit_helper_1 = require("../edit_helper");
|
|
13
|
+
const _builtin_1 = require("../abap/5_syntax/_builtin");
|
|
13
14
|
class OmitParameterNameConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
14
15
|
}
|
|
15
16
|
exports.OmitParameterNameConf = OmitParameterNameConf;
|
|
@@ -74,7 +75,7 @@ EXPORTING must already be omitted for this rule to take effect, https://rules.ab
|
|
|
74
75
|
if (ref === undefined) {
|
|
75
76
|
continue;
|
|
76
77
|
}
|
|
77
|
-
const i = ref.
|
|
78
|
+
const i = ref.getDefaultImporting();
|
|
78
79
|
if (i === undefined) {
|
|
79
80
|
continue;
|
|
80
81
|
}
|
|
@@ -101,12 +102,17 @@ EXPORTING must already be omitted for this rule to take effect, https://rules.ab
|
|
|
101
102
|
return undefined;
|
|
102
103
|
}
|
|
103
104
|
for (const r of scope.getData().references) {
|
|
104
|
-
if (r.referenceType !== _reference_1.ReferenceType.MethodReference
|
|
105
|
+
if (r.referenceType !== _reference_1.ReferenceType.MethodReference
|
|
106
|
+
&& r.referenceType !== _reference_1.ReferenceType.BuiltinMethodReference) {
|
|
105
107
|
continue;
|
|
106
108
|
}
|
|
107
|
-
else if (r.position.getStart().equals(token.getStart())
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
else if (r.position.getStart().equals(token.getStart())) {
|
|
110
|
+
if (r.resolved instanceof _builtin_1.BuiltInMethod) {
|
|
111
|
+
return r.resolved;
|
|
112
|
+
}
|
|
113
|
+
else if (r.resolved instanceof method_definition_1.MethodDefinition) {
|
|
114
|
+
return r.resolved.getParameters();
|
|
115
|
+
}
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
return undefined;
|
|
@@ -10,6 +10,11 @@ const syntax_1 = require("../abap/5_syntax/syntax");
|
|
|
10
10
|
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
11
11
|
const types_1 = require("../abap/types");
|
|
12
12
|
class StaticCallViaInstanceConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
/** Allow in test class includes */
|
|
16
|
+
this.allowInTestclassIncludes = false;
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
exports.StaticCallViaInstanceConf = StaticCallViaInstanceConf;
|
|
15
20
|
class StaticCallViaInstance extends _abap_rule_1.ABAPRule {
|
|
@@ -34,6 +39,9 @@ class StaticCallViaInstance extends _abap_rule_1.ABAPRule {
|
|
|
34
39
|
}
|
|
35
40
|
runParsed(file, obj) {
|
|
36
41
|
const issues = [];
|
|
42
|
+
if (this.getConfig().allowInTestclassIncludes === true && file.getFilename().includes(".testclasses.")) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
37
45
|
const staticMethodCalls = this.listMethodCalls(file.getFilename(), new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
|
|
38
46
|
const tokens = file.getTokens();
|
|
39
47
|
for (let i = 0; i < tokens.length - 1; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.94.
|
|
3
|
+
"version": "2.94.7",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"@microsoft/api-extractor": "^7.33.7",
|
|
50
50
|
"@types/chai": "^4.3.4",
|
|
51
51
|
"@types/mocha": "^10.0.1",
|
|
52
|
-
"@types/node": "^18.11.
|
|
52
|
+
"@types/node": "^18.11.17",
|
|
53
53
|
"chai": "^4.3.7",
|
|
54
|
-
"eslint": "^8.
|
|
54
|
+
"eslint": "^8.30.0",
|
|
55
55
|
"mocha": "^10.2.0",
|
|
56
56
|
"c8": "^7.12.0",
|
|
57
57
|
"source-map-support": "^0.5.21",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"fast-xml-parser": "^4.0.12",
|
|
63
|
-
"json5": "^2.2.
|
|
63
|
+
"json5": "^2.2.2",
|
|
64
64
|
"vscode-languageserver-types": "^3.17.2"
|
|
65
65
|
}
|
|
66
66
|
}
|