@abaplint/transpiler 2.13.96 → 2.13.98
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/chunk.js +2 -1
- package/build/src/expressions/reduce_body.js +12 -16
- package/build/src/expressions/source.d.ts +3 -1
- package/build/src/expressions/source.js +29 -5
- package/build/src/expressions/value_body.js +25 -22
- package/build/src/statements/assign.js +9 -8
- package/build/src/statements/call.js +3 -3
- package/build/src/statements/call_function.js +10 -3
- package/build/src/statements/create_data.js +1 -1
- package/build/src/statements/generate_subroutine.d.ts +3 -1
- package/build/src/statements/generate_subroutine.js +72 -2
- package/build/src/statements/move.d.ts +2 -0
- package/build/src/statements/move.js +70 -1
- package/build/src/statements/perform.js +13 -1
- package/build/src/statements/select.js +34 -33
- package/build/src/statements/sort.d.ts +2 -0
- package/build/src/statements/sort.js +33 -4
- package/build/src/structures/class_definition.js +10 -9
- package/package.json +2 -2
package/build/src/chunk.js
CHANGED
|
@@ -170,7 +170,8 @@ class Chunk {
|
|
|
170
170
|
}
|
|
171
171
|
const indentationByLine = this.mappings.length > 0 ? [] : undefined;
|
|
172
172
|
for (const l of this.raw.split("\n")) {
|
|
173
|
-
|
|
173
|
+
// trimStart, a pre-indented closing brace must still close its level
|
|
174
|
+
if (l.trimStart().startsWith("}")) {
|
|
174
175
|
i = i - 1;
|
|
175
176
|
}
|
|
176
177
|
// clamp so unbalanced braces never produce a negative indent/shift
|
|
@@ -31,22 +31,18 @@ class ReduceBodyTranspiler {
|
|
|
31
31
|
for (const declaration of declarations) {
|
|
32
32
|
ret.appendString(declaration + "\n");
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// no manual indentation, Chunk.runIndentationLogic indents by brace depth,
|
|
35
|
+
// pre-indented closing braces would not be recognized and drift the indentation
|
|
36
36
|
for (const descriptor of descriptors) {
|
|
37
|
-
this.appendBlocks(ret, descriptor.beforeLoop
|
|
38
|
-
ret.appendString(
|
|
39
|
-
|
|
40
|
-
levelIndents.push(indent);
|
|
41
|
-
this.appendBlocks(ret, descriptor.preBody, indent);
|
|
37
|
+
this.appendBlocks(ret, descriptor.beforeLoop);
|
|
38
|
+
ret.appendString(descriptor.open + "\n");
|
|
39
|
+
this.appendBlocks(ret, descriptor.preBody);
|
|
42
40
|
}
|
|
43
|
-
this.appendBlock(ret, this.transpileNext(body, traversal)
|
|
41
|
+
this.appendBlock(ret, this.transpileNext(body, traversal));
|
|
44
42
|
for (let i = descriptors.length - 1; i >= 0; i--) {
|
|
45
43
|
const descriptor = descriptors[i];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
indent = currentIndent.substring(0, Math.max(0, currentIndent.length - 2));
|
|
49
|
-
ret.appendString(indent + descriptor.close + "\n");
|
|
44
|
+
this.appendBlocks(ret, descriptor.postBody);
|
|
45
|
+
ret.appendString(descriptor.close + "\n");
|
|
50
46
|
}
|
|
51
47
|
ret.appendString(`return ${returnField};\n`);
|
|
52
48
|
ret.appendString("})())");
|
|
@@ -266,15 +262,15 @@ class ReduceBodyTranspiler {
|
|
|
266
262
|
}
|
|
267
263
|
return ret;
|
|
268
264
|
}
|
|
269
|
-
appendBlocks(ret, blocks
|
|
265
|
+
appendBlocks(ret, blocks) {
|
|
270
266
|
for (const block of blocks) {
|
|
271
|
-
this.appendBlock(ret, block
|
|
267
|
+
this.appendBlock(ret, block);
|
|
272
268
|
}
|
|
273
269
|
}
|
|
274
|
-
appendBlock(ret, block
|
|
270
|
+
appendBlock(ret, block) {
|
|
275
271
|
for (const line of block.split("\n")) {
|
|
276
272
|
if (line.trim() !== "") {
|
|
277
|
-
ret.appendString(
|
|
273
|
+
ret.appendString(line.replace(/\r/g, "") + "\n");
|
|
278
274
|
}
|
|
279
275
|
}
|
|
280
276
|
}
|
|
@@ -4,7 +4,9 @@ import { IExpressionTranspiler } from "./_expression_transpiler";
|
|
|
4
4
|
import { Traversal } from "../traversal";
|
|
5
5
|
export declare class SourceTranspiler implements IExpressionTranspiler {
|
|
6
6
|
private readonly addGet;
|
|
7
|
-
|
|
7
|
+
private readonly int8;
|
|
8
|
+
/** int8: the calculation type is int8, each operation gets its left operand as an int8 */
|
|
9
|
+
constructor(addGet?: boolean, int8?: boolean);
|
|
8
10
|
private concatOperands;
|
|
9
11
|
transpile(node: Nodes.ExpressionNode, traversal: Traversal, context?: AbstractType): Chunk;
|
|
10
12
|
}
|
|
@@ -9,11 +9,15 @@ const corresponding_body_1 = require("./corresponding_body");
|
|
|
9
9
|
const filter_body_1 = require("./filter_body");
|
|
10
10
|
const reduce_body_1 = require("./reduce_body");
|
|
11
11
|
const transpile_types_1 = require("../transpile_types");
|
|
12
|
+
const let_1 = require("./let");
|
|
12
13
|
const value_body_1 = require("./value_body");
|
|
13
14
|
class SourceTranspiler {
|
|
14
15
|
addGet;
|
|
15
|
-
|
|
16
|
+
int8;
|
|
17
|
+
/** int8: the calculation type is int8, each operation gets its left operand as an int8 */
|
|
18
|
+
constructor(addGet = false, int8 = false) {
|
|
16
19
|
this.addGet = addGet;
|
|
20
|
+
this.int8 = int8;
|
|
17
21
|
}
|
|
18
22
|
// the operands of a chain of & / && (the rearranger leaves them as a binary
|
|
19
23
|
// tree of Source nodes); an empty list when the node is not such a chain
|
|
@@ -81,6 +85,8 @@ class SourceTranspiler {
|
|
|
81
85
|
break;
|
|
82
86
|
}
|
|
83
87
|
}
|
|
88
|
+
// int8: whether the operand left of the next operator is already an int8
|
|
89
|
+
let leftIsInt8 = false;
|
|
84
90
|
for (let i = startIdx; i < children.length; i++) {
|
|
85
91
|
const c = children[i];
|
|
86
92
|
const isLast = i === children.length - 1;
|
|
@@ -98,7 +104,18 @@ class SourceTranspiler {
|
|
|
98
104
|
ret.appendChunk(traversal.traverse(c));
|
|
99
105
|
}
|
|
100
106
|
else if (c.get() instanceof core_1.Expressions.ArithOperator) {
|
|
101
|
-
|
|
107
|
+
// "/" rounds in calculation type int8, the runtime's divide() does not know the target
|
|
108
|
+
const operator = this.int8 === true && c.concatTokens().trim() === "/"
|
|
109
|
+
? new chunk_1.Chunk().append("abap.operators.divideInt8", c, traversal)
|
|
110
|
+
: traversal.traverse(c);
|
|
111
|
+
if (this.int8 === true && leftIsInt8 === false) {
|
|
112
|
+
ret = new chunk_1.Chunk().appendChunk(operator).appendString("(new abap.types.Integer8().set(").appendChunk(ret).appendString("),");
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
ret = new chunk_1.Chunk().appendChunk(operator).appendString("(").appendChunk(ret).appendString(",");
|
|
116
|
+
}
|
|
117
|
+
// the result of an operation with an int8 operand is an int8
|
|
118
|
+
leftIsInt8 = true;
|
|
102
119
|
post.appendString(")");
|
|
103
120
|
if (this.addGet) {
|
|
104
121
|
post.append(".get()", c, traversal);
|
|
@@ -115,7 +132,8 @@ class SourceTranspiler {
|
|
|
115
132
|
}
|
|
116
133
|
}
|
|
117
134
|
else if (c.get() instanceof core_1.Expressions.Source) {
|
|
118
|
-
ret.appendChunk(new SourceTranspiler(this.addGet).transpile(c, traversal));
|
|
135
|
+
ret.appendChunk(new SourceTranspiler(this.addGet, this.int8).transpile(c, traversal));
|
|
136
|
+
leftIsInt8 = c.findDirectExpression(core_1.Expressions.ArithOperator) !== undefined;
|
|
119
137
|
}
|
|
120
138
|
else if (c.get() instanceof core_1.Expressions.Arrow) {
|
|
121
139
|
ret = new chunk_1.Chunk().appendString("(").appendChunk(ret).appendString(").get().");
|
|
@@ -151,13 +169,19 @@ class SourceTranspiler {
|
|
|
151
169
|
}
|
|
152
170
|
ret = new chunk_1.Chunk().appendString(new _1.TypeNameOrInfer().transpile(typ, traversal).getCode());
|
|
153
171
|
ret.appendString(".set(");
|
|
154
|
-
// todo: handle LET
|
|
155
172
|
const context = new _1.TypeNameOrInfer().findType(typ, traversal);
|
|
156
|
-
|
|
173
|
+
const convSource = c.findDirectExpression(core_1.Expressions.Source);
|
|
174
|
+
ret.appendString(new SourceTranspiler().transpile(convSource, traversal, context).getCode());
|
|
157
175
|
ret.appendString(")");
|
|
158
176
|
if (this.addGet) {
|
|
159
177
|
ret.appendString(".get()");
|
|
160
178
|
}
|
|
179
|
+
const convLet = c.findDirectExpression(core_1.Expressions.Let);
|
|
180
|
+
if (convLet) {
|
|
181
|
+
// the LET bindings are declared in a scope of their own, before the value is built
|
|
182
|
+
const letCode = new let_1.LetTranspiler().transpile(convLet, traversal).getCode();
|
|
183
|
+
ret = new chunk_1.Chunk().appendString(`(await (async () => { ${letCode} return ${ret.getCode()}; })())`);
|
|
184
|
+
}
|
|
161
185
|
}
|
|
162
186
|
else if (c.get() instanceof core_1.Expressions.ValueBody) {
|
|
163
187
|
continue;
|
|
@@ -30,6 +30,7 @@ class ValueBodyTranspiler {
|
|
|
30
30
|
const outerLetCode = outerLet === undefined
|
|
31
31
|
? undefined
|
|
32
32
|
: new let_1.LetTranspiler().transpile(outerLet, traversal).getCode();
|
|
33
|
+
let hasFor = false;
|
|
33
34
|
const children = body.getChildren();
|
|
34
35
|
for (let i = 0; i < children.length; i++) {
|
|
35
36
|
const child = children[i];
|
|
@@ -72,6 +73,7 @@ class ValueBodyTranspiler {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
i = idx - 1;
|
|
76
|
+
hasFor = true;
|
|
75
77
|
const result = this.buildForChain(forNodes, typ, traversal, body, baseCode, outerLetCode);
|
|
76
78
|
ret = result.chunk;
|
|
77
79
|
post = result.post;
|
|
@@ -99,14 +101,18 @@ class ValueBodyTranspiler {
|
|
|
99
101
|
throw new Error("ValueBodyTranspiler, unknown " + child.get().constructor.name + " \"" + child.concatTokens()) + "\"";
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
|
|
104
|
+
ret.appendString(post);
|
|
105
|
+
if (outerLetCode !== undefined && hasFor === false) {
|
|
106
|
+
// without FOR the LET bindings are declared here, in a scope of their own, before the value is built
|
|
107
|
+
ret = new chunk_1.Chunk().appendString(`(await (async () => { ${outerLetCode} return ${ret.getCode()}; })())`);
|
|
108
|
+
}
|
|
109
|
+
return ret;
|
|
103
110
|
}
|
|
104
111
|
buildForChain(forNodes, typ, traversal, body, baseCode, outerLetCode) {
|
|
105
112
|
const val = baseCode ?? new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
|
|
106
113
|
const chunk = new chunk_1.Chunk();
|
|
107
114
|
const preLoopDecls = outerLetCode === undefined ? [] : [outerLetCode];
|
|
108
115
|
const descriptors = [];
|
|
109
|
-
const levelIndents = [];
|
|
110
116
|
let uniqueCounter = 1;
|
|
111
117
|
for (const child of forNodes) {
|
|
112
118
|
const loop = child.findDirectExpression(core_1.Expressions.InlineLoopDefinition);
|
|
@@ -222,11 +228,11 @@ class ValueBodyTranspiler {
|
|
|
222
228
|
letCode = new let_1.LetTranspiler().transpile(llet, traversal).getCode();
|
|
223
229
|
}
|
|
224
230
|
const condCode = traversal.traverse(cond).getCode();
|
|
225
|
-
const preCheck = hasWhile ? `if (!(${condCode})) {\
|
|
231
|
+
const preCheck = hasWhile ? `if (!(${condCode})) {\nbreak;\n}` : "";
|
|
226
232
|
const postLoop = [];
|
|
227
233
|
postLoop.push(incrementLine);
|
|
228
234
|
if (hasUntil) {
|
|
229
|
-
postLoop.push(`if (${condCode}) {\
|
|
235
|
+
postLoop.push(`if (${condCode}) {\nbreak;\n}`);
|
|
230
236
|
}
|
|
231
237
|
descriptors.push({
|
|
232
238
|
beforeLoop: [declare, `${counterName}.set(${start});`],
|
|
@@ -241,34 +247,31 @@ class ValueBodyTranspiler {
|
|
|
241
247
|
throw new Error("ValueBodyTranspiler FOR internal error");
|
|
242
248
|
}
|
|
243
249
|
chunk.appendString("await (async () => {\n");
|
|
244
|
-
this.appendBlocks(chunk, preLoopDecls
|
|
250
|
+
this.appendBlocks(chunk, preLoopDecls);
|
|
245
251
|
chunk.appendString(`const VAL = ${val};\n`);
|
|
246
|
-
|
|
252
|
+
// no manual indentation, Chunk.runIndentationLogic indents by brace depth,
|
|
253
|
+
// pre-indented closing braces would not be recognized and drift the indentation
|
|
247
254
|
for (const desc of descriptors) {
|
|
248
|
-
this.appendBlocks(chunk, desc.beforeLoop
|
|
249
|
-
chunk.appendString(
|
|
250
|
-
|
|
251
|
-
levelIndents.push(indent);
|
|
252
|
-
this.appendBlocks(chunk, desc.preBody, indent);
|
|
255
|
+
this.appendBlocks(chunk, desc.beforeLoop);
|
|
256
|
+
chunk.appendString(desc.open + "\n");
|
|
257
|
+
this.appendBlocks(chunk, desc.preBody);
|
|
253
258
|
}
|
|
254
|
-
chunk.appendString(
|
|
259
|
+
chunk.appendString("VAL");
|
|
255
260
|
let post = ";\n";
|
|
256
261
|
for (let i = descriptors.length - 1; i >= 0; i--) {
|
|
257
262
|
const desc = descriptors[i];
|
|
258
|
-
|
|
259
|
-
post +=
|
|
260
|
-
const parentIndent = currentIndent.substring(0, Math.max(0, currentIndent.length - 2));
|
|
261
|
-
post += parentIndent + desc.close + "\n";
|
|
263
|
+
post += this.blocksToString(desc.postBody);
|
|
264
|
+
post += desc.close + "\n";
|
|
262
265
|
}
|
|
263
266
|
post += "return VAL;\n})()";
|
|
264
267
|
return { chunk, post };
|
|
265
268
|
}
|
|
266
|
-
appendBlocks(chunk, blocks
|
|
269
|
+
appendBlocks(chunk, blocks) {
|
|
267
270
|
for (const block of blocks) {
|
|
268
|
-
this.appendBlock(chunk, block
|
|
271
|
+
this.appendBlock(chunk, block);
|
|
269
272
|
}
|
|
270
273
|
}
|
|
271
|
-
appendBlock(chunk, block
|
|
274
|
+
appendBlock(chunk, block) {
|
|
272
275
|
if (block === "") {
|
|
273
276
|
return;
|
|
274
277
|
}
|
|
@@ -278,10 +281,10 @@ class ValueBodyTranspiler {
|
|
|
278
281
|
if (clean.trim() === "") {
|
|
279
282
|
continue;
|
|
280
283
|
}
|
|
281
|
-
chunk.appendString(
|
|
284
|
+
chunk.appendString(clean + "\n");
|
|
282
285
|
}
|
|
283
286
|
}
|
|
284
|
-
blocksToString(blocks
|
|
287
|
+
blocksToString(blocks) {
|
|
285
288
|
let ret = "";
|
|
286
289
|
for (const block of blocks) {
|
|
287
290
|
if (block === "") {
|
|
@@ -293,7 +296,7 @@ class ValueBodyTranspiler {
|
|
|
293
296
|
if (clean.trim() === "") {
|
|
294
297
|
continue;
|
|
295
298
|
}
|
|
296
|
-
ret +=
|
|
299
|
+
ret += clean + "\n";
|
|
297
300
|
}
|
|
298
301
|
}
|
|
299
302
|
return ret;
|
|
@@ -43,15 +43,16 @@ class AssignTranspiler {
|
|
|
43
43
|
if (node?.findFirstExpression(abaplint.Expressions.TableExpression) === undefined) {
|
|
44
44
|
return code;
|
|
45
45
|
}
|
|
46
|
+
// not indented, Chunk.runIndentationLogic indents by brace depth
|
|
46
47
|
return `(await (async () => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
try {
|
|
49
|
+
return ${code};
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if (abap.isLineNotFound(error)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
55
56
|
})())`;
|
|
56
57
|
}
|
|
57
58
|
transpile(node, traversal) {
|
|
@@ -145,7 +145,7 @@ class CallTranspiler {
|
|
|
145
145
|
post += `\nabap.builtin.sy.get().subrc.set(0);
|
|
146
146
|
} catch (e) {
|
|
147
147
|
if (e.classic) {
|
|
148
|
-
|
|
148
|
+
switch (e.classic.toUpperCase()) {\n`;
|
|
149
149
|
for (const e of node.findAllExpressions(abaplint.Expressions.ParameterException)) {
|
|
150
150
|
const name = e.getFirstToken().getStr().toUpperCase();
|
|
151
151
|
// todo, also handle SimpleChain,
|
|
@@ -164,9 +164,9 @@ if (e.classic) {
|
|
|
164
164
|
post += `case "${name}": abap.builtin.sy.get().subrc.set(${value}); break;\n`;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
-
post += `
|
|
167
|
+
post += `}
|
|
168
168
|
} else {
|
|
169
|
-
|
|
169
|
+
throw e;
|
|
170
170
|
}
|
|
171
171
|
}`;
|
|
172
172
|
return { pre, post };
|
|
@@ -65,12 +65,13 @@ class CallFunctionTranspiler {
|
|
|
65
65
|
}
|
|
66
66
|
const calling = node.findExpressionAfterToken("CALLING");
|
|
67
67
|
const dest = node.findDirectExpression(abaplint.Expressions.Destination)?.findDirectExpression(abaplint.Expressions.Source);
|
|
68
|
-
|
|
68
|
+
const updateTask = node.findDirectTokenByText("UPDATE") !== undefined;
|
|
69
|
+
if (dest && updateTask === false) {
|
|
69
70
|
const s = new expressions_1.SourceTranspiler(true).transpile(dest, traversal);
|
|
70
71
|
param = param.replace("{", ",").replace(/}$/, "");
|
|
71
72
|
ret.appendString(`await abap.statements.callFunction({name:${fmname},destination:${s.getCode()}${param}});`);
|
|
72
73
|
}
|
|
73
|
-
else if (calling) {
|
|
74
|
+
else if (calling && updateTask === false) {
|
|
74
75
|
param = param.replace("{", ",").replace(/}$/, "");
|
|
75
76
|
// typically used in combination with STARTING NEW TASK so dont await,
|
|
76
77
|
ret.appendString(`abap.statements.callFunction({name:${fmname},calling:this.${calling.concatTokens().toLowerCase()}${param}});`);
|
|
@@ -80,7 +81,13 @@ class CallFunctionTranspiler {
|
|
|
80
81
|
const call = `abap.FunctionModules[${fmname}]`;
|
|
81
82
|
// eslint-disable-next-line max-len
|
|
82
83
|
ret.appendString(`if (${call} === undefined) { if (${illegalFunc} === undefined) { throw "CX_SY_DYN_CALL_ILLEGAL_FUNC not found"; } else { throw await new ${illegalFunc}().constructor_({function: new abap.types.String().set(${fmname})});} }\n`);
|
|
83
|
-
|
|
84
|
+
if (updateTask) {
|
|
85
|
+
param = param.replace("{", ",").replace(/}$/, "");
|
|
86
|
+
ret.appendString(`await abap.statements.callFunction({name:${fmname},updateTask:true${param}});`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
ret.appendString(`await ${call}(${param});`);
|
|
90
|
+
}
|
|
84
91
|
}
|
|
85
92
|
if (exceptions) {
|
|
86
93
|
const build = call_1.CallTranspiler.buildExceptions(exceptions);
|
|
@@ -83,7 +83,7 @@ class CreateDataTranspiler {
|
|
|
83
83
|
}
|
|
84
84
|
const handle = node.findExpressionAfterToken("HANDLE");
|
|
85
85
|
if (handle) {
|
|
86
|
-
const so = traversal.traverse(
|
|
86
|
+
const so = traversal.traverse(handle);
|
|
87
87
|
const lookup = traversal.lookupClassOrInterface("KERNEL_CREATE_DATA_HANDLE", node.getFirstToken());
|
|
88
88
|
const call = `await ${lookup}.call({handle: ${so.getCode()}, dref: ${target.getCode()}});`;
|
|
89
89
|
return new chunk_1.Chunk().append(`if (${lookup} === undefined) throw new Error("CreateData, kernel class missing");\n${call}`, node, traversal);
|
|
@@ -3,5 +3,7 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class GenerateSubroutineTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
|
+
/** the expression directly after the addition keyword, MESSAGE does not match MESSAGE-ID */
|
|
8
|
+
private findAddition;
|
|
7
9
|
}
|
|
@@ -1,10 +1,80 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.GenerateSubroutineTranspiler = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
4
38
|
const chunk_1 = require("../chunk");
|
|
39
|
+
// GENERATE SUBROUTINE POOL cannot be supported, there is no compiler at runtime.
|
|
40
|
+
// The statement is refused without an exception: sy-subrc = 8 (documented as "other
|
|
41
|
+
// generation error"), NAME initial, MESSAGE filled, LINE 0 and WORD initial. This is
|
|
42
|
+
// a refusal of its own, not what a system answers; the other additions are left untouched.
|
|
5
43
|
class GenerateSubroutineTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
44
|
+
transpile(node, traversal) {
|
|
45
|
+
const ret = new chunk_1.Chunk();
|
|
46
|
+
const name = this.findAddition(node, "NAME");
|
|
47
|
+
if (name) {
|
|
48
|
+
ret.appendString(traversal.traverse(name).getCode() + ".clear();\n");
|
|
49
|
+
}
|
|
50
|
+
const message = this.findAddition(node, "MESSAGE");
|
|
51
|
+
if (message) {
|
|
52
|
+
ret.appendString(traversal.traverse(message).getCode() + `.set("GENERATE SUBROUTINE POOL is not supported");\n`);
|
|
53
|
+
}
|
|
54
|
+
const line = this.findAddition(node, "LINE");
|
|
55
|
+
if (line) {
|
|
56
|
+
ret.appendString(traversal.traverse(line).getCode() + ".set(0);\n");
|
|
57
|
+
}
|
|
58
|
+
const word = this.findAddition(node, "WORD");
|
|
59
|
+
if (word) {
|
|
60
|
+
ret.appendString(traversal.traverse(word).getCode() + ".clear();\n");
|
|
61
|
+
}
|
|
62
|
+
ret.append("abap.builtin.sy.get().subrc.set(8);", node, traversal);
|
|
63
|
+
return ret;
|
|
64
|
+
}
|
|
65
|
+
/** the expression directly after the addition keyword, MESSAGE does not match MESSAGE-ID */
|
|
66
|
+
findAddition(node, keyword) {
|
|
67
|
+
const children = node.getChildren();
|
|
68
|
+
for (let i = 0; i < children.length - 1; i++) {
|
|
69
|
+
const child = children[i];
|
|
70
|
+
const next = children[i + 1];
|
|
71
|
+
if (child instanceof abaplint.Nodes.TokenNode
|
|
72
|
+
&& child.getFirstToken().getStr().toUpperCase() === keyword
|
|
73
|
+
&& next instanceof abaplint.Nodes.ExpressionNode) {
|
|
74
|
+
return next;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
8
78
|
}
|
|
9
79
|
}
|
|
10
80
|
exports.GenerateSubroutineTranspiler = GenerateSubroutineTranspiler;
|
|
@@ -4,4 +4,6 @@ import { Traversal } from "../traversal";
|
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class MoveTranspiler implements IStatementTranspiler {
|
|
6
6
|
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
|
+
private isInt8Calculation;
|
|
8
|
+
private integerOperands;
|
|
7
9
|
}
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.MoveTranspiler = void 0;
|
|
37
37
|
const abaplint = __importStar(require("@abaplint/core"));
|
|
38
38
|
const chunk_1 = require("../chunk");
|
|
39
|
+
const source_1 = require("../expressions/source");
|
|
39
40
|
class MoveTranspiler {
|
|
40
41
|
transpile(node, traversal) {
|
|
41
42
|
const sourceExpression = node.findDirectExpression(abaplint.Expressions.Source);
|
|
@@ -55,7 +56,9 @@ class MoveTranspiler {
|
|
|
55
56
|
ret.appendString(target + `.set(abap.alphaIn(${tSource.getCode()}, ${target}, ${target}));`);
|
|
56
57
|
return ret;
|
|
57
58
|
}
|
|
58
|
-
let source =
|
|
59
|
+
let source = this.isInt8Calculation(node, sourceExpression, targetExpressions.length, traversal)
|
|
60
|
+
? new source_1.SourceTranspiler(false, true).transpile(sourceExpression, traversal)
|
|
61
|
+
: traversal.traverse(sourceExpression);
|
|
59
62
|
const second = node.getChildren()[1]?.concatTokens();
|
|
60
63
|
switch (second) {
|
|
61
64
|
case "?=":
|
|
@@ -117,6 +120,72 @@ class MoveTranspiler {
|
|
|
117
120
|
}
|
|
118
121
|
return ret;
|
|
119
122
|
}
|
|
123
|
+
// The calculation type of an arithmetic expression comes from its operands and the target
|
|
124
|
+
// field, the type with the largest range wins. With operands of type i or int8 it is int8
|
|
125
|
+
// when the target or an operand is int8: i * i into int8 is exact up to 2^62, and "/"
|
|
126
|
+
// rounds. The runtime decides by the operands alone and does not know the target, so here
|
|
127
|
+
// the operands are converted to int8 before the calculation. Only for an i or int8 target
|
|
128
|
+
// and operands whose type is known to be i or int8, and not for **, which counts as f
|
|
129
|
+
isInt8Calculation(node, source, targets, traversal) {
|
|
130
|
+
if (source === undefined
|
|
131
|
+
|| targets !== 1
|
|
132
|
+
|| source.findFirstExpression(abaplint.Expressions.ArithOperator) === undefined) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const scope = traversal.findCurrentScopeByToken(node.getFirstToken());
|
|
136
|
+
const target = traversal.determineType(node, scope);
|
|
137
|
+
const found = { int8: target instanceof abaplint.BasicTypes.Integer8Type };
|
|
138
|
+
if (found.int8 === false && !(target instanceof abaplint.BasicTypes.IntegerType)) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return this.integerOperands(source, scope, found) && found.int8;
|
|
142
|
+
}
|
|
143
|
+
integerOperands(node, scope, found) {
|
|
144
|
+
for (const c of node.getChildren()) {
|
|
145
|
+
if (c instanceof abaplint.Nodes.TokenNode) {
|
|
146
|
+
if (["(", ")", "-", "+"].includes(c.getFirstToken().getStr()) === false) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (c.get() instanceof abaplint.Expressions.Source) {
|
|
151
|
+
if (this.integerOperands(c, scope, found) === false) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (c.get() instanceof abaplint.Expressions.ArithOperator) {
|
|
156
|
+
if (["+", "-", "*", "/", "DIV", "MOD"].includes(c.concatTokens().toUpperCase()) === false) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (c.get() instanceof abaplint.Expressions.Constant) {
|
|
161
|
+
const integer = c.findDirectExpression(abaplint.Expressions.Integer);
|
|
162
|
+
if (integer === undefined) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
else if (Math.abs(parseInt(integer.concatTokens().replace(/ /g, ""), 10)) > 2147483647) {
|
|
166
|
+
// the transpiler makes an int8 of a literal outside the range of i
|
|
167
|
+
found.int8 = true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else if (c.get() instanceof abaplint.Expressions.FieldChain) {
|
|
171
|
+
const children = c.getChildren();
|
|
172
|
+
if (children.length !== 1) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
const type = scope?.findVariable(children[0].concatTokens())?.getType();
|
|
176
|
+
if (!(type instanceof abaplint.BasicTypes.IntegerType) && !(type instanceof abaplint.BasicTypes.Integer8Type)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
if (type instanceof abaplint.BasicTypes.Integer8Type) {
|
|
180
|
+
found.int8 = true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
120
189
|
}
|
|
121
190
|
exports.MoveTranspiler = MoveTranspiler;
|
|
122
191
|
//# sourceMappingURL=move.js.map
|
|
@@ -44,16 +44,18 @@ class PerformTranspiler {
|
|
|
44
44
|
return new chunk_1.Chunk(`throw new Error("PerformTranspiler FormName not found");`);
|
|
45
45
|
}
|
|
46
46
|
else if (node.concatTokens().toUpperCase().includes(" IN PROGRAM ")) {
|
|
47
|
-
// todo: throw exception if not found?
|
|
48
47
|
const expression = node.findExpressionAfterToken("PROGRAM");
|
|
49
48
|
let ref = "";
|
|
49
|
+
let program = "";
|
|
50
50
|
if (expression?.get() instanceof abaplint.Expressions.Dynamic) {
|
|
51
51
|
const name = expression.getChildren()[1].concatTokens() + ".get().trimEnd()";
|
|
52
52
|
ref = `abap.Forms['PROG-' + ${name} + '-${formName.concatTokens().toUpperCase()}']`;
|
|
53
|
+
program = `'PROG-' + ${name} + '-'`;
|
|
53
54
|
}
|
|
54
55
|
else {
|
|
55
56
|
const progName = expression?.concatTokens().toUpperCase();
|
|
56
57
|
ref = `abap.Forms['PROG-${progName}-${formName.concatTokens().toUpperCase()}']`;
|
|
58
|
+
program = `'PROG-${progName}-'`;
|
|
57
59
|
}
|
|
58
60
|
const params = [];
|
|
59
61
|
// hacky hack
|
|
@@ -65,6 +67,16 @@ class PerformTranspiler {
|
|
|
65
67
|
if (node.concatTokens().toUpperCase().includes(" IF FOUND")) {
|
|
66
68
|
call = `if (${ref} !== undefined) { ${call} }`;
|
|
67
69
|
}
|
|
70
|
+
else {
|
|
71
|
+
// the form is missing from a program whose forms are registered: CX_SY_DYN_CALL_ILLEGAL_FORM,
|
|
72
|
+
// no form of the program is registered: CX_SY_PROGRAM_NOT_FOUND
|
|
73
|
+
const raise = (name) => {
|
|
74
|
+
const cls = traversal.lookupClassOrInterface(`'${name}'`, node.getFirstToken(), true);
|
|
75
|
+
return `if (${cls} === undefined) { throw "${name} not found"; } else { throw await new ${cls}().constructor_(); }`;
|
|
76
|
+
};
|
|
77
|
+
const loaded = `Object.keys(abap.Forms).some(k => k.startsWith(${program}))`;
|
|
78
|
+
call = `if (${ref} === undefined) { if (${loaded}) { ${raise("CX_SY_DYN_CALL_ILLEGAL_FORM")} } else { ${raise("CX_SY_PROGRAM_NOT_FOUND")} } }\n` + call;
|
|
79
|
+
}
|
|
68
80
|
return new chunk_1.Chunk(call);
|
|
69
81
|
}
|
|
70
82
|
else {
|
|
@@ -184,24 +184,25 @@ class SelectTranspiler {
|
|
|
184
184
|
// DB key alone is wrong for projections (INTO CORRESPONDING FIELDS
|
|
185
185
|
// without the key fields crashed on the missing component names)
|
|
186
186
|
const by = `Object.keys(${target}.getRowType().get())`;
|
|
187
|
+
// generated code is not indented, Chunk.runIndentationLogic indents by brace depth
|
|
187
188
|
const dedup = `if (!(${target} instanceof abap.types.HashedTable) && ${target}.getOptions()?.primaryKey?.type !== "SORTED") {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
abap.statements.sort(${target}, {by: ${by}.map(k => { return {component: k}; })});
|
|
190
|
+
await abap.statements.deleteInternal(${target}, {adjacent: true, allFields: true});
|
|
191
|
+
}`;
|
|
191
192
|
const at = where.startsWith("WHERE ") ? select.indexOf(where) : -1;
|
|
192
193
|
// UP TO with ORDER BY keeps the first n rows in that order; the blocks
|
|
193
194
|
// trim after the de-duplicating sort, so that pair stays row by row
|
|
194
195
|
if (concat.startsWith("SELECT SINGLE ") || at < 0 || (upTo && orderBy)) {
|
|
195
196
|
const code = `if (${faeTranspiled}.array().length === 0) {
|
|
196
|
-
|
|
197
|
+
await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
|
|
197
198
|
} else {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
const ${unique2} = ${faeTranspiled}.array();
|
|
200
|
+
${target}.clear();
|
|
201
|
+
for await (const ${unique} of ${unique2}) {
|
|
202
|
+
await abap.statements.select(${target}, {select: "${select.trim()}"${extra}}, {appending: true});
|
|
203
|
+
}
|
|
204
|
+
${dedup}
|
|
205
|
+
abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
205
206
|
}`;
|
|
206
207
|
return new chunk_1.Chunk().append(code, node, traversal);
|
|
207
208
|
}
|
|
@@ -229,29 +230,29 @@ class SelectTranspiler {
|
|
|
229
230
|
const unique3 = unique_identifier_1.UniqueIdentifier.get();
|
|
230
231
|
const unique4 = unique_identifier_1.UniqueIdentifier.get();
|
|
231
232
|
const code = `if (${faeTranspiled}.array().length === 0) {
|
|
232
|
-
|
|
233
|
+
await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
|
|
234
|
+
} else {
|
|
235
|
+
const ${unique2} = ${faeTranspiled}.array();
|
|
236
|
+
${target}.clear();
|
|
237
|
+
const ${unique3} = (${unique}) => "(${condition})";
|
|
238
|
+
for (let ${unique4} = 0; ${unique4} < ${unique2}.length; ${unique4} += 50) {
|
|
239
|
+
const ${unique4}where = ${unique2}.slice(${unique4}, ${unique4} + 50).map(${unique3}).join(" OR ");
|
|
240
|
+
await abap.statements.select(${target}, {select: "${head}WHERE " + ${unique4}where + " ${tail.trim()}"${extra}}, {appending: true});
|
|
241
|
+
}
|
|
242
|
+
${dedup}
|
|
243
|
+
const ${unique4}max = ${upToCode};
|
|
244
|
+
if (${unique4}max > 0 && ${target}.getArrayLength() > ${unique4}max) {
|
|
245
|
+
if (${target} instanceof abap.types.HashedTable) {
|
|
246
|
+
for (const ${unique4}row of ${target}.array().slice(${unique4}max)) {
|
|
247
|
+
await abap.statements.deleteInternal(${target}, {fromValue: ${unique4}row});
|
|
248
|
+
}
|
|
233
249
|
} else {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
${dedup}
|
|
242
|
-
const ${unique4}max = ${upToCode};
|
|
243
|
-
if (${unique4}max > 0 && ${target}.getArrayLength() > ${unique4}max) {
|
|
244
|
-
if (${target} instanceof abap.types.HashedTable) {
|
|
245
|
-
for (const ${unique4}row of ${target}.array().slice(${unique4}max)) {
|
|
246
|
-
await abap.statements.deleteInternal(${target}, {fromValue: ${unique4}row});
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
while (${target}.getArrayLength() > ${unique4}max) {
|
|
250
|
-
${target}.deleteIndex(${target}.getArrayLength() - 1);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
250
|
+
while (${target}.getArrayLength() > ${unique4}max) {
|
|
251
|
+
${target}.deleteIndex(${target}.getArrayLength() - 1);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
255
256
|
}`;
|
|
256
257
|
return new chunk_1.Chunk().append(code, node, traversal);
|
|
257
258
|
}
|
|
@@ -4,5 +4,7 @@ import { Traversal } from "../traversal";
|
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class SortTranspiler implements IStatementTranspiler {
|
|
6
6
|
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
|
+
private isDynamicName;
|
|
8
|
+
private dynamicName;
|
|
7
9
|
private findNextText;
|
|
8
10
|
}
|
|
@@ -40,7 +40,8 @@ const expressions_1 = require("../expressions");
|
|
|
40
40
|
class SortTranspiler {
|
|
41
41
|
transpile(node, traversal) {
|
|
42
42
|
const concat = node.concatTokens().toUpperCase();
|
|
43
|
-
const components = node.
|
|
43
|
+
const components = node.getChildren().filter(c => c instanceof abaplint.Nodes.ExpressionNode
|
|
44
|
+
&& (c.get() instanceof abaplint.Expressions.ComponentChain || this.isDynamicName(c, traversal)));
|
|
44
45
|
const options = [];
|
|
45
46
|
if (concat.includes(" BY ") === false) {
|
|
46
47
|
const descending = node.findDirectTokenByText("DESCENDING") !== undefined;
|
|
@@ -52,12 +53,14 @@ class SortTranspiler {
|
|
|
52
53
|
const by = [];
|
|
53
54
|
for (const c of components) {
|
|
54
55
|
const next = this.findNextText(c, node);
|
|
55
|
-
const
|
|
56
|
+
const component = c.get() instanceof abaplint.Expressions.Dynamic
|
|
57
|
+
? this.dynamicName(c, traversal)
|
|
58
|
+
: `"${expressions_1.ComponentChainTranspiler.concat(c, traversal)}"`;
|
|
56
59
|
if (next === "DESCENDING") {
|
|
57
|
-
by.push(`{component:
|
|
60
|
+
by.push(`{component: ${component}, descending: true}`);
|
|
58
61
|
}
|
|
59
62
|
else {
|
|
60
|
-
by.push(`{component:
|
|
63
|
+
by.push(`{component: ${component}}`);
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
options.push(`by: [${by.join(",")}]`);
|
|
@@ -65,6 +68,32 @@ class SortTranspiler {
|
|
|
65
68
|
const target = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Target)).getCode();
|
|
66
69
|
return new chunk_1.Chunk().append("abap.statements.sort(" + target + ",{" + options.join(",") + "});", node, traversal);
|
|
67
70
|
}
|
|
71
|
+
// "BY (name)" with the component name in a literal or a character-like field; a sort order table
|
|
72
|
+
// (abap_sortorder_tab) is not handled here
|
|
73
|
+
isDynamicName(c, traversal) {
|
|
74
|
+
if (!(c.get() instanceof abaplint.Expressions.Dynamic)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (c.findFirstExpression(abaplint.Expressions.ConstantString)) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
const field = c.findFirstExpression(abaplint.Expressions.FieldChain);
|
|
81
|
+
if (field === undefined) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const token = field.getFirstToken();
|
|
85
|
+
const type = traversal.findCurrentScopeByToken(token)?.findVariable(token.getStr())?.getType();
|
|
86
|
+
return !(type instanceof abaplint.BasicTypes.TableType);
|
|
87
|
+
}
|
|
88
|
+
dynamicName(c, traversal) {
|
|
89
|
+
const constant = c.findFirstExpression(abaplint.Expressions.ConstantString);
|
|
90
|
+
if (constant) {
|
|
91
|
+
const str = constant.getFirstToken().getStr();
|
|
92
|
+
return JSON.stringify(str.substring(1, str.length - 1).toLowerCase().trimEnd());
|
|
93
|
+
}
|
|
94
|
+
const field = c.findFirstExpression(abaplint.Expressions.FieldChain);
|
|
95
|
+
return new expressions_1.FieldChainTranspiler(true).transpile(field, traversal).getCode() + ".toLowerCase().trimEnd()";
|
|
96
|
+
}
|
|
68
97
|
findNextText(c, parent) {
|
|
69
98
|
const children = parent.getChildren();
|
|
70
99
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -52,17 +52,18 @@ class ClassDefinitionTranspiler {
|
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
54
|
// its an abstract class with only abstract methods
|
|
55
|
+
// not indented, Chunk.runIndentationLogic indents by brace depth
|
|
55
56
|
return new chunk_1.Chunk(`
|
|
56
57
|
class ${className?.toLowerCase()} {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
static INTERNAL_TYPE = 'CLAS';
|
|
59
|
+
static IMPLEMENTED_INTERFACES = [];
|
|
60
|
+
static INTERNAL_NAME = 'ABSTRACT_CLASS_INTERNAL_NAME';
|
|
61
|
+
static ATTRIBUTES = {};
|
|
62
|
+
async constructor_() {
|
|
63
|
+
this.me = new abap.types.ABAPObject();
|
|
64
|
+
this.me.set(this);
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
66
67
|
}`);
|
|
67
68
|
}
|
|
68
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.98",
|
|
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.66",
|
|
33
33
|
"source-map": "^0.8.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|