@abaplint/core 2.89.4 → 2.89.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 +1 -1
- package/build/src/abap/2_statements/statements/message.js +1 -1
- package/build/src/abap/5_syntax/_current_scope.js +2 -2
- package/build/src/abap/5_syntax/basic_types.js +8 -2
- package/build/src/abap/5_syntax/expressions/component_compare_simple.js +17 -5
- package/build/src/abap/5_syntax/expressions/source.js +5 -1
- package/build/src/abap/5_syntax/expressions/value_body.js +3 -0
- package/build/src/ddic.js +6 -6
- package/build/src/registry.js +1 -1
- package/build/src/rules/definitions_top.js +8 -4
- package/build/src/rules/downport.js +32 -0
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -1144,7 +1144,7 @@ export declare class CurrentScope {
|
|
|
1144
1144
|
/** Lookup class in local and global scope */
|
|
1145
1145
|
findClassDefinition(name: string | undefined): IClassDefinition | undefined;
|
|
1146
1146
|
findTypePoolConstant(name: string | undefined): TypedIdentifier | undefined;
|
|
1147
|
-
findTypePoolType(name: string):
|
|
1147
|
+
findTypePoolType(name: string): TypedIdentifier | undefined;
|
|
1148
1148
|
/** Lookup interface in local and global scope */
|
|
1149
1149
|
findInterfaceDefinition(name: string): IInterfaceDefinition | undefined;
|
|
1150
1150
|
findFormDefinition(name: string): IFormDefinition | undefined;
|
|
@@ -12,7 +12,7 @@ class Message {
|
|
|
12
12
|
const raising = (0, combi_1.seq)("RAISING", expressions_1.ExceptionName);
|
|
13
13
|
const options = (0, combi_1.per)(like, into, raising);
|
|
14
14
|
const type = (0, combi_1.seq)("TYPE", expressions_1.Source);
|
|
15
|
-
const sou = (0, combi_1.altPrio)(options,
|
|
15
|
+
const sou = (0, combi_1.altPrio)(options, s);
|
|
16
16
|
const sourc = (0, combi_1.alt)(sou, (0, combi_1.seq)(s, sou), (0, combi_1.seq)(s, s, sou), (0, combi_1.seq)(s, s, s, options));
|
|
17
17
|
const mwith = (0, combi_1.seq)("WITH", s, (0, combi_1.opt)(sourc));
|
|
18
18
|
const foo = (0, combi_1.seq)(expressions_1.MessageSource, (0, combi_1.opt)(options), (0, combi_1.opt)(mwith));
|
|
@@ -220,7 +220,7 @@ class CurrentScope {
|
|
|
220
220
|
return found;
|
|
221
221
|
}
|
|
222
222
|
findTypePoolType(name) {
|
|
223
|
-
var _a
|
|
223
|
+
var _a;
|
|
224
224
|
if (name.includes("_") === undefined) {
|
|
225
225
|
return undefined;
|
|
226
226
|
}
|
|
@@ -230,7 +230,7 @@ class CurrentScope {
|
|
|
230
230
|
return undefined;
|
|
231
231
|
}
|
|
232
232
|
const spag = (_a = new syntax_1.SyntaxLogic(this.reg, typePool).run().spaghetti.getFirstChild()) === null || _a === void 0 ? void 0 : _a.getFirstChild();
|
|
233
|
-
const found =
|
|
233
|
+
const found = spag === null || spag === void 0 ? void 0 : spag.findType(name);
|
|
234
234
|
return found;
|
|
235
235
|
}
|
|
236
236
|
/** Lookup interface in local and global scope */
|
|
@@ -52,6 +52,10 @@ class BasicTypes {
|
|
|
52
52
|
if (builtin) {
|
|
53
53
|
return new _typed_identifier_1.TypedIdentifier(new identifier_1.Identifier(new position_1.Position(1, 1), name), _builtin_1.BuiltIn.filename, builtin);
|
|
54
54
|
}
|
|
55
|
+
const type = this.scope.findTypePoolType(name);
|
|
56
|
+
if (type) {
|
|
57
|
+
return type;
|
|
58
|
+
}
|
|
55
59
|
return undefined;
|
|
56
60
|
}
|
|
57
61
|
resolveLikeName(node, headerLogic = true) {
|
|
@@ -145,6 +149,7 @@ class BasicTypes {
|
|
|
145
149
|
return type;
|
|
146
150
|
}
|
|
147
151
|
resolveTypeName(typeName, length, decimals, name) {
|
|
152
|
+
var _a;
|
|
148
153
|
if (typeName === undefined) {
|
|
149
154
|
return undefined;
|
|
150
155
|
}
|
|
@@ -170,7 +175,7 @@ class BasicTypes {
|
|
|
170
175
|
this.scope.addReference(token, typ, _reference_1.ReferenceType.TypeReference, this.filename);
|
|
171
176
|
return typ.getType();
|
|
172
177
|
}
|
|
173
|
-
const type = this.scope.findTypePoolType(chainText);
|
|
178
|
+
const type = (_a = this.scope.findTypePoolType(chainText)) === null || _a === void 0 ? void 0 : _a.getType();
|
|
174
179
|
if (type) {
|
|
175
180
|
// this.scope.addReference(typeName.getFirstToken(), type, ReferenceType.TypeReference, this.filename);
|
|
176
181
|
return type;
|
|
@@ -445,6 +450,7 @@ class BasicTypes {
|
|
|
445
450
|
/////////////////////
|
|
446
451
|
// todo, rewrite this method
|
|
447
452
|
resolveTypeChain(expr) {
|
|
453
|
+
var _a;
|
|
448
454
|
const chainText = expr.concatTokens().toUpperCase();
|
|
449
455
|
if (chainText.includes("=>") === false && chainText.includes("-") === false) {
|
|
450
456
|
return undefined;
|
|
@@ -496,7 +502,7 @@ class BasicTypes {
|
|
|
496
502
|
const found = this.scope.findType(subs[0]);
|
|
497
503
|
foundType = found === null || found === void 0 ? void 0 : found.getType();
|
|
498
504
|
if (foundType === undefined) {
|
|
499
|
-
const typePoolType = this.scope.findTypePoolType(subs[0]);
|
|
505
|
+
const typePoolType = (_a = this.scope.findTypePoolType(subs[0])) === null || _a === void 0 ? void 0 : _a.getType();
|
|
500
506
|
if (typePoolType) {
|
|
501
507
|
// this.scope.addReference(typeName.getFirstToken(), typePoolType, ReferenceType.TypeReference, this.filename);
|
|
502
508
|
foundType = typePoolType;
|
|
@@ -2,15 +2,27 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ComponentCompareSimple = void 0;
|
|
4
4
|
const Expressions = require("../../2_statements/expressions");
|
|
5
|
+
const nodes_1 = require("../../nodes");
|
|
5
6
|
const component_chain_1 = require("./component_chain");
|
|
6
7
|
const source_1 = require("./source");
|
|
7
8
|
class ComponentCompareSimple {
|
|
8
9
|
runSyntax(node, scope, filename, rowType) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
let targetType = undefined;
|
|
11
|
+
for (const c of node.getChildren()) {
|
|
12
|
+
if (c instanceof nodes_1.ExpressionNode) {
|
|
13
|
+
if (c.get() instanceof Expressions.ComponentChainSimple) {
|
|
14
|
+
targetType = new component_chain_1.ComponentChain().runSyntax(rowType, c);
|
|
15
|
+
}
|
|
16
|
+
else if (c.get() instanceof Expressions.Dynamic) {
|
|
17
|
+
targetType = undefined;
|
|
18
|
+
}
|
|
19
|
+
else if (c.get() instanceof Expressions.Source) {
|
|
20
|
+
new source_1.Source().runSyntax(c, scope, filename, targetType);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw "ComponentCompareSimple, unexpected node";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
14
26
|
}
|
|
15
27
|
}
|
|
16
28
|
}
|
|
@@ -120,7 +120,11 @@ class Source {
|
|
|
120
120
|
case "VALUE":
|
|
121
121
|
{
|
|
122
122
|
const foundType = this.determineType(node, scope, filename, targetType);
|
|
123
|
-
|
|
123
|
+
const bodyType = new value_body_1.ValueBody().runSyntax(node.findDirectExpression(Expressions.ValueBody), scope, filename, foundType);
|
|
124
|
+
if (foundType === undefined || foundType.isGeneric()) {
|
|
125
|
+
this.addIfInferred(node, scope, filename, bodyType);
|
|
126
|
+
}
|
|
127
|
+
return foundType ? foundType : bodyType;
|
|
124
128
|
}
|
|
125
129
|
default:
|
|
126
130
|
return new unknown_type_1.UnknownType("todo, Source type " + tok);
|
|
@@ -33,6 +33,9 @@ class ValueBody {
|
|
|
33
33
|
while (scope.getType() === _scope_type_1.ScopeType.For) {
|
|
34
34
|
scope.pop(node.getLastToken().getEnd());
|
|
35
35
|
}
|
|
36
|
+
if ((targetType === null || targetType === void 0 ? void 0 : targetType.isGeneric()) && type) {
|
|
37
|
+
return type;
|
|
38
|
+
}
|
|
36
39
|
return targetType ? targetType : type;
|
|
37
40
|
}
|
|
38
41
|
}
|
package/build/src/ddic.js
CHANGED
|
@@ -46,13 +46,13 @@ class DDIC {
|
|
|
46
46
|
lookupBuiltinType(name, length, decimals, qualifiedName) {
|
|
47
47
|
switch (name) {
|
|
48
48
|
case "STRING":
|
|
49
|
-
return new Types.StringType(name);
|
|
49
|
+
return new Types.StringType(qualifiedName || name);
|
|
50
50
|
case "XSTRING":
|
|
51
|
-
return new Types.XStringType(name);
|
|
51
|
+
return new Types.XStringType(qualifiedName || name);
|
|
52
52
|
case "D":
|
|
53
|
-
return new Types.DateType(name);
|
|
53
|
+
return new Types.DateType(qualifiedName || name);
|
|
54
54
|
case "T":
|
|
55
|
-
return new Types.TimeType(name);
|
|
55
|
+
return new Types.TimeType(qualifiedName || name);
|
|
56
56
|
case "XSEQUENCE":
|
|
57
57
|
return new Types.XSequenceType(qualifiedName);
|
|
58
58
|
case "CLIKE":
|
|
@@ -81,9 +81,9 @@ class DDIC {
|
|
|
81
81
|
return new Types.CSequenceType(qualifiedName);
|
|
82
82
|
case "I":
|
|
83
83
|
case "INT8": // todo, take version into account
|
|
84
|
-
return new Types.IntegerType(name);
|
|
84
|
+
return new Types.IntegerType(qualifiedName || name);
|
|
85
85
|
case "F":
|
|
86
|
-
return new Types.FloatType(name);
|
|
86
|
+
return new Types.FloatType(qualifiedName || name);
|
|
87
87
|
case "P":
|
|
88
88
|
if (length && decimals) {
|
|
89
89
|
return new Types.PackedType(length, decimals, qualifiedName);
|
package/build/src/registry.js
CHANGED
|
@@ -42,6 +42,7 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
42
42
|
this.conf = conf;
|
|
43
43
|
}
|
|
44
44
|
runParsed(file) {
|
|
45
|
+
var _a;
|
|
45
46
|
const issues = [];
|
|
46
47
|
const structure = file.getStructure();
|
|
47
48
|
if (structure === undefined) {
|
|
@@ -52,7 +53,7 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
52
53
|
// one fix per routine
|
|
53
54
|
this.fixed = false;
|
|
54
55
|
this.mode = DEFINITION;
|
|
55
|
-
this.moveTo = r.getFirstStatement();
|
|
56
|
+
this.moveTo = (_a = r.getFirstStatement()) === null || _a === void 0 ? void 0 : _a.getLastToken().getEnd();
|
|
56
57
|
const found = this.walk(r, file);
|
|
57
58
|
if (found) {
|
|
58
59
|
issues.push(found);
|
|
@@ -81,6 +82,9 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
81
82
|
// no quick fixes for these, its difficult?
|
|
82
83
|
return issue_1.Issue.atStatement(file, c.getFirstStatement(), this.getMessage(), this.getMetadata().key, this.conf.severity);
|
|
83
84
|
}
|
|
85
|
+
else {
|
|
86
|
+
this.moveTo = c.getLastToken().getEnd();
|
|
87
|
+
}
|
|
84
88
|
}
|
|
85
89
|
else if (c instanceof nodes_1.StatementNode
|
|
86
90
|
&& (c.get() instanceof Statements.Data
|
|
@@ -98,7 +102,7 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
98
102
|
return issue_1.Issue.atStatement(file, c, this.getMessage(), this.getMetadata().key, this.conf.severity, fix);
|
|
99
103
|
}
|
|
100
104
|
else {
|
|
101
|
-
this.moveTo = c;
|
|
105
|
+
this.moveTo = c.getLastToken().getEnd();
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
108
|
else if (c instanceof nodes_1.StructureNode && c.get() instanceof Structures.Define) {
|
|
@@ -121,12 +125,12 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
121
125
|
}
|
|
122
126
|
return undefined;
|
|
123
127
|
}
|
|
124
|
-
buildFix(file, statement,
|
|
128
|
+
buildFix(file, statement, at) {
|
|
125
129
|
let concat = statement.concatTokens();
|
|
126
130
|
concat = concat.replace(/,$/, ".");
|
|
127
131
|
const fix1 = edit_helper_1.EditHelper.deleteStatement(file, statement);
|
|
128
132
|
const indentation = " ".repeat(statement.getFirstToken().getCol() - 1);
|
|
129
|
-
const fix2 = edit_helper_1.EditHelper.insertAt(file,
|
|
133
|
+
const fix2 = edit_helper_1.EditHelper.insertAt(file, at, "\n" + indentation + concat);
|
|
130
134
|
return edit_helper_1.EditHelper.merge(fix1, fix2);
|
|
131
135
|
}
|
|
132
136
|
}
|
|
@@ -63,6 +63,7 @@ Current rules:
|
|
|
63
63
|
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
64
64
|
* line_exists and line_index is downported to READ TABLE
|
|
65
65
|
* ENUMs, but does not nessesarily give the correct type and value
|
|
66
|
+
* MESSAGE with non simple source
|
|
66
67
|
|
|
67
68
|
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
|
|
68
69
|
tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
@@ -285,6 +286,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
285
286
|
if (found) {
|
|
286
287
|
return found;
|
|
287
288
|
}
|
|
289
|
+
found = this.downportMessage(high, lowFile, highSyntax);
|
|
290
|
+
if (found) {
|
|
291
|
+
return found;
|
|
292
|
+
}
|
|
288
293
|
return undefined;
|
|
289
294
|
}
|
|
290
295
|
//////////////////////////////////////////
|
|
@@ -456,6 +461,30 @@ ${indentation}`);
|
|
|
456
461
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
457
462
|
return issue_1.Issue.atToken(lowFile, inlineData.getFirstToken(), "Outline SELECT @DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
458
463
|
}
|
|
464
|
+
downportMessage(high, lowFile, highSyntax) {
|
|
465
|
+
if (!(high.get() instanceof Statements.Message)) {
|
|
466
|
+
return undefined;
|
|
467
|
+
}
|
|
468
|
+
const foundWith = high.findExpressionAfterToken("WITH");
|
|
469
|
+
if (foundWith === undefined) {
|
|
470
|
+
return undefined;
|
|
471
|
+
}
|
|
472
|
+
const likeSource = high.findExpressionAfterToken("LIKE");
|
|
473
|
+
for (const s of high.findAllExpressions(Expressions.Source)) {
|
|
474
|
+
if (s === likeSource) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
478
|
+
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
479
|
+
const firstToken = high.getFirstToken();
|
|
480
|
+
const code = `DATA(${uniqueName}) = ${s.concatTokens()}.\n${indentation}`;
|
|
481
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), code);
|
|
482
|
+
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, s.getFirstToken().getStart(), s.getLastToken().getEnd(), uniqueName);
|
|
483
|
+
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
484
|
+
return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Refactor MESSAGE WITH source", this.getMetadata().key, this.conf.severity, fix);
|
|
485
|
+
}
|
|
486
|
+
return undefined;
|
|
487
|
+
}
|
|
459
488
|
replaceAppendExpression(high, lowFile, highSyntax) {
|
|
460
489
|
if (!(high.get() instanceof Statements.Append)) {
|
|
461
490
|
return undefined;
|
|
@@ -1202,6 +1231,9 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1202
1231
|
}
|
|
1203
1232
|
else if (b.get() instanceof Expressions.Source) {
|
|
1204
1233
|
structureName = b.concatTokens();
|
|
1234
|
+
if (base && (valueBody === null || valueBody === void 0 ? void 0 : valueBody.findDirectTokenByText("(")) === undefined) {
|
|
1235
|
+
structureName = uniqueName;
|
|
1236
|
+
}
|
|
1205
1237
|
}
|
|
1206
1238
|
else if (b.get() instanceof Expressions.ValueBodyLines) {
|
|
1207
1239
|
body += indentation + "APPEND " + b.concatTokens() + ` TO ${uniqueName}.\n`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.89.
|
|
3
|
+
"version": "2.89.7",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@microsoft/api-extractor": "^7.22.2",
|
|
49
49
|
"@types/chai": "^4.3.1",
|
|
50
|
-
"@types/mocha": "^9.1.
|
|
50
|
+
"@types/mocha": "^9.1.1",
|
|
51
51
|
"@types/node": "^17.0.25",
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
53
|
"eslint": "^8.13.0",
|