@abaplint/transpiler-cli 2.13.95 → 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 (2) hide show
  1. package/build/bundle.js +812 -33
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -28100,6 +28100,7 @@ class TypeUtils {
28100
28100
  || type instanceof basic_1.StringType
28101
28101
  || type instanceof basic_1.CLikeType
28102
28102
  || type instanceof basic_1.CSequenceType
28103
+ || type instanceof basic_1.DataType
28103
28104
  || this.isCharLikeField(type);
28104
28105
  }
28105
28106
  isCharLike(type) {
@@ -29350,6 +29351,7 @@ class BasicTypes {
29350
29351
  }
29351
29352
  parseType(node, qualifiedName) {
29352
29353
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
29354
+ var _l;
29353
29355
  const typeName = node.findFirstExpression(Expressions.TypeName);
29354
29356
  let text = (_a = node.findFirstExpression(Expressions.Type)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
29355
29357
  if (text === undefined) {
@@ -29500,6 +29502,9 @@ class BasicTypes {
29500
29502
  length = parseInt(int.concatTokens(), 10);
29501
29503
  }
29502
29504
  }
29505
+ else if (node.get() instanceof Statements.Parameter) {
29506
+ length = (_l = this.findParameterLength(node)) !== null && _l !== void 0 ? _l : length;
29507
+ }
29503
29508
  found = new Types.CharacterType(length, { qualifiedName: qualifiedName }); // fallback
29504
29509
  if (this.isOccurs(node)) {
29505
29510
  found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE"), keyType: Types.TableKeyType.default }, qualifiedName);
@@ -29869,11 +29874,43 @@ class BasicTypes {
29869
29874
  throw new Error("findValue, unexpected");
29870
29875
  }
29871
29876
  findDecimals(node) {
29872
- var _a, _b;
29877
+ var _a, _b, _c;
29873
29878
  const dec = (_b = (_a = node.findDirectExpression(Expressions.Decimals)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Integer)) === null || _b === void 0 ? void 0 : _b.concatTokens();
29874
29879
  if (dec) {
29875
29880
  return parseInt(dec, 10);
29876
29881
  }
29882
+ if (node.get() instanceof Statements.Parameter) {
29883
+ // PARAMETERS spells it seq("DECIMALS", Source) instead of the Decimals expression
29884
+ const source = (_c = this.findParameterAddition(node, "DECIMALS")) === null || _c === void 0 ? void 0 : _c.concatTokens();
29885
+ if (source && /^\d+$/.test(source)) {
29886
+ return parseInt(source, 10);
29887
+ }
29888
+ }
29889
+ return undefined;
29890
+ }
29891
+ // PARAMETERS spells it seq("LENGTH", Constant) instead of the Length expression
29892
+ findParameterLength(node) {
29893
+ const constant = this.findParameterAddition(node, "LENGTH");
29894
+ if (constant === undefined) {
29895
+ return undefined;
29896
+ }
29897
+ const length = this.parseInt(constant.concatTokens());
29898
+ return length === undefined || isNaN(length) ? undefined : length;
29899
+ }
29900
+ // finds the expression following a direct keyword token, "VISIBLE LENGTH" is not "LENGTH"
29901
+ findParameterAddition(node, keyword) {
29902
+ var _a;
29903
+ const children = node.getChildren();
29904
+ for (let i = 0; i < children.length - 1; i++) {
29905
+ const child = children[i];
29906
+ const next = children[i + 1];
29907
+ if (child instanceof nodes_1.ExpressionNode
29908
+ || child.getFirstToken().getStr().toUpperCase() !== keyword
29909
+ || ((_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr().toUpperCase()) === "VISIBLE") {
29910
+ continue;
29911
+ }
29912
+ return next instanceof nodes_1.ExpressionNode ? next : undefined;
29913
+ }
29877
29914
  return undefined;
29878
29915
  }
29879
29916
  findLength(node) {
@@ -29894,6 +29931,9 @@ class BasicTypes {
29894
29931
  }
29895
29932
  }
29896
29933
  if (val === undefined) {
29934
+ if (node.get() instanceof Statements.Parameter) {
29935
+ return this.findParameterLength(node);
29936
+ }
29897
29937
  return undefined;
29898
29938
  }
29899
29939
  const intExpr = val.findFirstExpression(Expressions.Integer);
@@ -57050,7 +57090,7 @@ class DDIC {
57050
57090
  return new Types.PackedType(length, 0, { qualifiedName: qualifiedName });
57051
57091
  }
57052
57092
  else {
57053
- return new Types.PackedType(8, 0, { qualifiedName: qualifiedName });
57093
+ return new Types.PackedType(8, decimals !== null && decimals !== void 0 ? decimals : 0, { qualifiedName: qualifiedName });
57054
57094
  }
57055
57095
  case "C":
57056
57096
  if (length) {
@@ -69486,11 +69526,17 @@ class Table extends _abstract_object_1.AbstractObject {
69486
69526
  }
69487
69527
  const ret = [];
69488
69528
  for (const p of this.parsedData.fields) {
69489
- if (p.KEYFLAG === "X" && p.FIELDNAME === ".INCLUDE") {
69490
- const lookup = new ddic_1.DDIC(reg).lookupTableOrView(p.PRECFIELD).type;
69529
+ if (p.KEYFLAG === "X" && (p.FIELDNAME === ".INCLUDE" || p.FIELDNAME.startsWith(".INCLU-"))) {
69530
+ let lookup = new ddic_1.DDIC(reg).lookupTableOrView(p.PRECFIELD).type;
69531
+ if (lookup instanceof _typed_identifier_1.TypedIdentifier) {
69532
+ lookup = lookup.getType();
69533
+ }
69534
+ // same naming as in parseType(), "--AP" are .APPENDS and get no suffix
69535
+ const postfix = p.FIELDNAME.startsWith(".INCLU-") && p.FIELDNAME !== ".INCLU--AP"
69536
+ ? p.FIELDNAME.substring(".INCLU-".length) : "";
69491
69537
  if (lookup instanceof Types.StructureType) {
69492
69538
  for (const c of lookup.getComponents()) {
69493
- ret.push(c.name);
69539
+ ret.push(c.name + postfix);
69494
69540
  }
69495
69541
  }
69496
69542
  }
@@ -71315,7 +71361,7 @@ class Registry {
71315
71361
  }
71316
71362
  static abaplintVersion() {
71317
71363
  // magic, see build script "version.js"
71318
- return "2.120.63";
71364
+ return "2.120.64";
71319
71365
  }
71320
71366
  getDDICReferences() {
71321
71367
  return this.ddicReferences;
@@ -81811,6 +81857,178 @@ exports.EasyToFindMessages = EasyToFindMessages;
81811
81857
 
81812
81858
  /***/ },
81813
81859
 
81860
+ /***/ "./node_modules/@abaplint/core/build/src/rules/else_after_all_returns.js"
81861
+ /*!*******************************************************************************!*\
81862
+ !*** ./node_modules/@abaplint/core/build/src/rules/else_after_all_returns.js ***!
81863
+ \*******************************************************************************/
81864
+ (__unused_webpack_module, exports, __webpack_require__) {
81865
+
81866
+ "use strict";
81867
+
81868
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
81869
+ if (k2 === undefined) k2 = k;
81870
+ var desc = Object.getOwnPropertyDescriptor(m, k);
81871
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
81872
+ desc = { enumerable: true, get: function() { return m[k]; } };
81873
+ }
81874
+ Object.defineProperty(o, k2, desc);
81875
+ }) : (function(o, m, k, k2) {
81876
+ if (k2 === undefined) k2 = k;
81877
+ o[k2] = m[k];
81878
+ }));
81879
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
81880
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
81881
+ }) : function(o, v) {
81882
+ o["default"] = v;
81883
+ });
81884
+ var __importStar = (this && this.__importStar) || (function () {
81885
+ var ownKeys = function(o) {
81886
+ ownKeys = Object.getOwnPropertyNames || function (o) {
81887
+ var ar = [];
81888
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
81889
+ return ar;
81890
+ };
81891
+ return ownKeys(o);
81892
+ };
81893
+ return function (mod) {
81894
+ if (mod && mod.__esModule) return mod;
81895
+ var result = {};
81896
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
81897
+ __setModuleDefault(result, mod);
81898
+ return result;
81899
+ };
81900
+ })();
81901
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
81902
+ exports.ElseAfterAllReturns = exports.ElseAfterAllReturnsConf = void 0;
81903
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
81904
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
81905
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
81906
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
81907
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
81908
+ const Structures = __importStar(__webpack_require__(/*! ../abap/3_structures/structures */ "./node_modules/@abaplint/core/build/src/abap/3_structures/structures/index.js"));
81909
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
81910
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
81911
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
81912
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
81913
+ class ElseAfterAllReturnsConf extends _basic_rule_config_1.BasicRuleConfig {
81914
+ }
81915
+ exports.ElseAfterAllReturnsConf = ElseAfterAllReturnsConf;
81916
+ class ElseAfterAllReturns extends _abap_rule_1.ABAPRule {
81917
+ constructor() {
81918
+ super(...arguments);
81919
+ this.conf = new ElseAfterAllReturnsConf();
81920
+ }
81921
+ getMetadata() {
81922
+ return {
81923
+ key: "else_after_all_returns",
81924
+ title: "Else after all returns",
81925
+ shortDescription: `Finds ELSE branches that are redundant because all prior branches exit unconditionally.`,
81926
+ extendedInformation: `When every branch preceding ELSE ends with RETURN, EXIT, or CONTINUE (or a non-resumable RAISE / LEAVE), ` +
81927
+ `the ELSE keyword adds no logical value and can be removed by de-indenting its body.`,
81928
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix],
81929
+ badExample: `IF x = 1.\n RETURN.\nELSE.\n WRITE 'hello'.\nENDIF.`,
81930
+ goodExample: `IF x = 1.\n RETURN.\nENDIF.\nWRITE 'hello'.`,
81931
+ };
81932
+ }
81933
+ getConfig() {
81934
+ return this.conf;
81935
+ }
81936
+ setConfig(conf) {
81937
+ this.conf = conf;
81938
+ }
81939
+ runParsed(file, _obj) {
81940
+ const issues = [];
81941
+ const structure = file.getStructure();
81942
+ if (structure === undefined) {
81943
+ return [];
81944
+ }
81945
+ for (const ifNode of structure.findAllStructures(Structures.If)) {
81946
+ const elseNode = ifNode.findDirectStructure(Structures.Else);
81947
+ if (elseNode === undefined) {
81948
+ continue;
81949
+ }
81950
+ if (this.allBranchesExit(ifNode)) {
81951
+ const elseStatement = elseNode.findFirstStatement(Statements.Else);
81952
+ const endifStatement = ifNode.findDirectStatement(Statements.EndIf);
81953
+ if (elseStatement === undefined || endifStatement === undefined) {
81954
+ continue;
81955
+ }
81956
+ const fix = edit_helper_1.EditHelper.merge(edit_helper_1.EditHelper.replaceRange(file, elseStatement.getFirstToken().getStart(), elseStatement.getLastToken().getEnd(), "ENDIF."), edit_helper_1.EditHelper.deleteStatement(file, endifStatement));
81957
+ // eslint-disable-next-line max-len
81958
+ issues.push(issue_1.Issue.atStatement(file, elseStatement, "Redundant ELSE: all prior branches exit unconditionally", this.getMetadata().key, this.conf.severity, fix));
81959
+ }
81960
+ }
81961
+ return issues;
81962
+ }
81963
+ // Returns true if every branch before the ELSE ends with an unconditional exit.
81964
+ allBranchesExit(ifNode) {
81965
+ // Main IF body
81966
+ const mainBody = ifNode.findDirectStructure(Structures.Body);
81967
+ if (!this.bodyEndsWithExit(mainBody)) {
81968
+ return false;
81969
+ }
81970
+ // Each ELSEIF body
81971
+ for (const elseifNode of ifNode.findDirectStructures(Structures.ElseIf)) {
81972
+ const elseifBody = elseifNode.findDirectStructure(Structures.Body);
81973
+ if (!this.bodyEndsWithExit(elseifBody)) {
81974
+ return false;
81975
+ }
81976
+ }
81977
+ return true;
81978
+ }
81979
+ bodyEndsWithExit(body) {
81980
+ if (body === undefined) {
81981
+ return false;
81982
+ }
81983
+ const last = this.lastNonCommentStatement(body);
81984
+ if (last === undefined) {
81985
+ return false;
81986
+ }
81987
+ return this.isExit(last);
81988
+ }
81989
+ collectStatements(node) {
81990
+ const result = [];
81991
+ for (const child of node.getChildren()) {
81992
+ if (child instanceof nodes_1.StatementNode) {
81993
+ result.push(child);
81994
+ }
81995
+ else if (child instanceof nodes_1.StructureNode) {
81996
+ result.push(...this.collectStatements(child));
81997
+ }
81998
+ }
81999
+ return result;
82000
+ }
82001
+ lastNonCommentStatement(node) {
82002
+ const all = this.collectStatements(node);
82003
+ for (let i = all.length - 1; i >= 0; i--) {
82004
+ if (!(all[i].get() instanceof _statement_1.Comment)) {
82005
+ return all[i];
82006
+ }
82007
+ }
82008
+ return undefined;
82009
+ }
82010
+ isExit(node) {
82011
+ const s = node.get();
82012
+ if (s instanceof Statements.Return
82013
+ || s instanceof Statements.Exit
82014
+ || s instanceof Statements.Continue) {
82015
+ return true;
82016
+ }
82017
+ if (s instanceof Statements.Raise) {
82018
+ return !node.concatTokens().toUpperCase().includes("RESUMABLE");
82019
+ }
82020
+ if (s instanceof Statements.Leave) {
82021
+ const tokens = node.concatTokens().toUpperCase();
82022
+ return !tokens.includes("LIST-PROCESSING") && node.findFirstExpression(Expressions.AndReturn) === undefined;
82023
+ }
82024
+ return false;
82025
+ }
82026
+ }
82027
+ exports.ElseAfterAllReturns = ElseAfterAllReturns;
82028
+ //# sourceMappingURL=else_after_all_returns.js.map
82029
+
82030
+ /***/ },
82031
+
81814
82032
  /***/ "./node_modules/@abaplint/core/build/src/rules/empty_event.js"
81815
82033
  /*!********************************************************************!*\
81816
82034
  !*** ./node_modules/@abaplint/core/build/src/rules/empty_event.js ***!
@@ -85632,6 +85850,7 @@ __exportStar(__webpack_require__(/*! ./empty_event */ "./node_modules/@abaplint/
85632
85850
  __exportStar(__webpack_require__(/*! ./empty_line_in_statement */ "./node_modules/@abaplint/core/build/src/rules/empty_line_in_statement.js"), exports);
85633
85851
  __exportStar(__webpack_require__(/*! ./empty_statement */ "./node_modules/@abaplint/core/build/src/rules/empty_statement.js"), exports);
85634
85852
  __exportStar(__webpack_require__(/*! ./empty_structure */ "./node_modules/@abaplint/core/build/src/rules/empty_structure.js"), exports);
85853
+ __exportStar(__webpack_require__(/*! ./else_after_all_returns */ "./node_modules/@abaplint/core/build/src/rules/else_after_all_returns.js"), exports);
85635
85854
  __exportStar(__webpack_require__(/*! ./exit_or_check */ "./node_modules/@abaplint/core/build/src/rules/exit_or_check.js"), exports);
85636
85855
  __exportStar(__webpack_require__(/*! ./expand_macros */ "./node_modules/@abaplint/core/build/src/rules/expand_macros.js"), exports);
85637
85856
  __exportStar(__webpack_require__(/*! ./exporting */ "./node_modules/@abaplint/core/build/src/rules/exporting.js"), exports);
@@ -104872,6 +105091,9 @@ class PGDatabaseSchema {
104872
105091
  else if (type instanceof abaplint.BasicTypes.IntegerType) {
104873
105092
  return `INT`;
104874
105093
  }
105094
+ else if (type instanceof abaplint.BasicTypes.Integer8Type) {
105095
+ return `BIGINT`;
105096
+ }
104875
105097
  else if (type instanceof abaplint.BasicTypes.FloatType
104876
105098
  || type instanceof abaplint.BasicTypes.FloatingPointType) {
104877
105099
  return `REAL`;
@@ -104995,6 +105217,9 @@ class SnowflakeDatabaseSchema {
104995
105217
  else if (type instanceof abaplint.BasicTypes.IntegerType) {
104996
105218
  return `INT`;
104997
105219
  }
105220
+ else if (type instanceof abaplint.BasicTypes.Integer8Type) {
105221
+ return `NUMBER(19)`;
105222
+ }
104998
105223
  else if (type instanceof abaplint.BasicTypes.FloatType
104999
105224
  || type instanceof abaplint.BasicTypes.FloatingPointType) {
105000
105225
  return `REAL`;
@@ -105120,6 +105345,9 @@ class SQLiteDatabaseSchema {
105120
105345
  else if (type instanceof abaplint.BasicTypes.IntegerType) {
105121
105346
  return `INT`;
105122
105347
  }
105348
+ else if (type instanceof abaplint.BasicTypes.Integer8Type) {
105349
+ return `INTEGER`;
105350
+ }
105123
105351
  else if (type instanceof abaplint.BasicTypes.FloatType
105124
105352
  || type instanceof abaplint.BasicTypes.FloatingPointType) {
105125
105353
  return `REAL`;
@@ -109084,6 +109312,11 @@ class SQLCondTranspiler {
109084
109312
  ret += fieldName + " IS NULL";
109085
109313
  return ret;
109086
109314
  }
109315
+ const aggregation = c.findDirectExpression(abaplint.Expressions.SQLAggregation);
109316
+ if (aggregation && operator && source) {
109317
+ return aggregation.concatTokens() + " " + this.sqlOperator(operator.concatTokens()) + " "
109318
+ + this.sqlSource(source, traversal, filename, table, true);
109319
+ }
109087
109320
  if (fieldName === undefined || operator === undefined || source === undefined) {
109088
109321
  throw new Error("SQL Condition, transpiler todo2, " + c.concatTokens());
109089
109322
  }
@@ -109145,17 +109378,18 @@ class SQLCondTranspiler {
109145
109378
  }
109146
109379
  return ret + ")";
109147
109380
  }
109148
- sqlSource(source, traversal, filename, table) {
109381
+ sqlSource(source, traversal, filename, table, numericHost = false) {
109149
109382
  let ret = "";
109150
109383
  const simple = source.findDirectExpression(abaplint.Expressions.SimpleSource3);
109151
109384
  const hostExpression = source.findDirectExpression(abaplint.Expressions.Source);
109152
109385
  const alias = source.findDirectExpression(abaplint.Expressions.SQLAliasField);
109153
109386
  if (source.getFirstToken().getStr() === "@" && hostExpression) {
109154
109387
  const code = new source_1.SourceTranspiler(true).transpile(hostExpression, traversal).getCode();
109155
- ret += "'\" + " + code + " + \"'";
109388
+ ret += this.sqlHost(code, numericHost);
109156
109389
  }
109157
109390
  else if (simple && simple.findDirectExpression(abaplint.Expressions.Constant) === undefined) {
109158
- ret += "'\" + " + new simple_source3_1.SimpleSource3Transpiler(true).transpile(simple, traversal).getCode() + " + \"'";
109391
+ const code = new simple_source3_1.SimpleSource3Transpiler(true).transpile(simple, traversal).getCode();
109392
+ ret += this.sqlHost(code, numericHost);
109159
109393
  }
109160
109394
  else if (alias) {
109161
109395
  // SQLAliasField might be a SQL reference or value from ABAP interface
@@ -109190,6 +109424,12 @@ class SQLCondTranspiler {
109190
109424
  }
109191
109425
  return ret;
109192
109426
  }
109427
+ sqlHost(code, numericHost) {
109428
+ if (numericHost) {
109429
+ return `" + ((value) => typeof value === "number" || typeof value === "bigint" ? value : "'" + value + "'")(${code}) + "`;
109430
+ }
109431
+ return "'\" + " + code + " + \"'";
109432
+ }
109193
109433
  basicConditionNew(node, traversal, filename, table) {
109194
109434
  const sourceWithComponents = this.sourceWithComponents(node, traversal);
109195
109435
  if (sourceWithComponents) {
@@ -112804,6 +113044,190 @@ exports.Requires = Requires;
112804
113044
 
112805
113045
  /***/ },
112806
113046
 
113047
+ /***/ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js"
113048
+ /*!****************************************************************************!*\
113049
+ !*** ./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js ***!
113050
+ \****************************************************************************/
113051
+ (__unused_webpack_module, exports, __webpack_require__) {
113052
+
113053
+ "use strict";
113054
+
113055
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
113056
+ if (k2 === undefined) k2 = k;
113057
+ var desc = Object.getOwnPropertyDescriptor(m, k);
113058
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
113059
+ desc = { enumerable: true, get: function() { return m[k]; } };
113060
+ }
113061
+ Object.defineProperty(o, k2, desc);
113062
+ }) : (function(o, m, k, k2) {
113063
+ if (k2 === undefined) k2 = k;
113064
+ o[k2] = m[k];
113065
+ }));
113066
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
113067
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
113068
+ }) : function(o, v) {
113069
+ o["default"] = v;
113070
+ });
113071
+ var __importStar = (this && this.__importStar) || (function () {
113072
+ var ownKeys = function(o) {
113073
+ ownKeys = Object.getOwnPropertyNames || function (o) {
113074
+ var ar = [];
113075
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
113076
+ return ar;
113077
+ };
113078
+ return ownKeys(o);
113079
+ };
113080
+ return function (mod) {
113081
+ if (mod && mod.__esModule) return mod;
113082
+ var result = {};
113083
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
113084
+ __setModuleDefault(result, mod);
113085
+ return result;
113086
+ };
113087
+ })();
113088
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
113089
+ exports.DatasetOperands = void 0;
113090
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
113091
+ /** the Sources and Targets of a DATASET statement, each found by the
113092
+ * keywords right in front of it: "MESSAGE" in "FOR INPUT IN BINARY MODE
113093
+ * MESSAGE m", "LENGTH" only when not "MAXIMUM LENGTH" or "ACTUAL LENGTH" */
113094
+ class DatasetOperands {
113095
+ operands = [];
113096
+ words = [];
113097
+ constructor(node, traversal) {
113098
+ let keywords = [];
113099
+ for (const c of node.getChildren()) {
113100
+ if (c instanceof abaplint.Nodes.TokenNode) {
113101
+ keywords.push(c.getFirstToken().getStr().toUpperCase());
113102
+ this.words.push(c.getFirstToken().getStr().toUpperCase());
113103
+ }
113104
+ else if (c instanceof abaplint.Nodes.ExpressionNode) {
113105
+ this.operands.push({ keywords, code: traversal.traverse(c).getCode() });
113106
+ keywords = [];
113107
+ }
113108
+ }
113109
+ }
113110
+ /** whether the statement has these keywords in a row: its own tokens only,
113111
+ * never the text of an operand, so a variable lv_type or a literal
113112
+ * 'no end of line' is not an addition */
113113
+ has(words) {
113114
+ // abaplint splits UTF-8, NON-UNICODE and BYTE-ORDER into three tokens
113115
+ const joined = this.words.join(" ").replace(/ - /g, "-");
113116
+ return (" " + joined + " ").includes(" " + words + " ");
113117
+ }
113118
+ /** the dataset name, or the source of TRANSFER: the first operand */
113119
+ first() {
113120
+ return this.operands[0].code;
113121
+ }
113122
+ after(words, notAfter = []) {
113123
+ const want = words.split(" ");
113124
+ for (const o of this.operands.slice(1)) {
113125
+ const tail = o.keywords.slice(-want.length);
113126
+ const before = o.keywords[o.keywords.length - want.length - 1];
113127
+ if (tail.join(" ") === words && (before === undefined || notAfter.includes(before) === false)) {
113128
+ return o.code;
113129
+ }
113130
+ }
113131
+ return undefined;
113132
+ }
113133
+ }
113134
+ exports.DatasetOperands = DatasetOperands;
113135
+ //# sourceMappingURL=_dataset.js.map
113136
+
113137
+ /***/ },
113138
+
113139
+ /***/ "./node_modules/@abaplint/transpiler/build/src/statements/_selection.js"
113140
+ /*!******************************************************************************!*\
113141
+ !*** ./node_modules/@abaplint/transpiler/build/src/statements/_selection.js ***!
113142
+ \******************************************************************************/
113143
+ (__unused_webpack_module, exports, __webpack_require__) {
113144
+
113145
+ "use strict";
113146
+
113147
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
113148
+ if (k2 === undefined) k2 = k;
113149
+ var desc = Object.getOwnPropertyDescriptor(m, k);
113150
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
113151
+ desc = { enumerable: true, get: function() { return m[k]; } };
113152
+ }
113153
+ Object.defineProperty(o, k2, desc);
113154
+ }) : (function(o, m, k, k2) {
113155
+ if (k2 === undefined) k2 = k;
113156
+ o[k2] = m[k];
113157
+ }));
113158
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
113159
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
113160
+ }) : function(o, v) {
113161
+ o["default"] = v;
113162
+ });
113163
+ var __importStar = (this && this.__importStar) || (function () {
113164
+ var ownKeys = function(o) {
113165
+ ownKeys = Object.getOwnPropertyNames || function (o) {
113166
+ var ar = [];
113167
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
113168
+ return ar;
113169
+ };
113170
+ return ownKeys(o);
113171
+ };
113172
+ return function (mod) {
113173
+ if (mod && mod.__esModule) return mod;
113174
+ var result = {};
113175
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
113176
+ __setModuleDefault(result, mod);
113177
+ return result;
113178
+ };
113179
+ })();
113180
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
113181
+ exports.SelectionDefault = void 0;
113182
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
113183
+ const traversal_1 = __webpack_require__(/*! ../traversal */ "./node_modules/@abaplint/transpiler/build/src/traversal.js");
113184
+ /** PARAMETERS and SELECT-OPTIONS declare program variables that exist, with their
113185
+ * DEFAULT values, before INITIALIZATION runs. Without LOWER CASE a character-like
113186
+ * default is upper-cased (measured on a 7.5x system: 'abcdef' into a parameter of
113187
+ * length 4 is "ABCD", a string parameter and the LOW of a select-option likewise) */
113188
+ class SelectionDefault {
113189
+ static variable(node, traversal) {
113190
+ const token = node.findDirectExpression(abaplint.Expressions.FieldSub)?.getFirstToken();
113191
+ if (token === undefined) {
113192
+ return undefined;
113193
+ }
113194
+ const found = traversal.findCurrentScopeByToken(token)?.findVariable(token.getStr());
113195
+ if (found === undefined) {
113196
+ return undefined;
113197
+ }
113198
+ return {
113199
+ name: traversal_1.Traversal.prefixVariable(traversal_1.Traversal.escapeNamespace(found.getName().toLowerCase())),
113200
+ type: found.getType(),
113201
+ };
113202
+ }
113203
+ /** the expression after a keyword of the statement, eg. DEFAULT; only a keyword
113204
+ * token counts, an operand named like the keyword does not */
113205
+ static after(node, keyword) {
113206
+ const children = node.getChildren();
113207
+ for (let i = 0; i < children.length - 1; i++) {
113208
+ if (children[i] instanceof abaplint.Nodes.TokenNode && children[i].concatTokens().toUpperCase() === keyword) {
113209
+ return children[i + 1];
113210
+ }
113211
+ }
113212
+ return undefined;
113213
+ }
113214
+ /** sets the target to a DEFAULT operand, a Constant or a FieldChain, and upper-cases
113215
+ * it when the target is character-like and the statement has no LOWER CASE */
113216
+ static set(node, target, targetType, operand, traversal) {
113217
+ let code = "\n" + target + ".set(" + traversal.traverse(operand).getCode() + ");";
113218
+ const characterLike = targetType instanceof abaplint.BasicTypes.CharacterType
113219
+ || targetType instanceof abaplint.BasicTypes.StringType;
113220
+ if (node.findDirectTokenByText("LOWER") === undefined && characterLike === true) {
113221
+ code += "\n" + target + ".set(abap.builtin.to_upper({val: " + target + "}));";
113222
+ }
113223
+ return code;
113224
+ }
113225
+ }
113226
+ exports.SelectionDefault = SelectionDefault;
113227
+ //# sourceMappingURL=_selection.js.map
113228
+
113229
+ /***/ },
113230
+
112807
113231
  /***/ "./node_modules/@abaplint/transpiler/build/src/statements/add.js"
112808
113232
  /*!***********************************************************************!*\
112809
113233
  !*** ./node_modules/@abaplint/transpiler/build/src/statements/add.js ***!
@@ -114353,12 +114777,50 @@ exports.CloseCursorTranspiler = CloseCursorTranspiler;
114353
114777
 
114354
114778
  "use strict";
114355
114779
 
114780
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
114781
+ if (k2 === undefined) k2 = k;
114782
+ var desc = Object.getOwnPropertyDescriptor(m, k);
114783
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
114784
+ desc = { enumerable: true, get: function() { return m[k]; } };
114785
+ }
114786
+ Object.defineProperty(o, k2, desc);
114787
+ }) : (function(o, m, k, k2) {
114788
+ if (k2 === undefined) k2 = k;
114789
+ o[k2] = m[k];
114790
+ }));
114791
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
114792
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
114793
+ }) : function(o, v) {
114794
+ o["default"] = v;
114795
+ });
114796
+ var __importStar = (this && this.__importStar) || (function () {
114797
+ var ownKeys = function(o) {
114798
+ ownKeys = Object.getOwnPropertyNames || function (o) {
114799
+ var ar = [];
114800
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
114801
+ return ar;
114802
+ };
114803
+ return ownKeys(o);
114804
+ };
114805
+ return function (mod) {
114806
+ if (mod && mod.__esModule) return mod;
114807
+ var result = {};
114808
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
114809
+ __setModuleDefault(result, mod);
114810
+ return result;
114811
+ };
114812
+ })();
114356
114813
  Object.defineProperty(exports, "__esModule", ({ value: true }));
114357
114814
  exports.CloseDatasetTranspiler = void 0;
114815
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
114358
114816
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
114359
114817
  class CloseDatasetTranspiler {
114360
- transpile(_node, _traversal) {
114361
- return new chunk_1.Chunk(`throw new Error("CloseDataset, not supported, transpiler");`);
114818
+ transpile(node, traversal) {
114819
+ const name = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Source)).getCode();
114820
+ return new chunk_1.Chunk()
114821
+ .append("await abap.statements.closeDataset(", node, traversal)
114822
+ .appendString(name)
114823
+ .append(");", node.getLastToken(), traversal);
114362
114824
  }
114363
114825
  }
114364
114826
  exports.CloseDatasetTranspiler = CloseDatasetTranspiler;
@@ -115388,12 +115850,50 @@ exports.DeleteDatabaseTranspiler = DeleteDatabaseTranspiler;
115388
115850
 
115389
115851
  "use strict";
115390
115852
 
115853
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
115854
+ if (k2 === undefined) k2 = k;
115855
+ var desc = Object.getOwnPropertyDescriptor(m, k);
115856
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
115857
+ desc = { enumerable: true, get: function() { return m[k]; } };
115858
+ }
115859
+ Object.defineProperty(o, k2, desc);
115860
+ }) : (function(o, m, k, k2) {
115861
+ if (k2 === undefined) k2 = k;
115862
+ o[k2] = m[k];
115863
+ }));
115864
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
115865
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
115866
+ }) : function(o, v) {
115867
+ o["default"] = v;
115868
+ });
115869
+ var __importStar = (this && this.__importStar) || (function () {
115870
+ var ownKeys = function(o) {
115871
+ ownKeys = Object.getOwnPropertyNames || function (o) {
115872
+ var ar = [];
115873
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
115874
+ return ar;
115875
+ };
115876
+ return ownKeys(o);
115877
+ };
115878
+ return function (mod) {
115879
+ if (mod && mod.__esModule) return mod;
115880
+ var result = {};
115881
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
115882
+ __setModuleDefault(result, mod);
115883
+ return result;
115884
+ };
115885
+ })();
115391
115886
  Object.defineProperty(exports, "__esModule", ({ value: true }));
115392
115887
  exports.DeleteDatasetTranspiler = void 0;
115888
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
115393
115889
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
115394
115890
  class DeleteDatasetTranspiler {
115395
- transpile(_node, _traversal) {
115396
- return new chunk_1.Chunk(`throw new Error("DeleteDataset, not supported, transpiler");`);
115891
+ transpile(node, traversal) {
115892
+ const name = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Source)).getCode();
115893
+ return new chunk_1.Chunk()
115894
+ .append("await abap.statements.deleteDataset(", node, traversal)
115895
+ .appendString(name)
115896
+ .append(");", node.getLastToken(), traversal);
115397
115897
  }
115398
115898
  }
115399
115899
  exports.DeleteDatasetTranspiler = DeleteDatasetTranspiler;
@@ -116886,9 +117386,21 @@ exports.GetBitTranspiler = GetBitTranspiler;
116886
117386
  Object.defineProperty(exports, "__esModule", ({ value: true }));
116887
117387
  exports.GetDatasetTranspiler = void 0;
116888
117388
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
117389
+ const _dataset_1 = __webpack_require__(/*! ./_dataset */ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js");
116889
117390
  class GetDatasetTranspiler {
116890
- transpile(_node, _traversal) {
116891
- return new chunk_1.Chunk(`throw new Error("GetDataset, not supported, transpiler");`);
117391
+ transpile(node, traversal) {
117392
+ const operands = new _dataset_1.DatasetOperands(node, traversal);
117393
+ const options = [];
117394
+ if (operands.after("POSITION") !== undefined) {
117395
+ options.push("position: " + operands.after("POSITION"));
117396
+ }
117397
+ if (operands.after("ATTRIBUTES") !== undefined) {
117398
+ options.push("attributes: " + operands.after("ATTRIBUTES"));
117399
+ }
117400
+ return new chunk_1.Chunk()
117401
+ .append("await abap.statements.getDataset(", node, traversal)
117402
+ .appendString(operands.first() + ", {" + options.join(", ") + "}")
117403
+ .append(");", node.getLastToken(), traversal);
116892
117404
  }
116893
117405
  }
116894
117406
  exports.GetDatasetTranspiler = GetDatasetTranspiler;
@@ -118014,6 +118526,10 @@ class LoopTranspiler {
118014
118526
  targetNode = assigning;
118015
118527
  target = traversal.traverse(assigning).getCode() + ".assign(" + this.unique + ");";
118016
118528
  }
118529
+ else if (!node.concatTokens().toUpperCase().includes(" TRANSPORTING NO FIELDS") && this.hasHeaderLine(loopSource, traversal)) {
118530
+ // LOOP AT itab. without a target: the row goes into the header line of the table
118531
+ target = source + ".getHeader().set(" + this.unique + ");";
118532
+ }
118017
118533
  }
118018
118534
  const extra = [];
118019
118535
  const fromNode = node.findExpressionAfterToken("FROM");
@@ -118108,6 +118624,14 @@ class LoopTranspiler {
118108
118624
  }
118109
118625
  return ret;
118110
118626
  }
118627
+ hasHeaderLine(loopSource, traversal) {
118628
+ if (loopSource === undefined || /^[\w\/]+$/.test(loopSource.concatTokens()) === false) {
118629
+ return false;
118630
+ }
118631
+ const token = loopSource.getFirstToken();
118632
+ const type = traversal.findCurrentScopeByToken(token)?.findVariable(loopSource.concatTokens())?.getType();
118633
+ return type instanceof abaplint.BasicTypes.TableType && type.isWithHeader();
118634
+ }
118111
118635
  }
118112
118636
  exports.LoopTranspiler = LoopTranspiler;
118113
118637
  //# sourceMappingURL=loop.js.map
@@ -119144,9 +119668,39 @@ exports.OpenCursorTranspiler = OpenCursorTranspiler;
119144
119668
  Object.defineProperty(exports, "__esModule", ({ value: true }));
119145
119669
  exports.OpenDatasetTranspiler = void 0;
119146
119670
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
119671
+ const _dataset_1 = __webpack_require__(/*! ./_dataset */ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js");
119147
119672
  class OpenDatasetTranspiler {
119148
- transpile(_node, _traversal) {
119149
- return new chunk_1.Chunk(`throw new Error("OpenDataset, not supported, transpiler");`);
119673
+ transpile(node, traversal) {
119674
+ const operands = new _dataset_1.DatasetOperands(node, traversal);
119675
+ const options = [];
119676
+ const mode = ["INPUT", "OUTPUT", "APPENDING", "UPDATE"].find(m => operands.has("FOR " + m)) ?? "INPUT";
119677
+ options.push(`mode: "${mode}"`);
119678
+ options.push(`binary: ${operands.has("BINARY MODE")}`);
119679
+ const encoding = ["DEFAULT", "UTF-8", "NON-UNICODE"].find(e => operands.has("ENCODING " + e));
119680
+ if (encoding !== undefined) {
119681
+ options.push(`encoding: "${encoding}"`);
119682
+ }
119683
+ if (operands.has("IN LEGACY")) {
119684
+ options.push("legacy: true");
119685
+ }
119686
+ if (operands.after("MESSAGE") !== undefined) {
119687
+ options.push("message: " + operands.after("MESSAGE"));
119688
+ }
119689
+ if (operands.after("AT POSITION") !== undefined) {
119690
+ options.push("position: " + operands.after("AT POSITION"));
119691
+ }
119692
+ // accepted by the syntax, not implemented by the runtime: it refuses them
119693
+ // by name rather than ignoring them
119694
+ const unsupported = ["CODE PAGE", "TYPE", "FILTER", "REPLACEMENT CHARACTER", "WITH BYTE-ORDER MARK", "SKIPPING BYTE-ORDER MARK",
119695
+ "WITH SMART LINEFEED", "WITH NATIVE LINEFEED", "WITH UNIX LINEFEED", "WITH WINDOWS LINEFEED", "IGNORING CONVERSION ERRORS"]
119696
+ .filter(u => operands.has(u) || operands.after(u) !== undefined);
119697
+ if (unsupported.length > 0) {
119698
+ options.push("unsupported: " + JSON.stringify(unsupported));
119699
+ }
119700
+ return new chunk_1.Chunk()
119701
+ .append("await abap.statements.openDataset(", node, traversal)
119702
+ .appendString(operands.first() + ", {" + options.join(", ") + "}")
119703
+ .append(");", node.getLastToken(), traversal);
119150
119704
  }
119151
119705
  }
119152
119706
  exports.OpenDatasetTranspiler = OpenDatasetTranspiler;
@@ -119224,12 +119778,78 @@ exports.OverlayTranspiler = OverlayTranspiler;
119224
119778
 
119225
119779
  "use strict";
119226
119780
 
119781
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
119782
+ if (k2 === undefined) k2 = k;
119783
+ var desc = Object.getOwnPropertyDescriptor(m, k);
119784
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
119785
+ desc = { enumerable: true, get: function() { return m[k]; } };
119786
+ }
119787
+ Object.defineProperty(o, k2, desc);
119788
+ }) : (function(o, m, k, k2) {
119789
+ if (k2 === undefined) k2 = k;
119790
+ o[k2] = m[k];
119791
+ }));
119792
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
119793
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
119794
+ }) : function(o, v) {
119795
+ o["default"] = v;
119796
+ });
119797
+ var __importStar = (this && this.__importStar) || (function () {
119798
+ var ownKeys = function(o) {
119799
+ ownKeys = Object.getOwnPropertyNames || function (o) {
119800
+ var ar = [];
119801
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
119802
+ return ar;
119803
+ };
119804
+ return ownKeys(o);
119805
+ };
119806
+ return function (mod) {
119807
+ if (mod && mod.__esModule) return mod;
119808
+ var result = {};
119809
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
119810
+ __setModuleDefault(result, mod);
119811
+ return result;
119812
+ };
119813
+ })();
119227
119814
  Object.defineProperty(exports, "__esModule", ({ value: true }));
119228
119815
  exports.ParameterTranspiler = void 0;
119816
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
119229
119817
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
119818
+ const transpile_types_1 = __webpack_require__(/*! ../transpile_types */ "./node_modules/@abaplint/transpiler/build/src/transpile_types.js");
119819
+ const _selection_1 = __webpack_require__(/*! ./_selection */ "./node_modules/@abaplint/transpiler/build/src/statements/_selection.js");
119230
119820
  class ParameterTranspiler {
119231
- transpile(_node, _traversal) {
119232
- return new chunk_1.Chunk(`throw new Error("Parameter, not supported, transpiler");`);
119821
+ transpile(node, traversal) {
119822
+ const variable = _selection_1.SelectionDefault.variable(node, traversal);
119823
+ // abaplint types "TYPE c LENGTH 3" and "TYPE p ... DECIMALS 2" of a parameter
119824
+ // without the length and the decimals, a value would be cut silently
119825
+ const tokens = node.getTokens().map(t => t.getStr().toUpperCase());
119826
+ const sized = tokens.some((t, i) => (t === "LENGTH" && tokens[i - 1] !== "VISIBLE") || t === "DECIMALS");
119827
+ if (variable === undefined || sized === true) {
119828
+ return new chunk_1.Chunk(`throw new Error("Parameter, not supported, transpiler");`);
119829
+ }
119830
+ const { name, type } = variable;
119831
+ const ret = new chunk_1.Chunk().appendString("let " + name + " = " + transpile_types_1.TranspileTypes.toType(type) + ";");
119832
+ const operand = _selection_1.SelectionDefault.after(node, "DEFAULT");
119833
+ if (operand) {
119834
+ ret.appendString(_selection_1.SelectionDefault.set(node, name, type, operand, traversal));
119835
+ }
119836
+ else if (this.isFirstOfUnsetRadioGroup(node, traversal)) {
119837
+ // a radio button group without DEFAULT 'X' starts with its first button chosen
119838
+ ret.appendString("\n" + name + ".set('X');");
119839
+ }
119840
+ return ret;
119841
+ }
119842
+ isFirstOfUnsetRadioGroup(node, traversal) {
119843
+ const group = node.findDirectExpression(abaplint.Expressions.RadioGroupName)?.concatTokens().toUpperCase();
119844
+ if (group === undefined) {
119845
+ return false;
119846
+ }
119847
+ const members = traversal.getFile().getStatements().filter(s => s.get() instanceof abaplint.Statements.Parameter
119848
+ && s.findDirectExpression(abaplint.Expressions.RadioGroupName)?.concatTokens().toUpperCase() === group);
119849
+ if (members.some(m => _selection_1.SelectionDefault.after(m, "DEFAULT") !== undefined)) {
119850
+ return false;
119851
+ }
119852
+ return members[0].getStart().equals(node.getStart());
119233
119853
  }
119234
119854
  }
119235
119855
  exports.ParameterTranspiler = ParameterTranspiler;
@@ -119673,9 +120293,23 @@ exports.RangesTranspiler = RangesTranspiler;
119673
120293
  Object.defineProperty(exports, "__esModule", ({ value: true }));
119674
120294
  exports.ReadDatasetTranspiler = void 0;
119675
120295
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
120296
+ const _dataset_1 = __webpack_require__(/*! ./_dataset */ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js");
119676
120297
  class ReadDatasetTranspiler {
119677
- transpile(_node, _traversal) {
119678
- return new chunk_1.Chunk(`throw new Error("ReadDataset, not supported, transpiler");`);
120298
+ transpile(node, traversal) {
120299
+ const operands = new _dataset_1.DatasetOperands(node, traversal);
120300
+ const options = [];
120301
+ if (operands.after("MAXIMUM LENGTH") !== undefined) {
120302
+ options.push("maximumLength: " + operands.after("MAXIMUM LENGTH"));
120303
+ }
120304
+ // the obsolete LENGTH is ACTUAL LENGTH
120305
+ const actual = operands.after("ACTUAL LENGTH") ?? operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]);
120306
+ if (actual !== undefined) {
120307
+ options.push("actualLength: " + actual);
120308
+ }
120309
+ return new chunk_1.Chunk()
120310
+ .append("await abap.statements.readDataset(", node, traversal)
120311
+ .appendString(operands.first() + ", " + operands.after("INTO") + ", {" + options.join(", ") + "}")
120312
+ .append(");", node.getLastToken(), traversal);
119679
120313
  }
119680
120314
  }
119681
120315
  exports.ReadDatasetTranspiler = ReadDatasetTranspiler;
@@ -120557,6 +121191,12 @@ class SelectTranspiler {
120557
121191
  if (groupBy) {
120558
121192
  select += new sql_group_by_1.SQLGroupByTranspiler().transpile(groupBy, traversal).getCode() + " ";
120559
121193
  }
121194
+ const having = node.findDirectExpression(abaplint.Expressions.Select)
121195
+ ?.findDirectExpression(abaplint.Expressions.SQLHaving);
121196
+ const havingCond = having?.findFirstExpression(abaplint.Expressions.SQLCond);
121197
+ if (havingCond) {
121198
+ select += "HAVING " + new expressions_1.SQLCondTranspiler().transpile(havingCond, traversal, table).getCode() + " ";
121199
+ }
120560
121200
  const upTo = node.findFirstExpression(abaplint.Expressions.SQLUpTo);
120561
121201
  if (upTo) {
120562
121202
  const s = upTo.findFirstExpression(abaplint.Expressions.SimpleSource3);
@@ -120623,14 +121263,25 @@ class SelectTranspiler {
120623
121263
  const faeTranspiled = new expressions_1.SQLSourceTranspiler().transpile(fn, traversal).getCode();
120624
121264
  // ABAP semantics: with an empty driving table the whole WHERE condition is ignored
120625
121265
  const selectEmpty = select.replace(whereClause, "");
120626
- select = select.replace(new RegExp(" " + escapeRegExp(faeTranspiled), "g"), " " + unique);
120627
- select = select.replace(unique + ".get().table_line.get()", unique + ".get()"); // there can be only one?
121266
+ const bindRow = (text) => text
121267
+ .replace(new RegExp(" " + escapeRegExp(faeTranspiled), "g"), " " + unique)
121268
+ .replace(unique + ".get().table_line.get()", unique + ".get()"); // there can be only one?
121269
+ select = bindRow(select);
121270
+ const where = bindRow(whereClause);
120628
121271
  // FOR ALL ENTRIES removes duplicate rows from the result: duplicates of
120629
121272
  // the selected columns, so de-duplicate by the target's components. The
120630
121273
  // DB key alone is wrong for projections (INTO CORRESPONDING FIELDS
120631
121274
  // without the key fields crashed on the missing component names)
120632
121275
  const by = `Object.keys(${target}.getRowType().get())`;
120633
- const code = `if (${faeTranspiled}.array().length === 0) {
121276
+ const dedup = `if (!(${target} instanceof abap.types.HashedTable) && ${target}.getOptions()?.primaryKey?.type !== "SORTED") {
121277
+ abap.statements.sort(${target}, {by: ${by}.map(k => { return {component: k}; })});
121278
+ await abap.statements.deleteInternal(${target}, {adjacent: true, allFields: true});
121279
+ }`;
121280
+ const at = where.startsWith("WHERE ") ? select.indexOf(where) : -1;
121281
+ // UP TO with ORDER BY keeps the first n rows in that order; the blocks
121282
+ // trim after the de-duplicating sort, so that pair stays row by row
121283
+ if (concat.startsWith("SELECT SINGLE ") || at < 0 || (upTo && orderBy)) {
121284
+ const code = `if (${faeTranspiled}.array().length === 0) {
120634
121285
  await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
120635
121286
  } else {
120636
121287
  const ${unique2} = ${faeTranspiled}.array();
@@ -120638,9 +121289,56 @@ class SelectTranspiler {
120638
121289
  for await (const ${unique} of ${unique2}) {
120639
121290
  await abap.statements.select(${target}, {select: "${select.trim()}"${extra}}, {appending: true});
120640
121291
  }
120641
- if (!(${target} instanceof abap.types.HashedTable) && ${target}.getOptions()?.primaryKey?.type !== "SORTED") {
120642
- abap.statements.sort(${target}, {by: ${by}.map(k => { return {component: k}; })});
120643
- await abap.statements.deleteInternal(${target}, {adjacent: true, allFields: true});
121292
+ ${dedup}
121293
+ abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
121294
+ }`;
121295
+ return new chunk_1.Chunk().append(code, node, traversal);
121296
+ }
121297
+ // One SELECT per block of driving rows, similar to the kernel's blocking
121298
+ // of FOR ALL ENTRIES (rsdb/max_blocking_factor): the condition of each row in
121299
+ // parentheses, joined with OR. Not one SELECT per row. UP TO n ROWS
121300
+ // counts the whole de-duplicated result, not each block (measured on
121301
+ // a 7.5x system: two driving rows and UP TO 3 give 3 rows).
121302
+ let tail = select.substring(at + where.length);
121303
+ let upToCode = "0";
121304
+ if (upTo) {
121305
+ const s = upTo.findFirstExpression(abaplint.Expressions.SimpleSource3);
121306
+ if (s) {
121307
+ const n = new expressions_1.SourceTranspiler(true).transpile(s, traversal).getCode();
121308
+ tail = tail.replace(`UP TO " + ${n} + " ROWS `, "");
121309
+ upToCode = `parseInt(${n}, 10)`;
121310
+ }
121311
+ else {
121312
+ tail = tail.replace(upTo.concatTokens() + " ", "");
121313
+ upToCode = String(parseInt(upTo.findFirstExpression(abaplint.Expressions.Integer)?.concatTokens() ?? "0", 10));
121314
+ }
121315
+ }
121316
+ const head = select.substring(0, at);
121317
+ const condition = where.substring("WHERE ".length).trimEnd();
121318
+ const unique3 = unique_identifier_1.UniqueIdentifier.get();
121319
+ const unique4 = unique_identifier_1.UniqueIdentifier.get();
121320
+ const code = `if (${faeTranspiled}.array().length === 0) {
121321
+ await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
121322
+ } else {
121323
+ const ${unique2} = ${faeTranspiled}.array();
121324
+ ${target}.clear();
121325
+ const ${unique3} = (${unique}) => "(${condition})";
121326
+ for (let ${unique4} = 0; ${unique4} < ${unique2}.length; ${unique4} += 50) {
121327
+ const ${unique4}where = ${unique2}.slice(${unique4}, ${unique4} + 50).map(${unique3}).join(" OR ");
121328
+ await abap.statements.select(${target}, {select: "${head}WHERE " + ${unique4}where + " ${tail.trim()}"${extra}}, {appending: true});
121329
+ }
121330
+ ${dedup}
121331
+ const ${unique4}max = ${upToCode};
121332
+ if (${unique4}max > 0 && ${target}.getArrayLength() > ${unique4}max) {
121333
+ if (${target} instanceof abap.types.HashedTable) {
121334
+ for (const ${unique4}row of ${target}.array().slice(${unique4}max)) {
121335
+ await abap.statements.deleteInternal(${target}, {fromValue: ${unique4}row});
121336
+ }
121337
+ } else {
121338
+ while (${target}.getArrayLength() > ${unique4}max) {
121339
+ ${target}.deleteIndex(${target}.getArrayLength() - 1);
121340
+ }
121341
+ }
120644
121342
  }
120645
121343
  abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
120646
121344
  }`;
@@ -120703,12 +121401,73 @@ exports.SelectTranspiler = SelectTranspiler;
120703
121401
 
120704
121402
  "use strict";
120705
121403
 
121404
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
121405
+ if (k2 === undefined) k2 = k;
121406
+ var desc = Object.getOwnPropertyDescriptor(m, k);
121407
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
121408
+ desc = { enumerable: true, get: function() { return m[k]; } };
121409
+ }
121410
+ Object.defineProperty(o, k2, desc);
121411
+ }) : (function(o, m, k, k2) {
121412
+ if (k2 === undefined) k2 = k;
121413
+ o[k2] = m[k];
121414
+ }));
121415
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
121416
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
121417
+ }) : function(o, v) {
121418
+ o["default"] = v;
121419
+ });
121420
+ var __importStar = (this && this.__importStar) || (function () {
121421
+ var ownKeys = function(o) {
121422
+ ownKeys = Object.getOwnPropertyNames || function (o) {
121423
+ var ar = [];
121424
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
121425
+ return ar;
121426
+ };
121427
+ return ownKeys(o);
121428
+ };
121429
+ return function (mod) {
121430
+ if (mod && mod.__esModule) return mod;
121431
+ var result = {};
121432
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
121433
+ __setModuleDefault(result, mod);
121434
+ return result;
121435
+ };
121436
+ })();
120706
121437
  Object.defineProperty(exports, "__esModule", ({ value: true }));
120707
121438
  exports.SelectOptionTranspiler = void 0;
121439
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
120708
121440
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
121441
+ const transpile_types_1 = __webpack_require__(/*! ../transpile_types */ "./node_modules/@abaplint/transpiler/build/src/transpile_types.js");
121442
+ const _selection_1 = __webpack_require__(/*! ./_selection */ "./node_modules/@abaplint/transpiler/build/src/statements/_selection.js");
120709
121443
  class SelectOptionTranspiler {
120710
- transpile(_node, _traversal) {
120711
- return new chunk_1.Chunk(`throw new Error("SelectOption, not supported, transpiler");`);
121444
+ transpile(node, traversal) {
121445
+ const variable = _selection_1.SelectionDefault.variable(node, traversal);
121446
+ const row = variable?.type instanceof abaplint.BasicTypes.TableType ? variable.type.getRowType() : undefined;
121447
+ const lowType = row instanceof abaplint.BasicTypes.StructureType ? row.getComponentByName("LOW") : undefined;
121448
+ if (variable === undefined || lowType === undefined) {
121449
+ // eg. FOR (dynamic)
121450
+ return new chunk_1.Chunk(`throw new Error("SelectOption, not supported, transpiler");`);
121451
+ }
121452
+ const { name, type } = variable;
121453
+ const ret = new chunk_1.Chunk().appendString("let " + name + " = " + transpile_types_1.TranspileTypes.toType(type) + ";");
121454
+ // DEFAULT low [TO high] [OPTION o] [SIGN s] is the first row of the table and
121455
+ // stays in the header line: I EQ, or I BT with TO, unless OPTION or SIGN say otherwise
121456
+ const low = _selection_1.SelectionDefault.after(node, "DEFAULT");
121457
+ if (low === undefined) {
121458
+ return ret;
121459
+ }
121460
+ const high = _selection_1.SelectionDefault.after(node, "TO");
121461
+ const option = _selection_1.SelectionDefault.after(node, "OPTION")?.concatTokens().toUpperCase() ?? (high ? "BT" : "EQ");
121462
+ const sign = _selection_1.SelectionDefault.after(node, "SIGN")?.concatTokens().toUpperCase() ?? "I";
121463
+ ret.appendString("\n" + name + ".get().sign.set('" + sign + "');");
121464
+ ret.appendString("\n" + name + ".get().option.set('" + option + "');");
121465
+ ret.appendString(_selection_1.SelectionDefault.set(node, name + ".get().low", lowType, low, traversal));
121466
+ if (high) {
121467
+ ret.appendString(_selection_1.SelectionDefault.set(node, name + ".get().high", lowType, high, traversal));
121468
+ }
121469
+ ret.appendString("\nabap.statements.append({source: " + name + "});");
121470
+ return ret;
120712
121471
  }
120713
121472
  }
120714
121473
  exports.SelectOptionTranspiler = SelectOptionTranspiler;
@@ -120854,9 +121613,17 @@ exports.SetCursorTranspiler = SetCursorTranspiler;
120854
121613
  Object.defineProperty(exports, "__esModule", ({ value: true }));
120855
121614
  exports.SetDatasetTranspiler = void 0;
120856
121615
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
121616
+ const _dataset_1 = __webpack_require__(/*! ./_dataset */ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js");
120857
121617
  class SetDatasetTranspiler {
120858
- transpile(_node, _traversal) {
120859
- return new chunk_1.Chunk(`throw new Error("SetDataset, not supported, transpiler");`);
121618
+ transpile(node, traversal) {
121619
+ const operands = new _dataset_1.DatasetOperands(node, traversal);
121620
+ const option = operands.after("POSITION") !== undefined
121621
+ ? "position: " + operands.after("POSITION")
121622
+ : "endOfFile: true";
121623
+ return new chunk_1.Chunk()
121624
+ .append("await abap.statements.setDataset(", node, traversal)
121625
+ .appendString(operands.first() + ", {" + option + "}")
121626
+ .append(");", node.getLastToken(), traversal);
120860
121627
  }
120861
121628
  }
120862
121629
  exports.SetDatasetTranspiler = SetDatasetTranspiler;
@@ -121800,9 +122567,21 @@ exports.TopOfPageTranspiler = TopOfPageTranspiler;
121800
122567
  Object.defineProperty(exports, "__esModule", ({ value: true }));
121801
122568
  exports.TransferTranspiler = void 0;
121802
122569
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
122570
+ const _dataset_1 = __webpack_require__(/*! ./_dataset */ "./node_modules/@abaplint/transpiler/build/src/statements/_dataset.js");
121803
122571
  class TransferTranspiler {
121804
- transpile(_node, _traversal) {
121805
- return new chunk_1.Chunk(`throw new Error("Transfer, not supported, transpiler");`);
122572
+ transpile(node, traversal) {
122573
+ const operands = new _dataset_1.DatasetOperands(node, traversal);
122574
+ const options = [];
122575
+ if (operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]) !== undefined) {
122576
+ options.push("length: " + operands.after("LENGTH", ["MAXIMUM", "ACTUAL"]));
122577
+ }
122578
+ if (operands.has("NO END OF LINE")) {
122579
+ options.push("noEndOfLine: true");
122580
+ }
122581
+ return new chunk_1.Chunk()
122582
+ .append("await abap.statements.transfer(", node, traversal)
122583
+ .appendString(operands.first() + ", " + operands.after("TO") + ", {" + options.join(", ") + "}")
122584
+ .append(");", node.getLastToken(), traversal);
121806
122585
  }
121807
122586
  }
121808
122587
  exports.TransferTranspiler = TransferTranspiler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.13.95",
3
+ "version": "2.13.96",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,8 +27,8 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.120.63",
31
- "@abaplint/transpiler": "^2.13.95",
30
+ "@abaplint/core": "^2.120.64",
31
+ "@abaplint/transpiler": "^2.13.96",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.6.2",
34
34
  "@types/progress": "^2.0.7",