@abaplint/transpiler 2.13.95 → 2.13.97
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/db/schema_generation/pg_database_schema.js +3 -0
- package/build/src/db/schema_generation/snowflake_database_schema.js +3 -0
- package/build/src/db/schema_generation/sqlite_database_schema.js +3 -0
- 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/sql_cond.d.ts +1 -0
- package/build/src/expressions/sql_cond.js +15 -3
- package/build/src/expressions/value_body.js +25 -22
- package/build/src/statements/_dataset.d.ts +17 -0
- package/build/src/statements/_dataset.js +82 -0
- package/build/src/statements/_selection.d.ts +18 -0
- package/build/src/statements/_selection.js +82 -0
- 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/close_dataset.d.ts +1 -1
- package/build/src/statements/close_dataset.js +40 -2
- package/build/src/statements/create_data.js +1 -1
- package/build/src/statements/delete_dataset.d.ts +1 -1
- package/build/src/statements/delete_dataset.js +40 -2
- package/build/src/statements/generate_subroutine.d.ts +3 -1
- package/build/src/statements/generate_subroutine.js +72 -2
- package/build/src/statements/get_dataset.d.ts +1 -1
- package/build/src/statements/get_dataset.js +14 -2
- package/build/src/statements/loop.d.ts +1 -0
- package/build/src/statements/loop.js +12 -0
- package/build/src/statements/move.d.ts +2 -0
- package/build/src/statements/move.js +70 -1
- package/build/src/statements/open_dataset.d.ts +1 -1
- package/build/src/statements/open_dataset.js +32 -2
- package/build/src/statements/parameter.d.ts +2 -1
- package/build/src/statements/parameter.js +68 -2
- package/build/src/statements/perform.js +13 -1
- package/build/src/statements/read_dataset.d.ts +1 -1
- package/build/src/statements/read_dataset.js +16 -2
- package/build/src/statements/select.js +78 -13
- package/build/src/statements/select_option.d.ts +1 -1
- package/build/src/statements/select_option.js +63 -2
- package/build/src/statements/set_dataset.d.ts +1 -1
- package/build/src/statements/set_dataset.js +10 -2
- package/build/src/statements/sort.d.ts +2 -0
- package/build/src/statements/sort.js +33 -4
- package/build/src/statements/transfer.d.ts +1 -1
- package/build/src/statements/transfer.js +14 -2
- package/build/src/structures/class_definition.js +10 -9
- package/package.json +2 -2
|
@@ -1,10 +1,48 @@
|
|
|
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.CloseDatasetTranspiler = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
4
38
|
const chunk_1 = require("../chunk");
|
|
5
39
|
class CloseDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
40
|
+
transpile(node, traversal) {
|
|
41
|
+
const name = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Source)).getCode();
|
|
42
|
+
return new chunk_1.Chunk()
|
|
43
|
+
.append("await abap.statements.closeDataset(", node, traversal)
|
|
44
|
+
.appendString(name)
|
|
45
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
46
|
}
|
|
9
47
|
}
|
|
10
48
|
exports.CloseDatasetTranspiler = CloseDatasetTranspiler;
|
|
@@ -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,5 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class DeleteDatasetTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -1,10 +1,48 @@
|
|
|
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.DeleteDatasetTranspiler = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
4
38
|
const chunk_1 = require("../chunk");
|
|
5
39
|
class DeleteDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
40
|
+
transpile(node, traversal) {
|
|
41
|
+
const name = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Source)).getCode();
|
|
42
|
+
return new chunk_1.Chunk()
|
|
43
|
+
.append("await abap.statements.deleteDataset(", node, traversal)
|
|
44
|
+
.appendString(name)
|
|
45
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
46
|
}
|
|
9
47
|
}
|
|
10
48
|
exports.DeleteDatasetTranspiler = DeleteDatasetTranspiler;
|
|
@@ -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;
|
|
@@ -3,5 +3,5 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class GetDatasetTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -2,9 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GetDatasetTranspiler = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const _dataset_1 = require("./_dataset");
|
|
5
6
|
class GetDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
7
|
+
transpile(node, traversal) {
|
|
8
|
+
const operands = new _dataset_1.DatasetOperands(node, traversal);
|
|
9
|
+
const options = [];
|
|
10
|
+
if (operands.after("POSITION") !== undefined) {
|
|
11
|
+
options.push("position: " + operands.after("POSITION"));
|
|
12
|
+
}
|
|
13
|
+
if (operands.after("ATTRIBUTES") !== undefined) {
|
|
14
|
+
options.push("attributes: " + operands.after("ATTRIBUTES"));
|
|
15
|
+
}
|
|
16
|
+
return new chunk_1.Chunk()
|
|
17
|
+
.append("await abap.statements.getDataset(", node, traversal)
|
|
18
|
+
.appendString(operands.first() + ", {" + options.join(", ") + "}")
|
|
19
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
20
|
}
|
|
9
21
|
}
|
|
10
22
|
exports.GetDatasetTranspiler = GetDatasetTranspiler;
|
|
@@ -94,6 +94,10 @@ class LoopTranspiler {
|
|
|
94
94
|
targetNode = assigning;
|
|
95
95
|
target = traversal.traverse(assigning).getCode() + ".assign(" + this.unique + ");";
|
|
96
96
|
}
|
|
97
|
+
else if (!node.concatTokens().toUpperCase().includes(" TRANSPORTING NO FIELDS") && this.hasHeaderLine(loopSource, traversal)) {
|
|
98
|
+
// LOOP AT itab. without a target: the row goes into the header line of the table
|
|
99
|
+
target = source + ".getHeader().set(" + this.unique + ");";
|
|
100
|
+
}
|
|
97
101
|
}
|
|
98
102
|
const extra = [];
|
|
99
103
|
const fromNode = node.findExpressionAfterToken("FROM");
|
|
@@ -188,6 +192,14 @@ class LoopTranspiler {
|
|
|
188
192
|
}
|
|
189
193
|
return ret;
|
|
190
194
|
}
|
|
195
|
+
hasHeaderLine(loopSource, traversal) {
|
|
196
|
+
if (loopSource === undefined || /^[\w\/]+$/.test(loopSource.concatTokens()) === false) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
const token = loopSource.getFirstToken();
|
|
200
|
+
const type = traversal.findCurrentScopeByToken(token)?.findVariable(loopSource.concatTokens())?.getType();
|
|
201
|
+
return type instanceof abaplint.BasicTypes.TableType && type.isWithHeader();
|
|
202
|
+
}
|
|
191
203
|
}
|
|
192
204
|
exports.LoopTranspiler = LoopTranspiler;
|
|
193
205
|
//# sourceMappingURL=loop.js.map
|
|
@@ -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
|
|
@@ -3,5 +3,5 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class OpenDatasetTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -2,9 +2,39 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OpenDatasetTranspiler = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const _dataset_1 = require("./_dataset");
|
|
5
6
|
class OpenDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
7
|
+
transpile(node, traversal) {
|
|
8
|
+
const operands = new _dataset_1.DatasetOperands(node, traversal);
|
|
9
|
+
const options = [];
|
|
10
|
+
const mode = ["INPUT", "OUTPUT", "APPENDING", "UPDATE"].find(m => operands.has("FOR " + m)) ?? "INPUT";
|
|
11
|
+
options.push(`mode: "${mode}"`);
|
|
12
|
+
options.push(`binary: ${operands.has("BINARY MODE")}`);
|
|
13
|
+
const encoding = ["DEFAULT", "UTF-8", "NON-UNICODE"].find(e => operands.has("ENCODING " + e));
|
|
14
|
+
if (encoding !== undefined) {
|
|
15
|
+
options.push(`encoding: "${encoding}"`);
|
|
16
|
+
}
|
|
17
|
+
if (operands.has("IN LEGACY")) {
|
|
18
|
+
options.push("legacy: true");
|
|
19
|
+
}
|
|
20
|
+
if (operands.after("MESSAGE") !== undefined) {
|
|
21
|
+
options.push("message: " + operands.after("MESSAGE"));
|
|
22
|
+
}
|
|
23
|
+
if (operands.after("AT POSITION") !== undefined) {
|
|
24
|
+
options.push("position: " + operands.after("AT POSITION"));
|
|
25
|
+
}
|
|
26
|
+
// accepted by the syntax, not implemented by the runtime: it refuses them
|
|
27
|
+
// by name rather than ignoring them
|
|
28
|
+
const unsupported = ["CODE PAGE", "TYPE", "FILTER", "REPLACEMENT CHARACTER", "WITH BYTE-ORDER MARK", "SKIPPING BYTE-ORDER MARK",
|
|
29
|
+
"WITH SMART LINEFEED", "WITH NATIVE LINEFEED", "WITH UNIX LINEFEED", "WITH WINDOWS LINEFEED", "IGNORING CONVERSION ERRORS"]
|
|
30
|
+
.filter(u => operands.has(u) || operands.after(u) !== undefined);
|
|
31
|
+
if (unsupported.length > 0) {
|
|
32
|
+
options.push("unsupported: " + JSON.stringify(unsupported));
|
|
33
|
+
}
|
|
34
|
+
return new chunk_1.Chunk()
|
|
35
|
+
.append("await abap.statements.openDataset(", node, traversal)
|
|
36
|
+
.appendString(operands.first() + ", {" + options.join(", ") + "}")
|
|
37
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
38
|
}
|
|
9
39
|
}
|
|
10
40
|
exports.OpenDatasetTranspiler = OpenDatasetTranspiler;
|
|
@@ -3,5 +3,6 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class ParameterTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
|
+
private isFirstOfUnsetRadioGroup;
|
|
7
8
|
}
|
|
@@ -1,10 +1,76 @@
|
|
|
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.ParameterTranspiler = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
4
38
|
const chunk_1 = require("../chunk");
|
|
39
|
+
const transpile_types_1 = require("../transpile_types");
|
|
40
|
+
const _selection_1 = require("./_selection");
|
|
5
41
|
class ParameterTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
42
|
+
transpile(node, traversal) {
|
|
43
|
+
const variable = _selection_1.SelectionDefault.variable(node, traversal);
|
|
44
|
+
// abaplint types "TYPE c LENGTH 3" and "TYPE p ... DECIMALS 2" of a parameter
|
|
45
|
+
// without the length and the decimals, a value would be cut silently
|
|
46
|
+
const tokens = node.getTokens().map(t => t.getStr().toUpperCase());
|
|
47
|
+
const sized = tokens.some((t, i) => (t === "LENGTH" && tokens[i - 1] !== "VISIBLE") || t === "DECIMALS");
|
|
48
|
+
if (variable === undefined || sized === true) {
|
|
49
|
+
return new chunk_1.Chunk(`throw new Error("Parameter, not supported, transpiler");`);
|
|
50
|
+
}
|
|
51
|
+
const { name, type } = variable;
|
|
52
|
+
const ret = new chunk_1.Chunk().appendString("let " + name + " = " + transpile_types_1.TranspileTypes.toType(type) + ";");
|
|
53
|
+
const operand = _selection_1.SelectionDefault.after(node, "DEFAULT");
|
|
54
|
+
if (operand) {
|
|
55
|
+
ret.appendString(_selection_1.SelectionDefault.set(node, name, type, operand, traversal));
|
|
56
|
+
}
|
|
57
|
+
else if (this.isFirstOfUnsetRadioGroup(node, traversal)) {
|
|
58
|
+
// a radio button group without DEFAULT 'X' starts with its first button chosen
|
|
59
|
+
ret.appendString("\n" + name + ".set('X');");
|
|
60
|
+
}
|
|
61
|
+
return ret;
|
|
62
|
+
}
|
|
63
|
+
isFirstOfUnsetRadioGroup(node, traversal) {
|
|
64
|
+
const group = node.findDirectExpression(abaplint.Expressions.RadioGroupName)?.concatTokens().toUpperCase();
|
|
65
|
+
if (group === undefined) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const members = traversal.getFile().getStatements().filter(s => s.get() instanceof abaplint.Statements.Parameter
|
|
69
|
+
&& s.findDirectExpression(abaplint.Expressions.RadioGroupName)?.concatTokens().toUpperCase() === group);
|
|
70
|
+
if (members.some(m => _selection_1.SelectionDefault.after(m, "DEFAULT") !== undefined)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return members[0].getStart().equals(node.getStart());
|
|
8
74
|
}
|
|
9
75
|
}
|
|
10
76
|
exports.ParameterTranspiler = ParameterTranspiler;
|
|
@@ -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 {
|
|
@@ -3,5 +3,5 @@ import { IStatementTranspiler } from "./_statement_transpiler";
|
|
|
3
3
|
import { Traversal } from "../traversal";
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class ReadDatasetTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -2,9 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ReadDatasetTranspiler = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const _dataset_1 = require("./_dataset");
|
|
5
6
|
class ReadDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
7
|
+
transpile(node, traversal) {
|
|
8
|
+
const operands = new _dataset_1.DatasetOperands(node, traversal);
|
|
9
|
+
const options = [];
|
|
10
|
+
if (operands.after("MAXIMUM LENGTH") !== undefined) {
|
|
11
|
+
options.push("maximumLength: " + operands.after("MAXIMUM LENGTH"));
|
|
12
|
+
}
|
|
13
|
+
// the obsolete LENGTH is ACTUAL LENGTH
|
|
14
|
+
const actual = operands.after("ACTUAL LENGTH") ?? operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]);
|
|
15
|
+
if (actual !== undefined) {
|
|
16
|
+
options.push("actualLength: " + actual);
|
|
17
|
+
}
|
|
18
|
+
return new chunk_1.Chunk()
|
|
19
|
+
.append("await abap.statements.readDataset(", node, traversal)
|
|
20
|
+
.appendString(operands.first() + ", " + operands.after("INTO") + ", {" + options.join(", ") + "}")
|
|
21
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
22
|
}
|
|
9
23
|
}
|
|
10
24
|
exports.ReadDatasetTranspiler = ReadDatasetTranspiler;
|