@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.
Files changed (32) hide show
  1. package/build/src/db/schema_generation/pg_database_schema.js +3 -0
  2. package/build/src/db/schema_generation/snowflake_database_schema.js +3 -0
  3. package/build/src/db/schema_generation/sqlite_database_schema.js +3 -0
  4. package/build/src/expressions/sql_cond.d.ts +1 -0
  5. package/build/src/expressions/sql_cond.js +15 -3
  6. package/build/src/statements/_dataset.d.ts +17 -0
  7. package/build/src/statements/_dataset.js +82 -0
  8. package/build/src/statements/_selection.d.ts +18 -0
  9. package/build/src/statements/_selection.js +82 -0
  10. package/build/src/statements/close_dataset.d.ts +1 -1
  11. package/build/src/statements/close_dataset.js +40 -2
  12. package/build/src/statements/delete_dataset.d.ts +1 -1
  13. package/build/src/statements/delete_dataset.js +40 -2
  14. package/build/src/statements/get_dataset.d.ts +1 -1
  15. package/build/src/statements/get_dataset.js +14 -2
  16. package/build/src/statements/loop.d.ts +1 -0
  17. package/build/src/statements/loop.js +16 -1
  18. package/build/src/statements/open_dataset.d.ts +1 -1
  19. package/build/src/statements/open_dataset.js +32 -2
  20. package/build/src/statements/parameter.d.ts +2 -1
  21. package/build/src/statements/parameter.js +68 -2
  22. package/build/src/statements/read_dataset.d.ts +1 -1
  23. package/build/src/statements/read_dataset.js +16 -2
  24. package/build/src/statements/select.js +70 -6
  25. package/build/src/statements/select_option.d.ts +1 -1
  26. package/build/src/statements/select_option.js +63 -2
  27. package/build/src/statements/set_dataset.d.ts +1 -1
  28. package/build/src/statements/set_dataset.js +10 -2
  29. package/build/src/statements/transfer.d.ts +1 -1
  30. package/build/src/statements/transfer.js +14 -2
  31. package/build/src/statements/update_database.js +5 -1
  32. 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`;
@@ -11,6 +11,7 @@ export declare class SQLCondTranspiler implements IExpressionTranspiler {
11
11
  private findSubselect;
12
12
  private sqlSubselect;
13
13
  private sqlSource;
14
+ private sqlHost;
14
15
  private basicConditionNew;
15
16
  private sourceWithComponents;
16
17
  private sqlOperator;
@@ -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 += "'\" + " + code + " + \"'";
227
+ ret += this.sqlHost(code, numericHost);
223
228
  }
224
229
  else if (simple && simple.findDirectExpression(abaplint.Expressions.Constant) === undefined) {
225
- ret += "'\" + " + new simple_source3_1.SimpleSource3Transpiler(true).transpile(simple, traversal).getCode() + " + \"'";
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("CloseDataset, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("DeleteDataset, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("GetDataset, not supported, transpiler");`);
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;
@@ -15,4 +15,5 @@ export declare class LoopTranspiler implements IStatementTranspiler {
15
15
  getTarget(): string;
16
16
  private determineInto;
17
17
  transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
18
+ private hasHeaderLine;
18
19
  }
@@ -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
- for (const compare of whereNode?.findDirectExpressions(abaplint.Expressions.ComponentCompare) || []) {
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("OpenDataset, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("Parameter, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("ReadDataset, not supported, transpiler");`);
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
- select = select.replace(new RegExp(" " + escapeRegExp(faeTranspiled), "g"), " " + unique);
172
- select = select.replace(unique + ".get().table_line.get()", unique + ".get()"); // there can be only one?
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 code = `if (${faeTranspiled}.array().length === 0) {
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
- if (!(${target} instanceof abap.types.HashedTable) && ${target}.getOptions()?.primaryKey?.type !== "SORTED") {
187
- abap.statements.sort(${target}, {by: ${by}.map(k => { return {component: k}; })});
188
- await abap.statements.deleteInternal(${target}, {adjacent: true, allFields: true});
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("SelectOption, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("SetDataset, not supported, transpiler");`);
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(_node: abaplint.Nodes.StatementNode, _traversal: Traversal): Chunk;
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(_node, _traversal) {
7
- return new chunk_1.Chunk(`throw new Error("Transfer, not supported, transpiler");`);
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.94",
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.61",
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.2",
39
+ "mocha": "^12.0.3",
40
40
  "source-map-support": "^0.5.21",
41
41
  "typescript": "^6.0.3"
42
42
  }