@abaplint/core 2.89.1 → 2.89.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/abap/5_syntax/basic_types.js +1 -1
- package/build/src/abap/5_syntax/expressions/cast.js +2 -0
- package/build/src/abap/5_syntax/expressions/source.js +7 -0
- package/build/src/abap/5_syntax/statements/find.js +2 -2
- package/build/src/registry.js +1 -1
- package/build/src/rules/downport.js +47 -6
- package/build/src/rules/no_inline_in_optional_branches.js +1 -1
- package/package.json +2 -2
|
@@ -623,7 +623,7 @@ class BasicTypes {
|
|
|
623
623
|
const search = this.scope.existsObject(name);
|
|
624
624
|
if (search.found === true && search.id) {
|
|
625
625
|
this.scope.addReference(chain.getFirstToken(), search.id, _reference_1.ReferenceType.ObjectOrientedReference, this.filename, { ooType: search.ooType, ooName: name });
|
|
626
|
-
return new Types.ObjectReferenceType(search.id);
|
|
626
|
+
return new Types.ObjectReferenceType(search.id, name);
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
629
|
const found = this.resolveTypeName(chain);
|
|
@@ -30,12 +30,14 @@ class Cast {
|
|
|
30
30
|
tt = new basic_1.VoidType(typeName);
|
|
31
31
|
}
|
|
32
32
|
else if (found === undefined) {
|
|
33
|
+
// todo, this should be an UnknownType instead?
|
|
33
34
|
throw new Error("Type \"" + typeName + "\" not found in scope, Cast");
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
tt = new basic_1.ObjectReferenceType(found);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
new source_1.Source().addIfInferred(node, scope, filename, tt);
|
|
39
41
|
if (new _type_utils_1.TypeUtils(scope).isCastable(sourceType, tt) === false) {
|
|
40
42
|
throw new Error("Cast, incompatible types");
|
|
41
43
|
}
|
|
@@ -176,6 +176,13 @@ class Source {
|
|
|
176
176
|
if (found) {
|
|
177
177
|
scope.addReference(typeToken, found, _reference_1.ReferenceType.InferredType, filename);
|
|
178
178
|
}
|
|
179
|
+
else if (inferredType instanceof basic_1.ObjectReferenceType) {
|
|
180
|
+
const def = scope.findObjectDefinition(inferredType.getQualifiedName());
|
|
181
|
+
if (def) {
|
|
182
|
+
const tid = new _typed_identifier_1.TypedIdentifier(typeToken, filename, inferredType);
|
|
183
|
+
scope.addReference(typeToken, tid, _reference_1.ReferenceType.InferredType, filename);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
179
186
|
else if (inferredType instanceof basic_1.CharacterType) {
|
|
180
187
|
// character is bit special it does not have a qualified name eg "TYPE c LENGTH 6"
|
|
181
188
|
const tid = new _typed_identifier_1.TypedIdentifier(typeToken, filename, inferredType);
|
|
@@ -18,12 +18,12 @@ class Find {
|
|
|
18
18
|
{ name: "OFFSET", type: new basic_1.IntegerType() },
|
|
19
19
|
{ name: "LENGTH", type: new basic_1.IntegerType() },
|
|
20
20
|
{ name: "SUBMATCHES", type: new basic_1.TableType(new basic_1.StringType(), { withHeader: false }) },
|
|
21
|
-
]);
|
|
21
|
+
], "MATCH_RESULT");
|
|
22
22
|
if (node.concatTokens().toUpperCase().startsWith("FIND FIRST")) {
|
|
23
23
|
this.inline(rfound, scope, filename, type);
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false }));
|
|
26
|
+
this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false }, "MATCH_RESULT_TAB"));
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
const ofound = node.findExpressionsAfterToken("OFFSET");
|
package/build/src/registry.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Downport = exports.DownportConf = void 0;
|
|
4
|
+
const Statements = require("../abap/2_statements/statements");
|
|
5
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
6
|
+
const Structures = require("../abap/3_structures/structures");
|
|
4
7
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
5
8
|
const issue_1 = require("../issue");
|
|
6
9
|
const _irule_1 = require("./_irule");
|
|
7
10
|
const _statement_1 = require("../abap/2_statements/statements/_statement");
|
|
8
11
|
const nodes_1 = require("../abap/nodes");
|
|
9
|
-
const Statements = require("../abap/2_statements/statements");
|
|
10
|
-
const Expressions = require("../abap/2_statements/expressions");
|
|
11
12
|
const edit_helper_1 = require("../edit_helper");
|
|
12
13
|
const position_1 = require("../position");
|
|
13
14
|
const _abap_object_1 = require("../objects/_abap_object");
|
|
@@ -61,6 +62,7 @@ Current rules:
|
|
|
61
62
|
* RAISE EXCEPTION ... MESSAGE
|
|
62
63
|
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
63
64
|
* line_exists and line_index is downported to READ TABLE
|
|
65
|
+
* ENUMs, but does not nessesarily give the correct type and value
|
|
64
66
|
|
|
65
67
|
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
|
|
66
68
|
tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
@@ -131,7 +133,7 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
131
133
|
const high = highStatements[i];
|
|
132
134
|
if ((low.get() instanceof _statement_1.Unknown && !(high.get() instanceof _statement_1.Unknown))
|
|
133
135
|
|| high.findFirstExpression(Expressions.InlineData)) {
|
|
134
|
-
const issue = this.checkStatement(low, high, lowFile, highSyntax);
|
|
136
|
+
const issue = this.checkStatement(low, high, lowFile, highSyntax, highFile);
|
|
135
137
|
if (issue) {
|
|
136
138
|
ret.push(issue);
|
|
137
139
|
}
|
|
@@ -163,11 +165,15 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
163
165
|
this.highReg.parse();
|
|
164
166
|
}
|
|
165
167
|
/** applies one rule at a time, multiple iterations are required to transform complex statements */
|
|
166
|
-
checkStatement(low, high, lowFile, highSyntax) {
|
|
168
|
+
checkStatement(low, high, lowFile, highSyntax, highFile) {
|
|
167
169
|
if (low.getFirstToken().getStart() instanceof position_1.VirtualPosition) {
|
|
168
170
|
return undefined;
|
|
169
171
|
}
|
|
170
|
-
let found = this.
|
|
172
|
+
let found = this.downportEnum(low, high, lowFile, highSyntax, highFile);
|
|
173
|
+
if (found) {
|
|
174
|
+
return found;
|
|
175
|
+
}
|
|
176
|
+
found = this.partiallyImplemented(high, lowFile);
|
|
171
177
|
if (found) {
|
|
172
178
|
return found;
|
|
173
179
|
}
|
|
@@ -738,6 +744,38 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
|
738
744
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, code);
|
|
739
745
|
return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, simple move", this.getMetadata().key, this.conf.severity, fix);
|
|
740
746
|
}
|
|
747
|
+
// note, downporting ENUM does not give the correct types, but it will work in most cases?
|
|
748
|
+
downportEnum(_low, high, lowFile, _highSyntax, highFile) {
|
|
749
|
+
var _a, _b, _c, _d, _e;
|
|
750
|
+
if (!(high.get() instanceof Statements.TypeEnumBegin)) {
|
|
751
|
+
return undefined;
|
|
752
|
+
}
|
|
753
|
+
const enumStructure = (_a = highFile.getStructure()) === null || _a === void 0 ? void 0 : _a.findFirstStructure(Structures.TypeEnum);
|
|
754
|
+
if (enumStructure === undefined) {
|
|
755
|
+
return undefined;
|
|
756
|
+
}
|
|
757
|
+
if (enumStructure.getFirstStatement() !== high) {
|
|
758
|
+
return undefined;
|
|
759
|
+
}
|
|
760
|
+
const enumName = (_b = high.findExpressionAfterToken("ENUM")) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
761
|
+
const structureName = (_c = high.findExpressionAfterToken("STRUCTURE")) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
762
|
+
let code = `TYPES ${enumName} TYPE i.
|
|
763
|
+
CONSTANTS: BEGIN OF ${structureName},\n`;
|
|
764
|
+
let count = 1;
|
|
765
|
+
for (const e of enumStructure.findDirectStatements(Statements.TypeEnum).concat(enumStructure.findDirectStatements(Statements.Type))) {
|
|
766
|
+
const name = (_d = e.findFirstExpression(Expressions.NamespaceSimpleName)) === null || _d === void 0 ? void 0 : _d.concatTokens();
|
|
767
|
+
let value = (_e = e.findFirstExpression(Expressions.Value)) === null || _e === void 0 ? void 0 : _e.concatTokens();
|
|
768
|
+
if (value === undefined) {
|
|
769
|
+
value = "VALUE " + count++;
|
|
770
|
+
}
|
|
771
|
+
code += ` ${name} TYPE ${enumName} ${value},\n`;
|
|
772
|
+
}
|
|
773
|
+
code += ` END OF ${structureName}.`;
|
|
774
|
+
const start = enumStructure.getFirstToken().getStart();
|
|
775
|
+
const end = enumStructure.getLastToken().getEnd();
|
|
776
|
+
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, code);
|
|
777
|
+
return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport ENUM", this.getMetadata().key, this.conf.severity, fix);
|
|
778
|
+
}
|
|
741
779
|
moveWithTableTarget(node, high, lowFile, highSyntax) {
|
|
742
780
|
var _a;
|
|
743
781
|
if (!(high.get() instanceof Statements.Move)) {
|
|
@@ -1310,7 +1348,10 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1310
1348
|
else if (found.getType() instanceof basic_1.VoidType && found.getType().getQualifiedName() === undefined) {
|
|
1311
1349
|
continue;
|
|
1312
1350
|
}
|
|
1313
|
-
|
|
1351
|
+
let type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();
|
|
1352
|
+
if (found.getType() instanceof basic_1.ObjectReferenceType) {
|
|
1353
|
+
type = found.getType().toABAP();
|
|
1354
|
+
}
|
|
1314
1355
|
const code = `DATA ${name} TYPE ${type}.\n` +
|
|
1315
1356
|
" ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1316
1357
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
|
|
@@ -67,7 +67,7 @@ Not considered optional branches:
|
|
|
67
67
|
const inline = c.findFirstExpression(Expressions.InlineData);
|
|
68
68
|
if (inline) {
|
|
69
69
|
const message = "Don't declare inline in optional branches";
|
|
70
|
-
const issue = issue_1.Issue.atToken(file,
|
|
70
|
+
const issue = issue_1.Issue.atToken(file, inline.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
|
|
71
71
|
output.push(issue);
|
|
72
72
|
}
|
|
73
73
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.89.
|
|
3
|
+
"version": "2.89.4",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
53
|
"eslint": "^8.13.0",
|
|
54
54
|
"mocha": "^9.2.2",
|
|
55
|
-
"c8": "^7.11.
|
|
55
|
+
"c8": "^7.11.2",
|
|
56
56
|
"source-map-support": "^0.5.21",
|
|
57
57
|
"ts-json-schema-generator": "^1.0.0",
|
|
58
58
|
"typescript": "^4.6.3"
|