@abaplint/core 2.89.6 → 2.89.9
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/2_statements/statements/message.js +1 -1
- package/build/src/abap/5_syntax/basic_types.js +18 -8
- package/build/src/abap/5_syntax/expressions/component_compare_simple.js +17 -5
- package/build/src/abap/5_syntax/expressions/loop_group_by.js +11 -0
- package/build/src/abap/5_syntax/expressions/source.js +3 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/downport.js +57 -18
- package/package.json +5 -5
|
@@ -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));
|
|
@@ -249,9 +249,9 @@ class BasicTypes {
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
const options = {
|
|
252
|
-
withHeader: text.includes("WITH HEADER LINE"),
|
|
252
|
+
withHeader: text.includes(" WITH HEADER LINE"),
|
|
253
253
|
type: type,
|
|
254
|
-
isUnique: text.includes("WITH UNIQUE"),
|
|
254
|
+
isUnique: text.includes(" WITH UNIQUE"),
|
|
255
255
|
keyFields: keyFields,
|
|
256
256
|
};
|
|
257
257
|
let found = undefined;
|
|
@@ -387,7 +387,7 @@ class BasicTypes {
|
|
|
387
387
|
sub = node.findFirstExpression(Expressions.FieldChain);
|
|
388
388
|
}
|
|
389
389
|
found = this.resolveLikeName(sub);
|
|
390
|
-
if (found &&
|
|
390
|
+
if (found && this.isOccurs(node)) {
|
|
391
391
|
found = new Types.TableType(found, { withHeader: text.includes("WITH HEADER LINE") }, qualifiedName);
|
|
392
392
|
}
|
|
393
393
|
}
|
|
@@ -416,10 +416,10 @@ class BasicTypes {
|
|
|
416
416
|
else if (text.startsWith("TYPE")) {
|
|
417
417
|
found = this.resolveTypeName(typeName, this.findLength(node), this.findDecimals(node), qualifiedName);
|
|
418
418
|
const concat = node.concatTokens().toUpperCase();
|
|
419
|
-
if (found &&
|
|
420
|
-
found = new Types.TableType(found, { withHeader: concat.includes("WITH HEADER LINE") }, qualifiedName);
|
|
419
|
+
if (found && this.isOccurs(node)) {
|
|
420
|
+
found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE") }, qualifiedName);
|
|
421
421
|
}
|
|
422
|
-
else if (found && concat.includes("WITH HEADER LINE")) {
|
|
422
|
+
else if (found && concat.includes(" WITH HEADER LINE")) {
|
|
423
423
|
if (found instanceof Types.VoidType) {
|
|
424
424
|
found = new Types.TableType(found, { withHeader: true });
|
|
425
425
|
}
|
|
@@ -440,14 +440,24 @@ class BasicTypes {
|
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
442
|
found = new Types.CharacterType(length, qualifiedName); // fallback
|
|
443
|
-
if (
|
|
444
|
-
found = new Types.TableType(found, { withHeader: concat.includes("WITH HEADER LINE") }, qualifiedName);
|
|
443
|
+
if (this.isOccurs(node)) {
|
|
444
|
+
found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE") }, qualifiedName);
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
}
|
|
448
448
|
return found;
|
|
449
449
|
}
|
|
450
450
|
/////////////////////
|
|
451
|
+
isOccurs(node) {
|
|
452
|
+
var _a;
|
|
453
|
+
if (node.findDirectTokenByText("OCCURS")) {
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
else if ((_a = node.findFirstExpression(Expressions.TypeTable)) === null || _a === void 0 ? void 0 : _a.findDirectTokenByText("OCCURS")) {
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
451
461
|
// todo, rewrite this method
|
|
452
462
|
resolveTypeChain(expr) {
|
|
453
463
|
var _a;
|
|
@@ -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
|
}
|
|
@@ -4,7 +4,9 @@ exports.LoopGroupBy = void 0;
|
|
|
4
4
|
const Expressions = require("../../2_statements/expressions");
|
|
5
5
|
const basic_1 = require("../../types/basic");
|
|
6
6
|
const component_compare_1 = require("./component_compare");
|
|
7
|
+
const inline_data_1 = require("./inline_data");
|
|
7
8
|
const inline_fs_1 = require("./inline_fs");
|
|
9
|
+
const target_1 = require("./target");
|
|
8
10
|
class LoopGroupBy {
|
|
9
11
|
runSyntax(node, scope, filename) {
|
|
10
12
|
const components = [];
|
|
@@ -17,6 +19,15 @@ class LoopGroupBy {
|
|
|
17
19
|
return;
|
|
18
20
|
}
|
|
19
21
|
const sourceType = new basic_1.StructureType(components);
|
|
22
|
+
for (const t of node.findAllExpressions(Expressions.Target)) {
|
|
23
|
+
const inline = t.findDirectExpression(Expressions.InlineData);
|
|
24
|
+
if (inline) {
|
|
25
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, new basic_1.VoidType("todoGroupBy"));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
new target_1.Target().runSyntax(t, scope, filename);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
20
31
|
const inlinefs = node.findFirstExpression(Expressions.InlineFS);
|
|
21
32
|
if (inlinefs) {
|
|
22
33
|
new inline_fs_1.InlineFS().runSyntax(inlinefs, scope, filename, sourceType);
|
package/build/src/registry.js
CHANGED
|
@@ -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;
|
|
@@ -661,36 +690,46 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
661
690
|
bar->if_t100_dyn_msg~msgv4 = 'abc'.
|
|
662
691
|
RAISE EXCEPTION bar.
|
|
663
692
|
*/
|
|
664
|
-
var _a;
|
|
665
|
-
if (node.get() instanceof Statements.Raise) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
693
|
+
var _a, _b, _c;
|
|
694
|
+
if (!(node.get() instanceof Statements.Raise)) {
|
|
695
|
+
return undefined;
|
|
696
|
+
}
|
|
697
|
+
let id = undefined;
|
|
698
|
+
let number = undefined;
|
|
699
|
+
let startToken = node.findDirectTokenByText("ID");
|
|
700
|
+
if (startToken) {
|
|
670
701
|
const sources = node.findDirectExpressions(Expressions.Source);
|
|
671
|
-
|
|
702
|
+
id = sources[0].concatTokens();
|
|
672
703
|
const numberExpression = node.findExpressionAfterToken("NUMBER");
|
|
673
704
|
if (numberExpression === undefined) {
|
|
674
705
|
throw "downport raiseException, could not find number";
|
|
675
706
|
}
|
|
676
|
-
|
|
707
|
+
number = numberExpression.concatTokens();
|
|
677
708
|
if (numberExpression.get() instanceof Expressions.MessageNumber) {
|
|
678
709
|
number = "'" + number + "'";
|
|
679
710
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
const s = node.findDirectExpression(Expressions.MessageSource);
|
|
714
|
+
if (s === undefined) {
|
|
715
|
+
return undefined;
|
|
716
|
+
}
|
|
717
|
+
id = "'" + ((_a = s.findDirectExpression(Expressions.MessageClass)) === null || _a === void 0 ? void 0 : _a.concatTokens()) + "'";
|
|
718
|
+
number = "'" + ((_b = s.findDirectExpression(Expressions.MessageTypeAndNumber)) === null || _b === void 0 ? void 0 : _b.concatTokens().substring(1)) + "'";
|
|
719
|
+
startToken = node.getFirstToken();
|
|
720
|
+
}
|
|
721
|
+
const className = ((_c = node.findDirectExpression(Expressions.ClassName)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "ERROR";
|
|
722
|
+
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
723
|
+
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
724
|
+
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
725
|
+
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
726
|
+
${indentation}${uniqueName1}-msgid = ${id === null || id === void 0 ? void 0 : id.toUpperCase()}.
|
|
686
727
|
${indentation}${uniqueName1}-msgno = ${number}.
|
|
687
728
|
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
688
729
|
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
689
730
|
${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
}
|
|
693
|
-
return undefined;
|
|
731
|
+
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), abap);
|
|
732
|
+
return issue_1.Issue.atToken(lowFile, startToken, "Downport RAISE MESSAGE", this.getMetadata().key, this.conf.severity, fix);
|
|
694
733
|
}
|
|
695
734
|
emptyKey(node, lowFile) {
|
|
696
735
|
for (let i of node.findAllExpressions(Expressions.TypeTable)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.89.
|
|
3
|
+
"version": "2.89.9",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://abaplint.org",
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@microsoft/api-extractor": "^7.
|
|
48
|
+
"@microsoft/api-extractor": "^7.23.0",
|
|
49
49
|
"@types/chai": "^4.3.1",
|
|
50
|
-
"@types/mocha": "^9.1.
|
|
51
|
-
"@types/node": "^17.0.
|
|
50
|
+
"@types/mocha": "^9.1.1",
|
|
51
|
+
"@types/node": "^17.0.26",
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
|
-
"eslint": "^8.
|
|
53
|
+
"eslint": "^8.14.0",
|
|
54
54
|
"mocha": "^9.2.2",
|
|
55
55
|
"c8": "^7.11.2",
|
|
56
56
|
"source-map-support": "^0.5.21",
|