@abaplint/transpiler 2.13.94 → 2.13.96
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/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/sql_cond.d.ts +1 -0
- package/build/src/expressions/sql_cond.js +15 -3
- 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/close_dataset.d.ts +1 -1
- package/build/src/statements/close_dataset.js +40 -2
- package/build/src/statements/delete_dataset.d.ts +1 -1
- package/build/src/statements/delete_dataset.js +40 -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 +16 -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/read_dataset.d.ts +1 -1
- package/build/src/statements/read_dataset.js +16 -2
- package/build/src/statements/select.js +70 -6
- 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/transfer.d.ts +1 -1
- package/build/src/statements/transfer.js +14 -2
- package/build/src/statements/update_database.js +5 -1
- package/package.json +3 -3
|
@@ -95,6 +95,9 @@ class PGDatabaseSchema {
|
|
|
95
95
|
else if (type instanceof abaplint.BasicTypes.IntegerType) {
|
|
96
96
|
return `INT`;
|
|
97
97
|
}
|
|
98
|
+
else if (type instanceof abaplint.BasicTypes.Integer8Type) {
|
|
99
|
+
return `BIGINT`;
|
|
100
|
+
}
|
|
98
101
|
else if (type instanceof abaplint.BasicTypes.FloatType
|
|
99
102
|
|| type instanceof abaplint.BasicTypes.FloatingPointType) {
|
|
100
103
|
return `REAL`;
|
|
@@ -94,6 +94,9 @@ class SnowflakeDatabaseSchema {
|
|
|
94
94
|
else if (type instanceof abaplint.BasicTypes.IntegerType) {
|
|
95
95
|
return `INT`;
|
|
96
96
|
}
|
|
97
|
+
else if (type instanceof abaplint.BasicTypes.Integer8Type) {
|
|
98
|
+
return `NUMBER(19)`;
|
|
99
|
+
}
|
|
97
100
|
else if (type instanceof abaplint.BasicTypes.FloatType
|
|
98
101
|
|| type instanceof abaplint.BasicTypes.FloatingPointType) {
|
|
99
102
|
return `REAL`;
|
|
@@ -96,6 +96,9 @@ class SQLiteDatabaseSchema {
|
|
|
96
96
|
else if (type instanceof abaplint.BasicTypes.IntegerType) {
|
|
97
97
|
return `INT`;
|
|
98
98
|
}
|
|
99
|
+
else if (type instanceof abaplint.BasicTypes.Integer8Type) {
|
|
100
|
+
return `INTEGER`;
|
|
101
|
+
}
|
|
99
102
|
else if (type instanceof abaplint.BasicTypes.FloatType
|
|
100
103
|
|| type instanceof abaplint.BasicTypes.FloatingPointType) {
|
|
101
104
|
return `REAL`;
|
|
@@ -151,6 +151,11 @@ class SQLCondTranspiler {
|
|
|
151
151
|
ret += fieldName + " IS NULL";
|
|
152
152
|
return ret;
|
|
153
153
|
}
|
|
154
|
+
const aggregation = c.findDirectExpression(abaplint.Expressions.SQLAggregation);
|
|
155
|
+
if (aggregation && operator && source) {
|
|
156
|
+
return aggregation.concatTokens() + " " + this.sqlOperator(operator.concatTokens()) + " "
|
|
157
|
+
+ this.sqlSource(source, traversal, filename, table, true);
|
|
158
|
+
}
|
|
154
159
|
if (fieldName === undefined || operator === undefined || source === undefined) {
|
|
155
160
|
throw new Error("SQL Condition, transpiler todo2, " + c.concatTokens());
|
|
156
161
|
}
|
|
@@ -212,17 +217,18 @@ class SQLCondTranspiler {
|
|
|
212
217
|
}
|
|
213
218
|
return ret + ")";
|
|
214
219
|
}
|
|
215
|
-
sqlSource(source, traversal, filename, table) {
|
|
220
|
+
sqlSource(source, traversal, filename, table, numericHost = false) {
|
|
216
221
|
let ret = "";
|
|
217
222
|
const simple = source.findDirectExpression(abaplint.Expressions.SimpleSource3);
|
|
218
223
|
const hostExpression = source.findDirectExpression(abaplint.Expressions.Source);
|
|
219
224
|
const alias = source.findDirectExpression(abaplint.Expressions.SQLAliasField);
|
|
220
225
|
if (source.getFirstToken().getStr() === "@" && hostExpression) {
|
|
221
226
|
const code = new source_1.SourceTranspiler(true).transpile(hostExpression, traversal).getCode();
|
|
222
|
-
ret +=
|
|
227
|
+
ret += this.sqlHost(code, numericHost);
|
|
223
228
|
}
|
|
224
229
|
else if (simple && simple.findDirectExpression(abaplint.Expressions.Constant) === undefined) {
|
|
225
|
-
|
|
230
|
+
const code = new simple_source3_1.SimpleSource3Transpiler(true).transpile(simple, traversal).getCode();
|
|
231
|
+
ret += this.sqlHost(code, numericHost);
|
|
226
232
|
}
|
|
227
233
|
else if (alias) {
|
|
228
234
|
// SQLAliasField might be a SQL reference or value from ABAP interface
|
|
@@ -257,6 +263,12 @@ class SQLCondTranspiler {
|
|
|
257
263
|
}
|
|
258
264
|
return ret;
|
|
259
265
|
}
|
|
266
|
+
sqlHost(code, numericHost) {
|
|
267
|
+
if (numericHost) {
|
|
268
|
+
return `" + ((value) => typeof value === "number" || typeof value === "bigint" ? value : "'" + value + "'")(${code}) + "`;
|
|
269
|
+
}
|
|
270
|
+
return "'\" + " + code + " + \"'";
|
|
271
|
+
}
|
|
260
272
|
basicConditionNew(node, traversal, filename, table) {
|
|
261
273
|
const sourceWithComponents = this.sourceWithComponents(node, traversal);
|
|
262
274
|
if (sourceWithComponents) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as abaplint from "@abaplint/core";
|
|
2
|
+
import { Traversal } from "../traversal";
|
|
3
|
+
/** the Sources and Targets of a DATASET statement, each found by the
|
|
4
|
+
* keywords right in front of it: "MESSAGE" in "FOR INPUT IN BINARY MODE
|
|
5
|
+
* MESSAGE m", "LENGTH" only when not "MAXIMUM LENGTH" or "ACTUAL LENGTH" */
|
|
6
|
+
export declare class DatasetOperands {
|
|
7
|
+
private readonly operands;
|
|
8
|
+
private readonly words;
|
|
9
|
+
constructor(node: abaplint.Nodes.StatementNode, traversal: Traversal);
|
|
10
|
+
/** whether the statement has these keywords in a row: its own tokens only,
|
|
11
|
+
* never the text of an operand, so a variable lv_type or a literal
|
|
12
|
+
* 'no end of line' is not an addition */
|
|
13
|
+
has(words: string): boolean;
|
|
14
|
+
/** the dataset name, or the source of TRANSFER: the first operand */
|
|
15
|
+
first(): string;
|
|
16
|
+
after(words: string, notAfter?: string[]): string | undefined;
|
|
17
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DatasetOperands = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
38
|
+
/** the Sources and Targets of a DATASET statement, each found by the
|
|
39
|
+
* keywords right in front of it: "MESSAGE" in "FOR INPUT IN BINARY MODE
|
|
40
|
+
* MESSAGE m", "LENGTH" only when not "MAXIMUM LENGTH" or "ACTUAL LENGTH" */
|
|
41
|
+
class DatasetOperands {
|
|
42
|
+
operands = [];
|
|
43
|
+
words = [];
|
|
44
|
+
constructor(node, traversal) {
|
|
45
|
+
let keywords = [];
|
|
46
|
+
for (const c of node.getChildren()) {
|
|
47
|
+
if (c instanceof abaplint.Nodes.TokenNode) {
|
|
48
|
+
keywords.push(c.getFirstToken().getStr().toUpperCase());
|
|
49
|
+
this.words.push(c.getFirstToken().getStr().toUpperCase());
|
|
50
|
+
}
|
|
51
|
+
else if (c instanceof abaplint.Nodes.ExpressionNode) {
|
|
52
|
+
this.operands.push({ keywords, code: traversal.traverse(c).getCode() });
|
|
53
|
+
keywords = [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** whether the statement has these keywords in a row: its own tokens only,
|
|
58
|
+
* never the text of an operand, so a variable lv_type or a literal
|
|
59
|
+
* 'no end of line' is not an addition */
|
|
60
|
+
has(words) {
|
|
61
|
+
// abaplint splits UTF-8, NON-UNICODE and BYTE-ORDER into three tokens
|
|
62
|
+
const joined = this.words.join(" ").replace(/ - /g, "-");
|
|
63
|
+
return (" " + joined + " ").includes(" " + words + " ");
|
|
64
|
+
}
|
|
65
|
+
/** the dataset name, or the source of TRANSFER: the first operand */
|
|
66
|
+
first() {
|
|
67
|
+
return this.operands[0].code;
|
|
68
|
+
}
|
|
69
|
+
after(words, notAfter = []) {
|
|
70
|
+
const want = words.split(" ");
|
|
71
|
+
for (const o of this.operands.slice(1)) {
|
|
72
|
+
const tail = o.keywords.slice(-want.length);
|
|
73
|
+
const before = o.keywords[o.keywords.length - want.length - 1];
|
|
74
|
+
if (tail.join(" ") === words && (before === undefined || notAfter.includes(before) === false)) {
|
|
75
|
+
return o.code;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DatasetOperands = DatasetOperands;
|
|
82
|
+
//# sourceMappingURL=_dataset.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as abaplint from "@abaplint/core";
|
|
2
|
+
import { Traversal } from "../traversal";
|
|
3
|
+
/** PARAMETERS and SELECT-OPTIONS declare program variables that exist, with their
|
|
4
|
+
* DEFAULT values, before INITIALIZATION runs. Without LOWER CASE a character-like
|
|
5
|
+
* default is upper-cased (measured on a 7.5x system: 'abcdef' into a parameter of
|
|
6
|
+
* length 4 is "ABCD", a string parameter and the LOW of a select-option likewise) */
|
|
7
|
+
export declare class SelectionDefault {
|
|
8
|
+
static variable(node: abaplint.Nodes.StatementNode, traversal: Traversal): {
|
|
9
|
+
name: string;
|
|
10
|
+
type: abaplint.AbstractType;
|
|
11
|
+
} | undefined;
|
|
12
|
+
/** the expression after a keyword of the statement, eg. DEFAULT; only a keyword
|
|
13
|
+
* token counts, an operand named like the keyword does not */
|
|
14
|
+
static after(node: abaplint.Nodes.StatementNode, keyword: string): abaplint.Nodes.ExpressionNode | undefined;
|
|
15
|
+
/** sets the target to a DEFAULT operand, a Constant or a FieldChain, and upper-cases
|
|
16
|
+
* it when the target is character-like and the statement has no LOWER CASE */
|
|
17
|
+
static set(node: abaplint.Nodes.StatementNode, target: string, targetType: abaplint.AbstractType, operand: abaplint.Nodes.ExpressionNode, traversal: Traversal): string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SelectionDefault = void 0;
|
|
37
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
38
|
+
const traversal_1 = require("../traversal");
|
|
39
|
+
/** PARAMETERS and SELECT-OPTIONS declare program variables that exist, with their
|
|
40
|
+
* DEFAULT values, before INITIALIZATION runs. Without LOWER CASE a character-like
|
|
41
|
+
* default is upper-cased (measured on a 7.5x system: 'abcdef' into a parameter of
|
|
42
|
+
* length 4 is "ABCD", a string parameter and the LOW of a select-option likewise) */
|
|
43
|
+
class SelectionDefault {
|
|
44
|
+
static variable(node, traversal) {
|
|
45
|
+
const token = node.findDirectExpression(abaplint.Expressions.FieldSub)?.getFirstToken();
|
|
46
|
+
if (token === undefined) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const found = traversal.findCurrentScopeByToken(token)?.findVariable(token.getStr());
|
|
50
|
+
if (found === undefined) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
name: traversal_1.Traversal.prefixVariable(traversal_1.Traversal.escapeNamespace(found.getName().toLowerCase())),
|
|
55
|
+
type: found.getType(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** the expression after a keyword of the statement, eg. DEFAULT; only a keyword
|
|
59
|
+
* token counts, an operand named like the keyword does not */
|
|
60
|
+
static after(node, keyword) {
|
|
61
|
+
const children = node.getChildren();
|
|
62
|
+
for (let i = 0; i < children.length - 1; i++) {
|
|
63
|
+
if (children[i] instanceof abaplint.Nodes.TokenNode && children[i].concatTokens().toUpperCase() === keyword) {
|
|
64
|
+
return children[i + 1];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
/** sets the target to a DEFAULT operand, a Constant or a FieldChain, and upper-cases
|
|
70
|
+
* it when the target is character-like and the statement has no LOWER CASE */
|
|
71
|
+
static set(node, target, targetType, operand, traversal) {
|
|
72
|
+
let code = "\n" + target + ".set(" + traversal.traverse(operand).getCode() + ");";
|
|
73
|
+
const characterLike = targetType instanceof abaplint.BasicTypes.CharacterType
|
|
74
|
+
|| targetType instanceof abaplint.BasicTypes.StringType;
|
|
75
|
+
if (node.findDirectTokenByText("LOWER") === undefined && characterLike === true) {
|
|
76
|
+
code += "\n" + target + ".set(abap.builtin.to_upper({val: " + target + "}));";
|
|
77
|
+
}
|
|
78
|
+
return code;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.SelectionDefault = SelectionDefault;
|
|
82
|
+
//# sourceMappingURL=_selection.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 CloseDatasetTranspiler 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.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;
|
|
@@ -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,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");
|
|
@@ -148,7 +152,10 @@ class LoopTranspiler {
|
|
|
148
152
|
extra.push(`atLast: (last) => { ${this.atLast} = last; }`);
|
|
149
153
|
}
|
|
150
154
|
const topEquals = {};
|
|
151
|
-
|
|
155
|
+
// only a pure conjunction makes each top-level `=` a condition every row
|
|
156
|
+
// has to meet: `a = 1 OR b = 2` narrows by neither
|
|
157
|
+
const onlyAnd = whereNode?.getChildren().every(c => !(c instanceof abaplint.Nodes.TokenNode) || c.concatTokens().toUpperCase() !== "OR") ?? true;
|
|
158
|
+
for (const compare of onlyAnd ? whereNode?.findDirectExpressions(abaplint.Expressions.ComponentCompare) || [] : []) {
|
|
152
159
|
const op = compare.findDirectExpression(abaplint.Expressions.CompareOperator)?.concatTokens().toUpperCase();
|
|
153
160
|
if (op !== "=" && op !== "EQ") {
|
|
154
161
|
continue;
|
|
@@ -185,6 +192,14 @@ class LoopTranspiler {
|
|
|
185
192
|
}
|
|
186
193
|
return ret;
|
|
187
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
|
+
}
|
|
188
203
|
}
|
|
189
204
|
exports.LoopTranspiler = LoopTranspiler;
|
|
190
205
|
//# sourceMappingURL=loop.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;
|
|
@@ -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;
|
|
@@ -102,6 +102,12 @@ class SelectTranspiler {
|
|
|
102
102
|
if (groupBy) {
|
|
103
103
|
select += new sql_group_by_1.SQLGroupByTranspiler().transpile(groupBy, traversal).getCode() + " ";
|
|
104
104
|
}
|
|
105
|
+
const having = node.findDirectExpression(abaplint.Expressions.Select)
|
|
106
|
+
?.findDirectExpression(abaplint.Expressions.SQLHaving);
|
|
107
|
+
const havingCond = having?.findFirstExpression(abaplint.Expressions.SQLCond);
|
|
108
|
+
if (havingCond) {
|
|
109
|
+
select += "HAVING " + new expressions_1.SQLCondTranspiler().transpile(havingCond, traversal, table).getCode() + " ";
|
|
110
|
+
}
|
|
105
111
|
const upTo = node.findFirstExpression(abaplint.Expressions.SQLUpTo);
|
|
106
112
|
if (upTo) {
|
|
107
113
|
const s = upTo.findFirstExpression(abaplint.Expressions.SimpleSource3);
|
|
@@ -168,14 +174,25 @@ class SelectTranspiler {
|
|
|
168
174
|
const faeTranspiled = new expressions_1.SQLSourceTranspiler().transpile(fn, traversal).getCode();
|
|
169
175
|
// ABAP semantics: with an empty driving table the whole WHERE condition is ignored
|
|
170
176
|
const selectEmpty = select.replace(whereClause, "");
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
const bindRow = (text) => text
|
|
178
|
+
.replace(new RegExp(" " + escapeRegExp(faeTranspiled), "g"), " " + unique)
|
|
179
|
+
.replace(unique + ".get().table_line.get()", unique + ".get()"); // there can be only one?
|
|
180
|
+
select = bindRow(select);
|
|
181
|
+
const where = bindRow(whereClause);
|
|
173
182
|
// FOR ALL ENTRIES removes duplicate rows from the result: duplicates of
|
|
174
183
|
// the selected columns, so de-duplicate by the target's components. The
|
|
175
184
|
// DB key alone is wrong for projections (INTO CORRESPONDING FIELDS
|
|
176
185
|
// without the key fields crashed on the missing component names)
|
|
177
186
|
const by = `Object.keys(${target}.getRowType().get())`;
|
|
178
|
-
const
|
|
187
|
+
const dedup = `if (!(${target} instanceof abap.types.HashedTable) && ${target}.getOptions()?.primaryKey?.type !== "SORTED") {
|
|
188
|
+
abap.statements.sort(${target}, {by: ${by}.map(k => { return {component: k}; })});
|
|
189
|
+
await abap.statements.deleteInternal(${target}, {adjacent: true, allFields: true});
|
|
190
|
+
}`;
|
|
191
|
+
const at = where.startsWith("WHERE ") ? select.indexOf(where) : -1;
|
|
192
|
+
// UP TO with ORDER BY keeps the first n rows in that order; the blocks
|
|
193
|
+
// trim after the de-duplicating sort, so that pair stays row by row
|
|
194
|
+
if (concat.startsWith("SELECT SINGLE ") || at < 0 || (upTo && orderBy)) {
|
|
195
|
+
const code = `if (${faeTranspiled}.array().length === 0) {
|
|
179
196
|
await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
|
|
180
197
|
} else {
|
|
181
198
|
const ${unique2} = ${faeTranspiled}.array();
|
|
@@ -183,9 +200,56 @@ class SelectTranspiler {
|
|
|
183
200
|
for await (const ${unique} of ${unique2}) {
|
|
184
201
|
await abap.statements.select(${target}, {select: "${select.trim()}"${extra}}, {appending: true});
|
|
185
202
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
203
|
+
${dedup}
|
|
204
|
+
abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
205
|
+
}`;
|
|
206
|
+
return new chunk_1.Chunk().append(code, node, traversal);
|
|
207
|
+
}
|
|
208
|
+
// One SELECT per block of driving rows, similar to the kernel's blocking
|
|
209
|
+
// of FOR ALL ENTRIES (rsdb/max_blocking_factor): the condition of each row in
|
|
210
|
+
// parentheses, joined with OR. Not one SELECT per row. UP TO n ROWS
|
|
211
|
+
// counts the whole de-duplicated result, not each block (measured on
|
|
212
|
+
// a 7.5x system: two driving rows and UP TO 3 give 3 rows).
|
|
213
|
+
let tail = select.substring(at + where.length);
|
|
214
|
+
let upToCode = "0";
|
|
215
|
+
if (upTo) {
|
|
216
|
+
const s = upTo.findFirstExpression(abaplint.Expressions.SimpleSource3);
|
|
217
|
+
if (s) {
|
|
218
|
+
const n = new expressions_1.SourceTranspiler(true).transpile(s, traversal).getCode();
|
|
219
|
+
tail = tail.replace(`UP TO " + ${n} + " ROWS `, "");
|
|
220
|
+
upToCode = `parseInt(${n}, 10)`;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
tail = tail.replace(upTo.concatTokens() + " ", "");
|
|
224
|
+
upToCode = String(parseInt(upTo.findFirstExpression(abaplint.Expressions.Integer)?.concatTokens() ?? "0", 10));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const head = select.substring(0, at);
|
|
228
|
+
const condition = where.substring("WHERE ".length).trimEnd();
|
|
229
|
+
const unique3 = unique_identifier_1.UniqueIdentifier.get();
|
|
230
|
+
const unique4 = unique_identifier_1.UniqueIdentifier.get();
|
|
231
|
+
const code = `if (${faeTranspiled}.array().length === 0) {
|
|
232
|
+
await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
|
|
233
|
+
} else {
|
|
234
|
+
const ${unique2} = ${faeTranspiled}.array();
|
|
235
|
+
${target}.clear();
|
|
236
|
+
const ${unique3} = (${unique}) => "(${condition})";
|
|
237
|
+
for (let ${unique4} = 0; ${unique4} < ${unique2}.length; ${unique4} += 50) {
|
|
238
|
+
const ${unique4}where = ${unique2}.slice(${unique4}, ${unique4} + 50).map(${unique3}).join(" OR ");
|
|
239
|
+
await abap.statements.select(${target}, {select: "${head}WHERE " + ${unique4}where + " ${tail.trim()}"${extra}}, {appending: true});
|
|
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
|
+
}
|
|
189
253
|
}
|
|
190
254
|
abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
|
|
191
255
|
}`;
|
|
@@ -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 SelectOptionTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -1,10 +1,71 @@
|
|
|
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.SelectOptionTranspiler = 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 SelectOptionTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
42
|
+
transpile(node, traversal) {
|
|
43
|
+
const variable = _selection_1.SelectionDefault.variable(node, traversal);
|
|
44
|
+
const row = variable?.type instanceof abaplint.BasicTypes.TableType ? variable.type.getRowType() : undefined;
|
|
45
|
+
const lowType = row instanceof abaplint.BasicTypes.StructureType ? row.getComponentByName("LOW") : undefined;
|
|
46
|
+
if (variable === undefined || lowType === undefined) {
|
|
47
|
+
// eg. FOR (dynamic)
|
|
48
|
+
return new chunk_1.Chunk(`throw new Error("SelectOption, not supported, transpiler");`);
|
|
49
|
+
}
|
|
50
|
+
const { name, type } = variable;
|
|
51
|
+
const ret = new chunk_1.Chunk().appendString("let " + name + " = " + transpile_types_1.TranspileTypes.toType(type) + ";");
|
|
52
|
+
// DEFAULT low [TO high] [OPTION o] [SIGN s] is the first row of the table and
|
|
53
|
+
// stays in the header line: I EQ, or I BT with TO, unless OPTION or SIGN say otherwise
|
|
54
|
+
const low = _selection_1.SelectionDefault.after(node, "DEFAULT");
|
|
55
|
+
if (low === undefined) {
|
|
56
|
+
return ret;
|
|
57
|
+
}
|
|
58
|
+
const high = _selection_1.SelectionDefault.after(node, "TO");
|
|
59
|
+
const option = _selection_1.SelectionDefault.after(node, "OPTION")?.concatTokens().toUpperCase() ?? (high ? "BT" : "EQ");
|
|
60
|
+
const sign = _selection_1.SelectionDefault.after(node, "SIGN")?.concatTokens().toUpperCase() ?? "I";
|
|
61
|
+
ret.appendString("\n" + name + ".get().sign.set('" + sign + "');");
|
|
62
|
+
ret.appendString("\n" + name + ".get().option.set('" + option + "');");
|
|
63
|
+
ret.appendString(_selection_1.SelectionDefault.set(node, name + ".get().low", lowType, low, traversal));
|
|
64
|
+
if (high) {
|
|
65
|
+
ret.appendString(_selection_1.SelectionDefault.set(node, name + ".get().high", lowType, high, traversal));
|
|
66
|
+
}
|
|
67
|
+
ret.appendString("\nabap.statements.append({source: " + name + "});");
|
|
68
|
+
return ret;
|
|
8
69
|
}
|
|
9
70
|
}
|
|
10
71
|
exports.SelectOptionTranspiler = SelectOptionTranspiler;
|
|
@@ -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 SetDatasetTranspiler implements IStatementTranspiler {
|
|
6
|
-
transpile(
|
|
6
|
+
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
7
|
}
|
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SetDatasetTranspiler = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const _dataset_1 = require("./_dataset");
|
|
5
6
|
class SetDatasetTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
7
|
+
transpile(node, traversal) {
|
|
8
|
+
const operands = new _dataset_1.DatasetOperands(node, traversal);
|
|
9
|
+
const option = operands.after("POSITION") !== undefined
|
|
10
|
+
? "position: " + operands.after("POSITION")
|
|
11
|
+
: "endOfFile: true";
|
|
12
|
+
return new chunk_1.Chunk()
|
|
13
|
+
.append("await abap.statements.setDataset(", node, traversal)
|
|
14
|
+
.appendString(operands.first() + ", {" + option + "}")
|
|
15
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
16
|
}
|
|
9
17
|
}
|
|
10
18
|
exports.SetDatasetTranspiler = SetDatasetTranspiler;
|
|
@@ -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 TransferTranspiler 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.TransferTranspiler = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const _dataset_1 = require("./_dataset");
|
|
5
6
|
class TransferTranspiler {
|
|
6
|
-
transpile(
|
|
7
|
-
|
|
7
|
+
transpile(node, traversal) {
|
|
8
|
+
const operands = new _dataset_1.DatasetOperands(node, traversal);
|
|
9
|
+
const options = [];
|
|
10
|
+
if (operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]) !== undefined) {
|
|
11
|
+
options.push("length: " + operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]));
|
|
12
|
+
}
|
|
13
|
+
if (operands.has("NO END OF LINE")) {
|
|
14
|
+
options.push("noEndOfLine: true");
|
|
15
|
+
}
|
|
16
|
+
return new chunk_1.Chunk()
|
|
17
|
+
.append("await abap.statements.transfer(", node, traversal)
|
|
18
|
+
.appendString(operands.first() + ", " + operands.after("TO") + ", {" + options.join(", ") + "}")
|
|
19
|
+
.append(");", node.getLastToken(), traversal);
|
|
8
20
|
}
|
|
9
21
|
}
|
|
10
22
|
exports.TransferTranspiler = TransferTranspiler;
|
|
@@ -58,8 +58,12 @@ class UpdateDatabaseTranspiler {
|
|
|
58
58
|
}
|
|
59
59
|
options.push(`"set": [${s.join(",")}]`);
|
|
60
60
|
}
|
|
61
|
+
const fromTable = node.findExpressionAfterToken("TABLE");
|
|
62
|
+
if (fromTable && fromTable.get() instanceof abaplint.Expressions.SQLSource) {
|
|
63
|
+
options.push(`"table": ` + traversal.traverse(fromTable).getCode());
|
|
64
|
+
}
|
|
61
65
|
const sourceExpression = node.findDirectExpression(abaplint.Expressions.SQLSource)?.findDirectExpression(abaplint.Expressions.SimpleSource3);
|
|
62
|
-
if (sourceExpression) {
|
|
66
|
+
if (sourceExpression && fromTable === undefined) {
|
|
63
67
|
const sqlSource = new expressions_1.SourceTranspiler(true).transpile(sourceExpression, traversal).getCode();
|
|
64
68
|
const tableName = node.findDirectExpression(abaplint.Expressions.DatabaseTable)?.concatTokens();
|
|
65
69
|
const tabl = traversal.findTable(tableName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.96",
|
|
4
4
|
"description": "Transpiler",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/src/index.d.ts",
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"author": "abaplint",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@abaplint/core": "^2.120.
|
|
32
|
+
"@abaplint/core": "^2.120.64",
|
|
33
33
|
"source-map": "^0.8.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/chai": "^5.2.3",
|
|
37
37
|
"@types/mocha": "^10.0.10",
|
|
38
38
|
"chai": "^6.2.2",
|
|
39
|
-
"mocha": "^12.0.
|
|
39
|
+
"mocha": "^12.0.3",
|
|
40
40
|
"source-map-support": "^0.5.21",
|
|
41
41
|
"typescript": "^6.0.3"
|
|
42
42
|
}
|