@abaplint/transpiler-cli 2.13.79 → 2.13.81

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 +166 -28
  2. package/package.json +4 -4
package/build/bundle.js CHANGED
@@ -149,6 +149,24 @@ class FileOperations {
149
149
  }
150
150
  fs.rmSync(p, { recursive: true });
151
151
  }
152
+ /** posix + absolute make glob return forward slashed absolute paths on all
153
+ platforms, but on Windows in fully resolved UNC form, ie. //?/C:/foo.
154
+ path.relative() does not consider //?/C: and C: the same root, and would
155
+ return the full path instead of a relative one, so strip the prefix */
156
+ static stripNamespace(filename) {
157
+ if (filename.startsWith("//?/UNC/")) {
158
+ return "//" + filename.substring("//?/UNC/".length);
159
+ }
160
+ else if (filename.startsWith("//?/")) {
161
+ return filename.substring("//?/".length);
162
+ }
163
+ return filename;
164
+ }
165
+ static globSync(pattern) {
166
+ // backslashes are escape characters in glob patterns, always hand it forward slashes
167
+ const normalized = pattern.split(path.sep).join("/");
168
+ return glob.sync(normalized, { nodir: true, absolute: true, posix: true }).map(f => this.stripNamespace(f));
169
+ }
152
170
  static setupPLimit() {
153
171
  let concurrency = os.cpus().length;
154
172
  if (concurrency > 8) {
@@ -181,7 +199,7 @@ class FileOperations {
181
199
  const folders = Array.isArray(config.input_folder) ? config.input_folder : [config.input_folder];
182
200
  const filesToRead = [];
183
201
  for (const folder of folders) {
184
- for (const filename of glob.sync(folder + "/**", { nodir: true })) {
202
+ for (const filename of this.globSync(folder + "/**")) {
185
203
  if (inputFilters.length > 0 && inputFilters.some(a => a.test(filename)) === false) {
186
204
  skipped++;
187
205
  continue;
@@ -278,7 +296,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
278
296
  Object.defineProperty(exports, "__esModule", ({ value: true }));
279
297
  const fs = __importStar(__webpack_require__(/*! fs */ "fs"));
280
298
  const path = __importStar(__webpack_require__(/*! path */ "path"));
281
- const glob = __importStar(__webpack_require__(/*! glob */ "./node_modules/glob/dist/commonjs/index.min.js"));
282
299
  const childProcess = __importStar(__webpack_require__(/*! child_process */ "child_process"));
283
300
  const os = __importStar(__webpack_require__(/*! os */ "os"));
284
301
  const module_1 = __webpack_require__(/*! module */ "module");
@@ -327,7 +344,7 @@ async function loadLib(config) {
327
344
  const excludeFilters = (lib.exclude_filter ?? []).map(pattern => new RegExp(pattern, "i"));
328
345
  const filesToRead = [];
329
346
  for (const pattern of patterns) {
330
- for (const filename of glob.sync(dir + pattern, { nodir: true })) {
347
+ for (const filename of file_operations_1.FileOperations.globSync(dir + pattern)) {
331
348
  if (filename.endsWith(".clas.testclasses.abap")) {
332
349
  continue;
333
350
  }
@@ -36799,6 +36816,19 @@ class ValueBody {
36799
36816
  const message = "VALUE, source type CharacterType not compatible with StringType";
36800
36817
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, s.getFirstToken(), message));
36801
36818
  }
36819
+ else if (this.insertsUsingTableKey(targetType)) {
36820
+ // only STANDARD tables append the rows, and thus allow padding of shorter c and x values
36821
+ const row = this.characterOrHexLength(rowType);
36822
+ const source = this.characterOrHexLength(sourceType);
36823
+ if (row !== undefined
36824
+ && source !== undefined
36825
+ && row.abap === source.abap
36826
+ && row.length !== source.length) {
36827
+ const message = `VALUE, source type ${source.abap} LENGTH ${source.length} not compatible ` +
36828
+ `with row type ${row.abap} LENGTH ${row.length}`;
36829
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, s.getFirstToken(), message));
36830
+ }
36831
+ }
36802
36832
  }
36803
36833
  }
36804
36834
  if (letScoped === true) {
@@ -36812,6 +36842,25 @@ class ValueBody {
36812
36842
  }
36813
36843
  return targetType ? targetType : type;
36814
36844
  }
36845
+ /** SORTED and HASHED tables insert the constructed rows using the table key, which
36846
+ * requires the rows to be compatible with the row type. STANDARD tables only append
36847
+ * the rows, so shorter c and x values are padded on the right instead. */
36848
+ static insertsUsingTableKey(targetType) {
36849
+ if (!(targetType instanceof basic_1.TableType)) {
36850
+ return false;
36851
+ }
36852
+ const accessType = targetType.getAccessType();
36853
+ return accessType === basic_1.TableAccessType.sorted || accessType === basic_1.TableAccessType.hashed;
36854
+ }
36855
+ static characterOrHexLength(type) {
36856
+ if (type instanceof basic_1.CharacterType) {
36857
+ return { abap: "c", length: type.getLength() };
36858
+ }
36859
+ else if (type instanceof basic_1.HexType) {
36860
+ return { abap: "x", length: type.getLength() };
36861
+ }
36862
+ return undefined;
36863
+ }
36815
36864
  }
36816
36865
  exports.ValueBody = ValueBody;
36817
36866
  //# sourceMappingURL=value_body.js.map
@@ -69131,6 +69180,20 @@ class Table extends _abstract_object_1.AbstractObject {
69131
69180
  }
69132
69181
  return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.tableCategory;
69133
69182
  }
69183
+ getDeliveryClass() {
69184
+ var _a;
69185
+ if (this.parsedData === undefined) {
69186
+ this.parseXML();
69187
+ }
69188
+ return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.deliveryClass;
69189
+ }
69190
+ getSizeCategory() {
69191
+ var _a;
69192
+ if (this.parsedData === undefined) {
69193
+ this.parseXML();
69194
+ }
69195
+ return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sizeCategory;
69196
+ }
69134
69197
  getEnhancementCategory() {
69135
69198
  var _a;
69136
69199
  if (this.parsedData === undefined) {
@@ -69158,7 +69221,7 @@ class Table extends _abstract_object_1.AbstractObject {
69158
69221
  return false;
69159
69222
  }
69160
69223
  parseXML() {
69161
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
69224
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
69162
69225
  const parsed = super.parseRaw2();
69163
69226
  if (parsed === undefined) {
69164
69227
  return;
@@ -69178,8 +69241,10 @@ class Table extends _abstract_object_1.AbstractObject {
69178
69241
  this.parsedData.tableCategory = (_m = (_l = (_k = (_j = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _j === void 0 ? void 0 : _j["asx:abap"]) === null || _k === void 0 ? void 0 : _k["asx:values"]) === null || _l === void 0 ? void 0 : _l.DD02V) === null || _m === void 0 ? void 0 : _m.TABCLASS;
69179
69242
  this.parsedData.description = (_r = (_q = (_p = (_o = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _o === void 0 ? void 0 : _o["asx:abap"]) === null || _p === void 0 ? void 0 : _p["asx:values"]) === null || _q === void 0 ? void 0 : _q.DD02V) === null || _r === void 0 ? void 0 : _r.DDTEXT;
69180
69243
  this.parsedData.dataClass = (_v = (_u = (_t = (_s = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _s === void 0 ? void 0 : _s["asx:abap"]) === null || _t === void 0 ? void 0 : _t["asx:values"]) === null || _u === void 0 ? void 0 : _u.DD09L) === null || _v === void 0 ? void 0 : _v.TABART;
69244
+ this.parsedData.deliveryClass = (_z = (_y = (_x = (_w = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _w === void 0 ? void 0 : _w["asx:abap"]) === null || _x === void 0 ? void 0 : _x["asx:values"]) === null || _y === void 0 ? void 0 : _y.DD02V) === null || _z === void 0 ? void 0 : _z.CONTFLAG;
69245
+ this.parsedData.sizeCategory = (_3 = (_2 = (_1 = (_0 = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _0 === void 0 ? void 0 : _0["asx:abap"]) === null || _1 === void 0 ? void 0 : _1["asx:values"]) === null || _2 === void 0 ? void 0 : _2.DD09L) === null || _3 === void 0 ? void 0 : _3.TABKAT;
69181
69246
  // fields
69182
- const fields = (_y = (_x = (_w = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _w === void 0 ? void 0 : _w["asx:abap"]) === null || _x === void 0 ? void 0 : _x["asx:values"]) === null || _y === void 0 ? void 0 : _y.DD03P_TABLE;
69247
+ const fields = (_6 = (_5 = (_4 = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _4 === void 0 ? void 0 : _4["asx:abap"]) === null || _5 === void 0 ? void 0 : _5["asx:values"]) === null || _6 === void 0 ? void 0 : _6.DD03P_TABLE;
69183
69248
  for (const field of (0, xml_utils_1.xmlToArray)(fields === null || fields === void 0 ? void 0 : fields.DD03P)) {
69184
69249
  if (typeof (field === null || field === void 0 ? void 0 : field.FIELDNAME) !== "string") {
69185
69250
  continue;
@@ -69203,13 +69268,13 @@ class Table extends _abstract_object_1.AbstractObject {
69203
69268
  });
69204
69269
  }
69205
69270
  // secondary indexes
69206
- const indexes = (_1 = (_0 = (_z = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _z === void 0 ? void 0 : _z["asx:abap"]) === null || _0 === void 0 ? void 0 : _0["asx:values"]) === null || _1 === void 0 ? void 0 : _1.DD12V;
69271
+ const indexes = (_9 = (_8 = (_7 = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _7 === void 0 ? void 0 : _7["asx:abap"]) === null || _8 === void 0 ? void 0 : _8["asx:values"]) === null || _9 === void 0 ? void 0 : _9.DD12V;
69207
69272
  ;
69208
69273
  this.parsedData.secondaryIndexes = [];
69209
69274
  for (const index of (0, xml_utils_1.xmlToArray)(indexes === null || indexes === void 0 ? void 0 : indexes.DD12V)) {
69210
69275
  const indexName = index.INDEXNAME;
69211
69276
  const indexFields = [];
69212
- const indexFieldsXml = (_4 = (_3 = (_2 = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _2 === void 0 ? void 0 : _2["asx:abap"]) === null || _3 === void 0 ? void 0 : _3["asx:values"]) === null || _4 === void 0 ? void 0 : _4.DD17V;
69277
+ const indexFieldsXml = (_12 = (_11 = (_10 = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _10 === void 0 ? void 0 : _10["asx:abap"]) === null || _11 === void 0 ? void 0 : _11["asx:values"]) === null || _12 === void 0 ? void 0 : _12.DD17V;
69213
69278
  for (const indexField of (0, xml_utils_1.xmlToArray)(indexFieldsXml === null || indexFieldsXml === void 0 ? void 0 : indexFieldsXml.DD17V)) {
69214
69279
  if (indexField.INDEXNAME === indexName) {
69215
69280
  // assumption: fields are listed by POSITION in the xml
@@ -70747,7 +70812,7 @@ class Registry {
70747
70812
  }
70748
70813
  static abaplintVersion() {
70749
70814
  // magic, see build script "version.js"
70750
- return "2.120.44";
70815
+ return "2.120.45";
70751
70816
  }
70752
70817
  getDDICReferences() {
70753
70818
  return this.ddicReferences;
@@ -86120,6 +86185,7 @@ exports.LineBreakStyle = exports.LineBreakStyleConf = void 0;
86120
86185
  const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
86121
86186
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
86122
86187
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
86188
+ const objects_1 = __webpack_require__(/*! ../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
86123
86189
  class LineBreakStyleConf extends _basic_rule_config_1.BasicRuleConfig {
86124
86190
  }
86125
86191
  exports.LineBreakStyleConf = LineBreakStyleConf;
@@ -86130,10 +86196,11 @@ class LineBreakStyle {
86130
86196
  getMetadata() {
86131
86197
  return {
86132
86198
  key: "line_break_style",
86133
- title: "Makes sure line breaks are consistent in the ABAP code",
86134
- shortDescription: `Enforces LF as newlines in ABAP files
86199
+ title: "Makes sure line breaks are consistent",
86200
+ shortDescription: `Enforces LF as newlines in ABAP and XML files
86135
86201
 
86136
86202
  abapGit does not work with CRLF`,
86203
+ extendedInformation: `SMIM and W3MI files are not checked.`,
86137
86204
  tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.SingleFile],
86138
86205
  };
86139
86206
  }
@@ -86148,8 +86215,15 @@ abapGit does not work with CRLF`,
86148
86215
  }
86149
86216
  run(obj) {
86150
86217
  const output = [];
86218
+ if (obj instanceof objects_1.MIMEObject || obj instanceof objects_1.WebMIME) {
86219
+ return output;
86220
+ }
86151
86221
  for (const file of obj.getFiles()) {
86152
- if (file.getFilename().endsWith(".abap")) {
86222
+ const filename = file.getFilename();
86223
+ if (filename.endsWith(".abap") || filename.endsWith(".xml")) {
86224
+ if (filename.endsWith(".xslt.source.xml")) {
86225
+ continue;
86226
+ }
86153
86227
  const rows = file.getRawRows();
86154
86228
  for (let i = 0; i < rows.length; i++) {
86155
86229
  if (rows[i].endsWith("\r") === true) {
@@ -100675,6 +100749,7 @@ class XMLConsistency {
100675
100749
  * XML is well-formed and parseable
100676
100750
  * Naming for CLAS and INTF objects
100677
100751
  * QUAN fields in TABL objects have reference table and field values
100752
+ * Transparent TABL objects have delivery class and size category set
100678
100753
  * Lock parameter names in ENQU objects are max 16 characters
100679
100754
  * Texts and translations do not exceed maximum allowed length.`,
100680
100755
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
@@ -100933,15 +101008,25 @@ class XMLConsistency {
100933
101008
  return issues;
100934
101009
  }
100935
101010
  runTable(obj, file) {
100936
- var _a, _b;
100937
- var _c;
101011
+ var _a, _b, _c, _d;
101012
+ var _e;
100938
101013
  const issues = [];
100939
- for (const field of (_c = obj.getFields()) !== null && _c !== void 0 ? _c : []) {
101014
+ for (const field of (_e = obj.getFields()) !== null && _e !== void 0 ? _e : []) {
100940
101015
  if (field.DATATYPE === "QUAN" && (!((_a = field.REFTABLE) === null || _a === void 0 ? void 0 : _a.trim()) || !((_b = field.REFFIELD) === null || _b === void 0 ? void 0 : _b.trim()))) {
100941
101016
  const message = `QUAN field ${field.FIELDNAME} must have REFTABLE and REFFIELD set`;
100942
101017
  issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
100943
101018
  }
100944
101019
  }
101020
+ if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
101021
+ if (!((_c = obj.getDeliveryClass()) === null || _c === void 0 ? void 0 : _c.trim())) {
101022
+ const message = `Transparent table must have delivery class(CONTFLAG in DD02V) set`;
101023
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
101024
+ }
101025
+ if (!((_d = obj.getSizeCategory()) === null || _d === void 0 ? void 0 : _d.trim())) {
101026
+ const message = `Transparent table must have size category(TABKAT in DD09L) set`;
101027
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
101028
+ }
101029
+ }
100945
101030
  return issues;
100946
101031
  }
100947
101032
  }
@@ -105450,11 +105535,14 @@ const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/tr
105450
105535
  class MethodCallTranspiler {
105451
105536
  postName;
105452
105537
  method;
105453
- /** @param postName inserted between the method name and the parameters, eg. ".bind(this)"
105454
- * @param method the already resolved method reference, saves looking it up again */
105455
- constructor(postName = "", method) {
105538
+ discardResult;
105539
+ /** @param postName inserted between the method name and the parameters, eg. ".bind(this)"
105540
+ * @param method the already resolved method reference, saves looking it up again
105541
+ * @param discardResult the RETURNING value of this call is not consumed */
105542
+ constructor(postName = "", method, discardResult = false) {
105456
105543
  this.postName = postName;
105457
105544
  this.method = method;
105545
+ this.discardResult = discardResult;
105458
105546
  }
105459
105547
  transpile(node, traversal) {
105460
105548
  let post = "";
@@ -105465,7 +105553,8 @@ class MethodCallTranspiler {
105465
105553
  const scope = traversal.findCurrentScopeByToken(nameToken);
105466
105554
  const m = this.method ?? traversal.findMethodReference(nameToken, scope);
105467
105555
  let name = nameToken.getStr().toLowerCase();
105468
- if (traversal.isBuiltinMethod(nameToken)) {
105556
+ const isBuiltin = traversal.isBuiltinMethod(nameToken);
105557
+ if (isBuiltin) {
105469
105558
  // todo: this is not correct, the method name might be shadowed
105470
105559
  name = "abap.builtin." + name + "(";
105471
105560
  if (name === "abap.builtin.line_exists(" || name === "abap.builtin.line_index(") {
@@ -105499,9 +105588,14 @@ class MethodCallTranspiler {
105499
105588
  if (step === undefined) {
105500
105589
  throw new Error("MethodCallTranspiler, unexpected node");
105501
105590
  }
105591
+ // "IS SUPPLIED" on a RETURNING parameter is true when the call is functional,
105592
+ // the flag is only passed along when the value of this very call is consumed
105593
+ const returning = isBuiltin === true || this.discardResult === true
105594
+ ? undefined
105595
+ : m?.def.getParameters().getReturning()?.getName().toLowerCase();
105502
105596
  const ret = new chunk_1.Chunk();
105503
105597
  ret.append(name, nameToken, traversal);
105504
- ret.appendChunk(new method_call_param_1.MethodCallParamTranspiler(m?.def).transpile(step, traversal));
105598
+ ret.appendChunk(new method_call_param_1.MethodCallParamTranspiler(m?.def, returning).transpile(step, traversal));
105505
105599
  ret.appendString(post + ")");
105506
105600
  return ret;
105507
105601
  }
@@ -105614,9 +105708,17 @@ const traversal_1 = __webpack_require__(/*! ../traversal */ "./node_modules/@aba
105614
105708
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
105615
105709
  const method_call_1 = __webpack_require__(/*! ./method_call */ "./node_modules/@abaplint/transpiler/build/src/expressions/method_call.js");
105616
105710
  class MethodCallChainTranspiler {
105711
+ discardResult;
105712
+ /** @param discardResult the value of the last call in the chain is not consumed,
105713
+ * ie. the chain is a standalone CALL statement */
105714
+ constructor(discardResult = false) {
105715
+ this.discardResult = discardResult;
105716
+ }
105617
105717
  transpile(node, traversal) {
105618
105718
  let ret = new chunk_1.Chunk();
105619
105719
  const children = node.getChildren();
105720
+ const calls = node.findDirectExpressions(core_1.Expressions.MethodCall);
105721
+ const lastCall = calls[calls.length - 1];
105620
105722
  for (const c of children) {
105621
105723
  if (c instanceof core_1.Nodes.ExpressionNode && c.get() instanceof core_1.Expressions.MethodCall) {
105622
105724
  const isFirst = c === node.getFirstChild();
@@ -105634,9 +105736,10 @@ class MethodCallChainTranspiler {
105634
105736
  method = traversal.findMethodReference(nameToken, traversal.findCurrentScopeByToken(nameToken));
105635
105737
  prefix = traversal.constructorPrototypePrefix(nameToken, method?.def, enclosingClass);
105636
105738
  }
105739
+ const discard = this.discardResult === true && c === lastCall;
105637
105740
  const sub = prefix === undefined
105638
- ? traversal.traverse(c)
105639
- : new method_call_1.MethodCallTranspiler(".bind(this)", method).transpile(c, traversal);
105741
+ ? new method_call_1.MethodCallTranspiler("", undefined, discard).transpile(c, traversal)
105742
+ : new method_call_1.MethodCallTranspiler(".bind(this)", method, discard).transpile(c, traversal);
105640
105743
  if (sub.getCode().startsWith("abap.builtin.")
105641
105744
  || sub.getCode().startsWith("await abap.builtin.")) {
105642
105745
  ret.appendChunk(sub);
@@ -105719,32 +105822,43 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
105719
105822
  exports.MethodCallParamTranspiler = void 0;
105720
105823
  const core_1 = __webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js");
105721
105824
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
105825
+ const parameter_list_s_1 = __webpack_require__(/*! ./parameter_list_s */ "./node_modules/@abaplint/transpiler/build/src/expressions/parameter_list_s.js");
105722
105826
  class MethodCallParamTranspiler {
105723
105827
  m;
105724
- constructor(m) {
105828
+ suppliedReturning;
105829
+ /** On a real system "RETURNING IS SUPPLIED" is true exactly when the method is called
105830
+ * functionally, so the caller has to say so.
105831
+ * @param m the resolved method definition
105832
+ * @param suppliedReturning name of the RETURNING parameter to flag as supplied,
105833
+ * ie. the call is functional and the value is consumed */
105834
+ constructor(m, suppliedReturning) {
105725
105835
  this.m = m;
105836
+ this.suppliedReturning = suppliedReturning;
105726
105837
  }
105727
105838
  transpile(node, traversal) {
105728
105839
  let name = "";
105729
105840
  if (!(node.get() instanceof core_1.Expressions.MethodCallParam)) {
105730
105841
  throw new Error("MethodCallParam, unexpected node, " + node?.get().constructor.name);
105731
105842
  }
105843
+ // the RETURNING parameter is passed along when the call is functional, see the constructor
105844
+ const extra = this.suppliedReturning === undefined ? "" : this.suppliedReturning + ": 1";
105732
105845
  const source = node.findDirectExpression(core_1.Expressions.Source);
105733
105846
  if (source) {
105734
105847
  const def = this.m?.getParameters().getDefaultImporting()?.toLowerCase();
105735
105848
  if (this.m === undefined || def === undefined) {
105849
+ // the input is not an object, so there is nowhere to put the RETURNING flag
105736
105850
  return traversal.traverse(source);
105737
105851
  }
105738
105852
  else {
105739
105853
  return new chunk_1.Chunk()
105740
105854
  .appendString("{" + def + ": ")
105741
105855
  .appendChunk(traversal.traverse(source))
105742
- .appendString("}");
105856
+ .appendString(extra === "" ? "}" : ", " + extra + "}");
105743
105857
  }
105744
105858
  }
105745
105859
  const parameters = node.findDirectExpression(core_1.Expressions.ParameterListS);
105746
105860
  if (parameters) {
105747
- return traversal.traverse(parameters);
105861
+ return new parameter_list_s_1.ParameterListSTranspiler(extra).transpile(parameters, traversal);
105748
105862
  }
105749
105863
  else {
105750
105864
  const params = node.findDirectExpression(core_1.Expressions.MethodParameters);
@@ -105759,7 +105873,13 @@ class MethodCallParamTranspiler {
105759
105873
  }
105760
105874
  }
105761
105875
  name = name.replace(/}{/g, ", ");
105762
- return new chunk_1.Chunk(name);
105876
+ if (extra === "") {
105877
+ return new chunk_1.Chunk(name);
105878
+ }
105879
+ else if (name === "") {
105880
+ return new chunk_1.Chunk("{" + extra + "}");
105881
+ }
105882
+ return new chunk_1.Chunk(name.replace(/}$/, ", " + extra + "}"));
105763
105883
  }
105764
105884
  }
105765
105885
  exports.MethodCallParamTranspiler = MethodCallParamTranspiler;
@@ -106126,6 +106246,11 @@ exports.ParameterListSTranspiler = void 0;
106126
106246
  const core_1 = __webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js");
106127
106247
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
106128
106248
  class ParameterListSTranspiler {
106249
+ extra;
106250
+ /** @param extra appended as an additional field of the emitted object, eg. "result: 1" */
106251
+ constructor(extra = "") {
106252
+ this.extra = extra;
106253
+ }
106129
106254
  transpile(node, traversal) {
106130
106255
  const parameters = [];
106131
106256
  for (const c of node.getChildren()) {
@@ -106133,7 +106258,8 @@ class ParameterListSTranspiler {
106133
106258
  parameters.push(traversal.traverse(c));
106134
106259
  }
106135
106260
  }
106136
- return new chunk_1.Chunk().appendString("{").join(parameters).appendString("}");
106261
+ const post = this.extra === "" ? "}" : ", " + this.extra + "}";
106262
+ return new chunk_1.Chunk().appendString("{").join(parameters).appendString(post);
106137
106263
  }
106138
106264
  }
106139
106265
  exports.ParameterListSTranspiler = ParameterListSTranspiler;
@@ -111535,7 +111661,8 @@ class CallTranspiler {
111535
111661
  pre = build.pre + pre;
111536
111662
  post += build.post;
111537
111663
  }
111538
- const chainChunk = traversal.traverse(chain);
111664
+ // without RECEIVING the value of the last call in the chain is thrown away
111665
+ const chainChunk = new expressions_1.MethodCallChainTranspiler(receiving === undefined).transpile(chain, traversal);
111539
111666
  let chainCode = chainChunk.getCode();
111540
111667
  if (chainCode.startsWith("await super.constructor(")) {
111541
111668
  // semantics of constructors in JS vs ABAP is different, so the "constructor_" has been introduced,
@@ -116332,6 +116459,11 @@ class MethodImplementationTranspiler {
116332
116459
  }
116333
116460
  }
116334
116461
  else if (identifier.getMeta().includes("returning" /* abaplint.IdentifierMeta.MethodReturning */)) {
116462
+ // the caller flags a consumed RETURNING value in INPUT, see MethodCallParamTranspiler,
116463
+ // so "result IS SUPPLIED" needs the parameter even if the method has nothing else
116464
+ if (unique === "") {
116465
+ unique = "INPUT";
116466
+ }
116335
116467
  after = after + transpile_types_1.TranspileTypes.declare(identifier) + "\n";
116336
116468
  }
116337
116469
  }
@@ -118366,6 +118498,7 @@ class SelectTranspiler {
118366
118498
  throw new Error("SelectTranspiler, UNION DISTINCT todo");
118367
118499
  }
118368
118500
  let target = "undefined";
118501
+ let intoCorrespondingStructure = false;
118369
118502
  if (targetOverride) {
118370
118503
  // SelectLoop structure uses override
118371
118504
  target = targetOverride;
@@ -118377,7 +118510,9 @@ class SelectTranspiler {
118377
118510
  target = traversal.traverse(node.findFirstExpression(abaplint.Expressions.SQLIntoList)).getCode();
118378
118511
  }
118379
118512
  else if (node.findFirstExpression(abaplint.Expressions.SQLIntoStructure)) {
118380
- target = traversal.traverse(node.findFirstExpression(abaplint.Expressions.SQLIntoStructure)).getCode();
118513
+ const into = node.findFirstExpression(abaplint.Expressions.SQLIntoStructure);
118514
+ target = traversal.traverse(into).getCode();
118515
+ intoCorrespondingStructure = into.findDirectTokenByText("CORRESPONDING") !== undefined;
118381
118516
  }
118382
118517
  const tokens = node.getTokens();
118383
118518
  const isDistinct = tokens[0]?.getStr().toUpperCase() === "SELECT"
@@ -118455,6 +118590,9 @@ class SelectTranspiler {
118455
118590
  if (concat.includes(" APPENDING TABLE ") || concat.includes(" APPENDING CORRESPONDING FIELDS OF TABLE ")) {
118456
118591
  runtimeOptionsList.push(`appending: true`);
118457
118592
  }
118593
+ if (intoCorrespondingStructure) {
118594
+ runtimeOptionsList.push(`corresponding: true`);
118595
+ }
118458
118596
  if (runtimeOptionsList.length > 0) {
118459
118597
  runtimeOptions = `, {` + runtimeOptionsList.join(", ") + `}`;
118460
118598
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.13.79",
3
+ "version": "2.13.81",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,12 +27,12 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.120.44",
31
- "@abaplint/transpiler": "^2.13.79",
30
+ "@abaplint/core": "^2.120.45",
31
+ "@abaplint/transpiler": "^2.13.81",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.4.1",
34
34
  "@types/progress": "^2.0.7",
35
- "glob": "=13.0.6",
35
+ "glob": "^13.0.6",
36
36
  "p-limit": "^7.3.2",
37
37
  "progress": "^2.0.3",
38
38
  "ts-json-schema-generator": "^2.9.0",