@abaplint/core 2.101.16 → 2.101.18
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 +1 -1
- package/build/src/abap/5_syntax/_current_scope.js +9 -2
- package/build/src/abap/5_syntax/_type_utils.js +12 -1
- package/build/src/abap/5_syntax/expressions/attribute_chain.js +3 -1
- package/build/src/abap/5_syntax/expressions/method_call_param.js +1 -1
- package/build/src/abap/5_syntax/expressions/source.js +24 -8
- package/build/src/abap/5_syntax/expressions/sql_compare.js +7 -1
- package/build/src/abap/5_syntax/statements/loop.js +13 -3
- package/build/src/registry.js +1 -1
- package/build/src/rules/align_parameters.js +1 -1
- package/build/src/rules/unnecessary_pragma.js +26 -2
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -1311,7 +1311,7 @@ export declare class CurrentScope {
|
|
|
1311
1311
|
addDeferred(token: Token | undefined): void;
|
|
1312
1312
|
addListPrefix(identifiers: readonly TypedIdentifier[], prefix: string): void;
|
|
1313
1313
|
addList(identifiers: readonly TypedIdentifier[]): void;
|
|
1314
|
-
addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | undefined, filename: string, extra?: IReferenceExtras): void;
|
|
1314
|
+
addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | ReferenceType[] | undefined, filename: string, extra?: IReferenceExtras): void;
|
|
1315
1315
|
addSQLConversion(fieldName: string, message: string, token: Token): void;
|
|
1316
1316
|
findFunctionModule(name: string | undefined): FunctionModuleDefinition | undefined;
|
|
1317
1317
|
findObjectDefinition(name: string | undefined): IClassDefinition | IInterfaceDefinition | undefined;
|
|
@@ -133,12 +133,19 @@ class CurrentScope {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
addReference(usage, referencing, type, filename, extra) {
|
|
136
|
-
var _a;
|
|
136
|
+
var _a, _b;
|
|
137
137
|
if (usage === undefined || type === undefined) {
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
const position = new _identifier_1.Identifier(usage, filename);
|
|
141
|
-
|
|
141
|
+
if (Array.isArray(type)) {
|
|
142
|
+
for (const t of type) {
|
|
143
|
+
(_a = this.current) === null || _a === void 0 ? void 0 : _a.getData().references.push({ position, resolved: referencing, referenceType: t, extra });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
(_b = this.current) === null || _b === void 0 ? void 0 : _b.getData().references.push({ position, resolved: referencing, referenceType: type, extra });
|
|
148
|
+
}
|
|
142
149
|
}
|
|
143
150
|
addSQLConversion(fieldName, message, token) {
|
|
144
151
|
var _a;
|
|
@@ -209,12 +209,15 @@ class TypeUtils {
|
|
|
209
209
|
}
|
|
210
210
|
return false;
|
|
211
211
|
}
|
|
212
|
-
isAssignableStrict(source, target) {
|
|
212
|
+
isAssignableStrict(source, target, containsMethodCall = false) {
|
|
213
213
|
var _a, _b, _c, _d, _e, _f;
|
|
214
214
|
/*
|
|
215
215
|
console.dir(source);
|
|
216
216
|
console.dir(target);
|
|
217
217
|
*/
|
|
218
|
+
if (containsMethodCall) {
|
|
219
|
+
return this.isAssignable(source, target);
|
|
220
|
+
}
|
|
218
221
|
if (source instanceof basic_1.CharacterType) {
|
|
219
222
|
if (target instanceof basic_1.CharacterType) {
|
|
220
223
|
if (((_a = source.getAbstractTypeData()) === null || _a === void 0 ? void 0 : _a.derivedFromConstant) === true) {
|
|
@@ -253,6 +256,9 @@ class TypeUtils {
|
|
|
253
256
|
if (target instanceof basic_1.StructureType && this.structureContainsString(target)) {
|
|
254
257
|
return false;
|
|
255
258
|
}
|
|
259
|
+
else if (target instanceof basic_1.IntegerType) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
256
262
|
else if (target instanceof basic_1.XSequenceType || target instanceof basic_1.XStringType) {
|
|
257
263
|
if (((_f = source.getAbstractTypeData()) === null || _f === void 0 ? void 0 : _f.derivedFromConstant) === true) {
|
|
258
264
|
return true;
|
|
@@ -279,6 +285,11 @@ class TypeUtils {
|
|
|
279
285
|
return false;
|
|
280
286
|
}
|
|
281
287
|
}
|
|
288
|
+
else if (source instanceof basic_1.FloatType) {
|
|
289
|
+
if (target instanceof basic_1.IntegerType) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
282
293
|
else if (source instanceof basic_1.XStringType) {
|
|
283
294
|
if (target instanceof basic_1.CLikeType) {
|
|
284
295
|
return false;
|
|
@@ -32,7 +32,9 @@ class AttributeChain {
|
|
|
32
32
|
if (context === undefined) {
|
|
33
33
|
throw new Error("Attribute or constant \"" + name + "\" not found in \"" + def.getName() + "\"");
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
for (const t of type) {
|
|
36
|
+
scope.addReference(nameToken, context, t, filename);
|
|
37
|
+
}
|
|
36
38
|
// todo, loop, handle ArrowOrDash, ComponentName, TableExpression
|
|
37
39
|
return context.getType();
|
|
38
40
|
}
|
|
@@ -55,7 +55,7 @@ class MethodCallParam {
|
|
|
55
55
|
if (sourceType === undefined) {
|
|
56
56
|
throw new Error("No source type determined, method source");
|
|
57
57
|
}
|
|
58
|
-
else if (new _type_utils_1.TypeUtils(scope).isAssignableStrict(sourceType, targetType) === false) {
|
|
58
|
+
else if (new _type_utils_1.TypeUtils(scope).isAssignableStrict(sourceType, targetType, child.findFirstExpression(Expressions.MethodCallChain) !== undefined) === false) {
|
|
59
59
|
throw new Error("Method parameter type not compatible");
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -34,7 +34,7 @@ const _typed_identifier_1 = require("../../types/_typed_identifier");
|
|
|
34
34
|
* DATA(bar) = VALUE #( ... ). give error, no type can be derived
|
|
35
35
|
*/
|
|
36
36
|
class Source {
|
|
37
|
-
runSyntax(node, scope, filename, targetType) {
|
|
37
|
+
runSyntax(node, scope, filename, targetType, writeReference = false) {
|
|
38
38
|
if (node === undefined) {
|
|
39
39
|
return undefined;
|
|
40
40
|
}
|
|
@@ -161,33 +161,41 @@ class Source {
|
|
|
161
161
|
return undefined;
|
|
162
162
|
}
|
|
163
163
|
let context = new unknown_type_1.UnknownType("todo, Source type");
|
|
164
|
+
const type = [_reference_1.ReferenceType.DataReadReference];
|
|
165
|
+
if (writeReference) {
|
|
166
|
+
type.push(_reference_1.ReferenceType.DataWriteReference);
|
|
167
|
+
}
|
|
164
168
|
while (children.length >= 0) {
|
|
165
169
|
if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.MethodCallChain) {
|
|
166
170
|
context = new method_call_chain_1.MethodCallChain().runSyntax(first, scope, filename, targetType);
|
|
167
171
|
}
|
|
168
172
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.FieldChain) {
|
|
169
|
-
context = new field_chain_1.FieldChain().runSyntax(first, scope, filename,
|
|
173
|
+
context = new field_chain_1.FieldChain().runSyntax(first, scope, filename, type);
|
|
170
174
|
}
|
|
171
175
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.StringTemplate) {
|
|
172
176
|
context = new string_template_1.StringTemplate().runSyntax(first, scope, filename);
|
|
173
177
|
}
|
|
174
178
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.Source) {
|
|
175
|
-
|
|
179
|
+
const found = new Source().runSyntax(first, scope, filename);
|
|
180
|
+
context = this.infer(context, found);
|
|
176
181
|
}
|
|
177
182
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.Constant) {
|
|
178
|
-
|
|
183
|
+
const found = new constant_1.Constant().runSyntax(first);
|
|
184
|
+
context = this.infer(context, found);
|
|
179
185
|
}
|
|
180
186
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.Dereference) {
|
|
181
187
|
context = new dereference_1.Dereference().runSyntax(context);
|
|
182
188
|
}
|
|
183
|
-
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.ArrowOrDash) {
|
|
184
|
-
// console.dir("dash");
|
|
185
|
-
}
|
|
186
189
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.ComponentChain) {
|
|
187
190
|
context = new component_chain_1.ComponentChain().runSyntax(context, first, scope, filename);
|
|
188
191
|
}
|
|
192
|
+
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.ArithOperator) {
|
|
193
|
+
if (first.concatTokens() === "**") {
|
|
194
|
+
context = new basic_1.FloatType();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
189
197
|
else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.AttributeChain) {
|
|
190
|
-
context = new attribute_chain_1.AttributeChain().runSyntax(context, first, scope, filename,
|
|
198
|
+
context = new attribute_chain_1.AttributeChain().runSyntax(context, first, scope, filename, type);
|
|
191
199
|
}
|
|
192
200
|
first = children.shift();
|
|
193
201
|
if (first === undefined) {
|
|
@@ -200,6 +208,14 @@ class Source {
|
|
|
200
208
|
return context;
|
|
201
209
|
}
|
|
202
210
|
////////////////////////////////
|
|
211
|
+
infer(context, found) {
|
|
212
|
+
if (context instanceof basic_1.FloatType && found instanceof basic_1.IntegerType) {
|
|
213
|
+
return context;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
return found;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
203
219
|
addIfInferred(node, scope, filename, inferredType) {
|
|
204
220
|
const basic = new basic_types_1.BasicTypes(filename, scope);
|
|
205
221
|
const typeExpression = node.findFirstExpression(Expressions.TypeNameOrInfer);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SQLCompare = void 0;
|
|
4
4
|
const Expressions = require("../../2_statements/expressions");
|
|
5
|
+
const nodes_1 = require("../../nodes");
|
|
5
6
|
const basic_1 = require("../../types/basic");
|
|
6
7
|
const sql_source_1 = require("./sql_source");
|
|
7
8
|
class SQLCompare {
|
|
@@ -10,7 +11,12 @@ class SQLCompare {
|
|
|
10
11
|
let sourceType;
|
|
11
12
|
let token;
|
|
12
13
|
for (const s of node.findAllExpressions(Expressions.SQLSource)) {
|
|
13
|
-
|
|
14
|
+
for (const child of s.getChildren()) {
|
|
15
|
+
if (child instanceof nodes_1.ExpressionNode) {
|
|
16
|
+
token = child.getFirstToken();
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
14
20
|
sourceType = new sql_source_1.SQLSource().runSyntax(s, scope, filename);
|
|
15
21
|
}
|
|
16
22
|
const fieldName = (_a = node.findDirectExpression(Expressions.SQLFieldName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
@@ -13,19 +13,19 @@ const dynamic_1 = require("../expressions/dynamic");
|
|
|
13
13
|
const loop_group_by_1 = require("../expressions/loop_group_by");
|
|
14
14
|
class Loop {
|
|
15
15
|
runSyntax(node, scope, filename) {
|
|
16
|
-
var _a;
|
|
17
16
|
const loopTarget = node.findDirectExpression(Expressions.LoopTarget);
|
|
18
17
|
let target = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectExpression(Expressions.Target);
|
|
19
18
|
const targetType = target ? new target_1.Target().runSyntax(target, scope, filename) : undefined;
|
|
20
19
|
if (target === undefined) {
|
|
21
20
|
target = node.findDirectExpression(Expressions.FSTarget);
|
|
22
21
|
}
|
|
22
|
+
const write = (loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectTokenByText("ASSIGNING")) !== undefined;
|
|
23
23
|
const sources = node.findDirectExpressions(Expressions.Source);
|
|
24
24
|
let firstSource = node.findDirectExpression(Expressions.SimpleSource2);
|
|
25
25
|
if (firstSource === undefined) {
|
|
26
26
|
firstSource = sources[0];
|
|
27
27
|
}
|
|
28
|
-
let sourceType = firstSource ? new source_1.Source().runSyntax(firstSource, scope, filename, targetType) : undefined;
|
|
28
|
+
let sourceType = firstSource ? new source_1.Source().runSyntax(firstSource, scope, filename, targetType, write) : undefined;
|
|
29
29
|
let rowType = undefined;
|
|
30
30
|
const concat = node.concatTokens().toUpperCase();
|
|
31
31
|
if (sourceType === undefined) {
|
|
@@ -46,14 +46,24 @@ class Loop {
|
|
|
46
46
|
&& concat.startsWith("LOOP AT GROUP ") === false) {
|
|
47
47
|
throw new Error("Loop, not a table type");
|
|
48
48
|
}
|
|
49
|
+
else if (loopTarget === undefined
|
|
50
|
+
&& sourceType instanceof basic_1.TableType
|
|
51
|
+
&& sourceType.isWithHeader() === false) {
|
|
52
|
+
throw new Error("Loop, no header");
|
|
53
|
+
}
|
|
54
|
+
const targetConcat = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.concatTokens().toUpperCase();
|
|
49
55
|
if (sourceType instanceof basic_1.TableType) {
|
|
50
|
-
const targetConcat = (_a = node.findDirectExpression(Expressions.LoopTarget)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
|
|
51
56
|
rowType = sourceType.getRowType();
|
|
52
57
|
sourceType = rowType;
|
|
53
58
|
if (targetConcat === null || targetConcat === void 0 ? void 0 : targetConcat.startsWith("REFERENCE INTO ")) {
|
|
54
59
|
sourceType = new basic_1.DataReference(sourceType);
|
|
55
60
|
}
|
|
56
61
|
}
|
|
62
|
+
if (targetConcat
|
|
63
|
+
&& targetConcat.startsWith("TRANSPORTING ")
|
|
64
|
+
&& node.findDirectTokenByText("WHERE") === undefined) {
|
|
65
|
+
throw new Error("Loop, TRANSPORTING NO FIELDS only with WHERE");
|
|
66
|
+
}
|
|
57
67
|
const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
|
|
58
68
|
if (inline) {
|
|
59
69
|
new inline_data_1.InlineData().runSyntax(inline, scope, filename, sourceType);
|
package/build/src/registry.js
CHANGED
|
@@ -37,7 +37,7 @@ Does not take effect on non functional method calls, use https://rules.abaplint.
|
|
|
37
37
|
|
|
38
38
|
If parameters are on the same row, no issues are reported, see
|
|
39
39
|
https://rules.abaplint.org/max_one_method_parameter_per_line/ for splitting parameters to lines`,
|
|
40
|
-
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide],
|
|
40
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix],
|
|
41
41
|
badExample: `CALL FUNCTION 'FOOBAR'
|
|
42
42
|
EXPORTING
|
|
43
43
|
foo = 2
|
|
@@ -9,6 +9,12 @@ const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
|
9
9
|
const _statement_1 = require("../abap/2_statements/statements/_statement");
|
|
10
10
|
const _irule_1 = require("./_irule");
|
|
11
11
|
class UnnecessaryPragmaConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
/** Allow NO_TEXT in global CLAS and INTF definitions,
|
|
15
|
+
its added automatically by SE24 in some cases where it should not */
|
|
16
|
+
this.allowNoTextGlobal = false;
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
19
|
exports.UnnecessaryPragmaConf = UnnecessaryPragmaConf;
|
|
14
20
|
class UnnecessaryPragma extends _abap_rule_1.ABAPRule {
|
|
@@ -58,6 +64,7 @@ ENDIF.`,
|
|
|
58
64
|
runParsed(file) {
|
|
59
65
|
const issues = [];
|
|
60
66
|
let noHandler = false;
|
|
67
|
+
let globalDefinition = false;
|
|
61
68
|
const statements = file.getStatements();
|
|
62
69
|
for (let i = 0; i < statements.length; i++) {
|
|
63
70
|
const statement = statements[i];
|
|
@@ -65,6 +72,16 @@ ENDIF.`,
|
|
|
65
72
|
if (statement.get() instanceof Statements.EndTry) {
|
|
66
73
|
noHandler = false;
|
|
67
74
|
}
|
|
75
|
+
else if (statement.get() instanceof Statements.ClassDefinition
|
|
76
|
+
|| statement.get() instanceof Statements.Interface) {
|
|
77
|
+
if (statement.findDirectExpression(Expressions.ClassGlobal)) {
|
|
78
|
+
globalDefinition = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (statement.get() instanceof Statements.EndClass
|
|
82
|
+
|| statement.get() instanceof Statements.EndInterface) {
|
|
83
|
+
globalDefinition = false;
|
|
84
|
+
}
|
|
68
85
|
else if (statement.get() instanceof _statement_1.Comment) {
|
|
69
86
|
continue;
|
|
70
87
|
}
|
|
@@ -77,9 +94,16 @@ ENDIF.`,
|
|
|
77
94
|
else {
|
|
78
95
|
noHandler = this.containsNoHandler(statement, statements[i + 1]);
|
|
79
96
|
}
|
|
80
|
-
|
|
97
|
+
if (this.getConfig().allowNoTextGlobal === true && globalDefinition === true) {
|
|
98
|
+
// skip
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
issues.push(...this.checkText(statement, file));
|
|
102
|
+
}
|
|
81
103
|
issues.push(...this.checkNeeded(statement, file));
|
|
82
|
-
|
|
104
|
+
if (globalDefinition === false) {
|
|
105
|
+
issues.push(...this.checkSubrc(statement, nextStatement, file));
|
|
106
|
+
}
|
|
83
107
|
}
|
|
84
108
|
return issues;
|
|
85
109
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.101.
|
|
3
|
+
"version": "2.101.18",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@microsoft/api-extractor": "^7.35.2",
|
|
54
54
|
"@types/chai": "^4.3.5",
|
|
55
55
|
"@types/mocha": "^10.0.1",
|
|
56
|
-
"@types/node": "^20.
|
|
56
|
+
"@types/node": "^20.3.0",
|
|
57
57
|
"chai": "^4.3.7",
|
|
58
58
|
"eslint": "^8.42.0",
|
|
59
59
|
"mocha": "^10.2.0",
|