@abaplint/transpiler 2.13.97 → 2.13.99
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/traversal.d.ts +13 -0
- package/build/src/traversal.js +97 -12
- package/package.json +2 -2
package/build/src/traversal.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare class Traversal {
|
|
|
15
15
|
private readonly doOrWhileIndexBackups;
|
|
16
16
|
private readonly statementsInsideLoop;
|
|
17
17
|
private readonly enclosingDoOrWhile;
|
|
18
|
+
/** DATA, CONSTANTS and FIELD-SYMBOLS nested in blocks, already declared in front of the block */
|
|
19
|
+
private readonly declaredEarly;
|
|
20
|
+
private emittingEarly;
|
|
21
|
+
private blockDepth;
|
|
18
22
|
readonly reg: abaplint.IRegistry;
|
|
19
23
|
readonly options: ITranspilerOptions | undefined;
|
|
20
24
|
constructor(spaghetti: abaplint.ISpaghettiScope, file: abaplint.ABAPFile, obj: abaplint.ABAPObject, reg: abaplint.IRegistry, options?: ITranspilerOptions);
|
|
@@ -106,6 +110,15 @@ export declare class Traversal {
|
|
|
106
110
|
buildInternalName(name: string, def: abaplint.IClassDefinition | abaplint.IInterfaceDefinition | undefined): string;
|
|
107
111
|
lookupClassOrInterface(name: string | undefined, token: abaplint.Token | undefined, directGlobal?: boolean): string;
|
|
108
112
|
buildPrefix(): string;
|
|
113
|
+
/** In ABAP, DATA, CONSTANTS and FIELD-SYMBOLS are visible in the whole method/form/program, but a
|
|
114
|
+
* javascript "let" inside the block of an IF, LOOP, TRY etc. is not. So before each block on
|
|
115
|
+
* method/form/program level the declarations nested in it are output, in source order, and
|
|
116
|
+
* skipped inside the block. They then exist after the block even if the branch did not run,
|
|
117
|
+
* and are initialized once, also when the block is a loop */
|
|
118
|
+
private traverseProcedureLevel;
|
|
119
|
+
private declareNestedEarly;
|
|
120
|
+
private static isDeclaration;
|
|
121
|
+
private static findNestedDeclarations;
|
|
109
122
|
protected traverseStructure(node: abaplint.Nodes.StructureNode): Chunk;
|
|
110
123
|
protected traverseStatement(node: abaplint.Nodes.StatementNode): Chunk;
|
|
111
124
|
protected traverseExpression(node: abaplint.Nodes.ExpressionNode): Chunk;
|
package/build/src/traversal.js
CHANGED
|
@@ -88,6 +88,10 @@ class Traversal {
|
|
|
88
88
|
doOrWhileIndexBackups = new Map();
|
|
89
89
|
statementsInsideLoop = new WeakSet();
|
|
90
90
|
enclosingDoOrWhile = new WeakMap();
|
|
91
|
+
/** DATA, CONSTANTS and FIELD-SYMBOLS nested in blocks, already declared in front of the block */
|
|
92
|
+
declaredEarly = new WeakSet();
|
|
93
|
+
emittingEarly = false;
|
|
94
|
+
blockDepth = 0;
|
|
91
95
|
reg;
|
|
92
96
|
options;
|
|
93
97
|
constructor(spaghetti, file, obj, reg, options) {
|
|
@@ -926,17 +930,15 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
926
930
|
}
|
|
927
931
|
else if (c.get() instanceof abaplint.Expressions.AttributeName
|
|
928
932
|
&& context instanceof abaplint.BasicTypes.ObjectReferenceType) {
|
|
929
|
-
const
|
|
930
|
-
if (
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
context = id.getAttributes().findByName(concat)?.getType();
|
|
939
|
-
}
|
|
933
|
+
const concat = c.concatTokens();
|
|
934
|
+
if (concat.includes("~")) {
|
|
935
|
+
const [iname, aname] = concat.split("~");
|
|
936
|
+
const intf = this.findInterfaceDefinition(iname, scope);
|
|
937
|
+
context = intf?.getAttributes().findByName(aname)?.getType();
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
// Global references can carry an identifier rather than a class definition.
|
|
941
|
+
context = this.narrowContextAttribute(context, concat, scope);
|
|
940
942
|
}
|
|
941
943
|
}
|
|
942
944
|
else if (c.get() instanceof abaplint.Expressions.AttributeName
|
|
@@ -950,7 +952,7 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
950
952
|
return context;
|
|
951
953
|
}
|
|
952
954
|
isInsideLoop(node) {
|
|
953
|
-
return this.statementsInsideLoop.has(node);
|
|
955
|
+
return this.statementsInsideLoop.has(node) && !this.declaredEarly.has(node);
|
|
954
956
|
}
|
|
955
957
|
isInsideDoOrWhile(node) {
|
|
956
958
|
return this.findCurrentDoOrWhileIndexBackup(node) !== undefined;
|
|
@@ -1045,7 +1047,87 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
1045
1047
|
return this.obj.getType() + "-" + this.obj.getName() + "-";
|
|
1046
1048
|
}
|
|
1047
1049
|
////////////////////////////
|
|
1050
|
+
/** In ABAP, DATA, CONSTANTS and FIELD-SYMBOLS are visible in the whole method/form/program, but a
|
|
1051
|
+
* javascript "let" inside the block of an IF, LOOP, TRY etc. is not. So before each block on
|
|
1052
|
+
* method/form/program level the declarations nested in it are output, in source order, and
|
|
1053
|
+
* skipped inside the block. They then exist after the block even if the branch did not run,
|
|
1054
|
+
* and are initialized once, also when the block is a loop */
|
|
1055
|
+
traverseProcedureLevel(node) {
|
|
1056
|
+
const ret = new chunk_1.Chunk();
|
|
1057
|
+
for (const c of node.getChildren()) {
|
|
1058
|
+
if (c instanceof abaplint.Nodes.StructureNode && Traversal.isDeclaration(c) === false) {
|
|
1059
|
+
ret.appendChunk(this.declareNestedEarly(c));
|
|
1060
|
+
this.blockDepth++;
|
|
1061
|
+
try {
|
|
1062
|
+
ret.appendChunk(this.traverseStructure(c));
|
|
1063
|
+
}
|
|
1064
|
+
finally {
|
|
1065
|
+
this.blockDepth--;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
ret.appendChunk(this.traverse(c));
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return ret;
|
|
1073
|
+
}
|
|
1074
|
+
declareNestedEarly(block) {
|
|
1075
|
+
const found = [];
|
|
1076
|
+
Traversal.findNestedDeclarations(block, found);
|
|
1077
|
+
for (const node of found) {
|
|
1078
|
+
this.declaredEarly.add(node);
|
|
1079
|
+
if (node instanceof abaplint.Nodes.StructureNode) {
|
|
1080
|
+
for (const statement of node.findAllStatementNodes()) {
|
|
1081
|
+
this.declaredEarly.add(statement);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
const ret = new chunk_1.Chunk();
|
|
1086
|
+
this.emittingEarly = true;
|
|
1087
|
+
try {
|
|
1088
|
+
for (const node of found) {
|
|
1089
|
+
ret.appendChunk(this.traverse(node));
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
finally {
|
|
1093
|
+
this.emittingEarly = false;
|
|
1094
|
+
}
|
|
1095
|
+
return ret;
|
|
1096
|
+
}
|
|
1097
|
+
static isDeclaration(node) {
|
|
1098
|
+
const get = node.get();
|
|
1099
|
+
return get instanceof abaplint.Structures.Data
|
|
1100
|
+
|| get instanceof abaplint.Structures.Constants
|
|
1101
|
+
|| get instanceof abaplint.Structures.Types;
|
|
1102
|
+
}
|
|
1103
|
+
static findNestedDeclarations(node, found) {
|
|
1104
|
+
for (const c of node.getChildren()) {
|
|
1105
|
+
if (c instanceof abaplint.Nodes.StatementNode) {
|
|
1106
|
+
const get = c.get();
|
|
1107
|
+
if (get instanceof abaplint.Statements.Data
|
|
1108
|
+
|| get instanceof abaplint.Statements.Constant
|
|
1109
|
+
|| get instanceof abaplint.Statements.FieldSymbol) {
|
|
1110
|
+
found.push(c);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
else if (c instanceof abaplint.Nodes.StructureNode) {
|
|
1114
|
+
const get = c.get();
|
|
1115
|
+
if (get instanceof abaplint.Structures.Data || get instanceof abaplint.Structures.Constants) {
|
|
1116
|
+
found.push(c);
|
|
1117
|
+
}
|
|
1118
|
+
else {
|
|
1119
|
+
Traversal.findNestedDeclarations(c, found);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1048
1124
|
traverseStructure(node) {
|
|
1125
|
+
if (this.declaredEarly.has(node) && this.emittingEarly === false) {
|
|
1126
|
+
return new chunk_1.Chunk();
|
|
1127
|
+
}
|
|
1128
|
+
else if (this.blockDepth === 0 && node.get() instanceof abaplint.Structures.Normal) {
|
|
1129
|
+
return this.traverseProcedureLevel(node);
|
|
1130
|
+
}
|
|
1049
1131
|
const list = StructureTranspilers;
|
|
1050
1132
|
const ret = new chunk_1.Chunk();
|
|
1051
1133
|
const search = node.get().constructor.name + "Transpiler";
|
|
@@ -1068,6 +1150,9 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
1068
1150
|
return ret;
|
|
1069
1151
|
}
|
|
1070
1152
|
traverseStatement(node) {
|
|
1153
|
+
if (this.declaredEarly.has(node) && this.emittingEarly === false) {
|
|
1154
|
+
return new chunk_1.Chunk();
|
|
1155
|
+
}
|
|
1071
1156
|
const list = StatementTranspilers;
|
|
1072
1157
|
const search = node.get().constructor.name + "Transpiler";
|
|
1073
1158
|
if (list[search]) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.99",
|
|
4
4
|
"description": "Transpiler",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/src/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"author": "abaplint",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@abaplint/core": "^2.120.
|
|
32
|
+
"@abaplint/core": "^2.120.68",
|
|
33
33
|
"source-map": "^0.8.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|