@abaplint/transpiler-cli 2.13.40 → 2.13.42

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 +1058 -194
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -327,31 +327,34 @@ async function writeObjects(outputFiles, config, outputFolder, files) {
327
327
  const writeSourceMaps = config.write_source_map || false;
328
328
  const filesToWrite = [];
329
329
  for (const output of outputFiles) {
330
+ const type = output.object.type.toUpperCase();
330
331
  let contents = output.chunk.getCode();
332
+ // PROG output gets a runtime bootstrap line prepended, which shifts every
333
+ // generated line down by one - the source map must account for this offset
334
+ let generatedLineOffset = 0;
335
+ if (type === "PROG") {
336
+ // hmm, will this work for INCLUDEs ?
337
+ contents = `if (!globalThis.abap) await import("./_init.mjs");\n` + contents;
338
+ generatedLineOffset = 1;
339
+ }
331
340
  if (writeSourceMaps === true
332
- && output.object.type.toUpperCase() === "PROG"
333
- && output.object.type.toUpperCase() === "FUGR"
334
- && output.object.type.toUpperCase() === "CLAS") {
341
+ && (type === "PROG" || type === "FUGR" || type === "CLAS")) {
335
342
  const name = output.filename + ".map";
336
343
  // SourceMappingUrl needs to be percent-encoded, ref https://github.com/microsoft/TypeScript/issues/40951
337
344
  contents = contents + `\n//# sourceMappingURL=` + name.replace(/#/g, "%23");
338
- let map = output.chunk.getMap(output.filename);
339
- for (const f of files) { // hack the paths to the original files
345
+ // map the bare abap filename each mapping carries to its path on disk;
346
+ // source map "sources" are URLs, so always forward slashes, also on Windows
347
+ const sourcePaths = {};
348
+ for (const f of files) {
340
349
  if (f.relative === undefined) {
341
350
  continue;
342
351
  }
343
- if (map.includes(`"${f.filename}"`)) {
344
- let withPath = `"${f.relative}${path.sep}${f.filename}"`;
345
- withPath = withPath.replace(/\\/g, "\\\\");
346
- map = map.replace(`"${f.filename}"`, withPath);
347
- }
352
+ const rel = f.relative.split(path.sep).join("/");
353
+ sourcePaths[f.filename] = rel === "" ? f.filename : `${rel}/${f.filename}`;
348
354
  }
355
+ const map = output.chunk.getMap(output.filename, { generatedLineOffset, sourcePaths });
349
356
  filesToWrite.push({ path: outputFolder + path.sep + name, contents: map });
350
357
  }
351
- if (output.object.type.toUpperCase() === "PROG") {
352
- // hmm, will this work for INCLUDEs ?
353
- contents = `if (!globalThis.abap) await import("./_init.mjs");\n` + contents;
354
- }
355
358
  filesToWrite.push({ path: outputFolder + path.sep + output.filename, contents });
356
359
  }
357
360
  await file_operations_1.FileOperations.writeFiles(filesToWrite);
@@ -26425,7 +26428,7 @@ class CurrentScope {
26425
26428
  return this.reg.getConfig().getLanguageVersion();
26426
26429
  }
26427
26430
  getOpenABAP() {
26428
- return this.reg.getConfig().getOpenABAP();
26431
+ return this.reg.getConfig().isOpenABAP();
26429
26432
  }
26430
26433
  getRegistry() {
26431
26434
  return this.reg;
@@ -27376,6 +27379,7 @@ const basic_1 = __webpack_require__(/*! ../types/basic */ "./node_modules/@abapl
27376
27379
  const ddic_1 = __webpack_require__(/*! ../../ddic */ "./node_modules/@abaplint/core/build/src/ddic.js");
27377
27380
  const _object_oriented_1 = __webpack_require__(/*! ./_object_oriented */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_object_oriented.js");
27378
27381
  const _reference_1 = __webpack_require__(/*! ./_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
27382
+ const tokens_1 = __webpack_require__(/*! ../1_lexer/tokens */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js");
27379
27383
  class Procedural {
27380
27384
  constructor(reg, scope) {
27381
27385
  this.scope = scope;
@@ -27555,7 +27559,8 @@ class Procedural {
27555
27559
  continue;
27556
27560
  }
27557
27561
  else {
27558
- const type = new _typed_identifier_1.TypedIdentifier(nameToken, filename, found);
27562
+ const token = new tokens_1.Identifier(nameToken.getStart(), param.name);
27563
+ const type = new _typed_identifier_1.TypedIdentifier(token, filename, found, this.functionModuleParameterMeta(param));
27559
27564
  if (ignoreIfAlreadyExists === true) {
27560
27565
  const exists = this.scope.findVariable(param.name);
27561
27566
  if (exists === undefined) {
@@ -27569,6 +27574,25 @@ class Procedural {
27569
27574
  }
27570
27575
  }
27571
27576
  }
27577
+ functionModuleParameterMeta(param) {
27578
+ const ret = [];
27579
+ if (param.direction === types_1.FunctionModuleParameterDirection.importing) {
27580
+ ret.push("function_module_importing" /* IdentifierMeta.FunctionModuleImporting */);
27581
+ }
27582
+ else if (param.direction === types_1.FunctionModuleParameterDirection.exporting) {
27583
+ ret.push("function_module_exporting" /* IdentifierMeta.FunctionModuleExporting */);
27584
+ }
27585
+ else if (param.direction === types_1.FunctionModuleParameterDirection.changing) {
27586
+ ret.push("function_module_changing" /* IdentifierMeta.FunctionModuleChanging */);
27587
+ }
27588
+ else if (param.direction === types_1.FunctionModuleParameterDirection.tables) {
27589
+ ret.push("function_module_tables" /* IdentifierMeta.FunctionModuleTables */);
27590
+ }
27591
+ if (param.passByValue) {
27592
+ ret.push("pass_by_value" /* IdentifierMeta.PassByValue */);
27593
+ }
27594
+ return ret;
27595
+ }
27572
27596
  }
27573
27597
  exports.Procedural = Procedural;
27574
27598
  //# sourceMappingURL=_procedural.js.map
@@ -27999,7 +28023,8 @@ class TypeUtils {
27999
28023
  console.dir(target);
28000
28024
  console.dir(calculated);
28001
28025
  */
28002
- if (calculated && source instanceof basic_1.StringType && target instanceof basic_1.XStringType) {
28026
+ if (calculated && source instanceof basic_1.StringType
28027
+ && (target instanceof basic_1.XStringType || target instanceof basic_1.XSequenceType)) {
28003
28028
  return false;
28004
28029
  }
28005
28030
  if (calculated) {
@@ -29428,6 +29453,75 @@ exports.BasicTypes = BasicTypes;
29428
29453
 
29429
29454
  /***/ },
29430
29455
 
29456
+ /***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js"
29457
+ /*!*************************************************************************************************!*\
29458
+ !*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js ***!
29459
+ \*************************************************************************************************/
29460
+ (__unused_webpack_module, exports, __webpack_require__) {
29461
+
29462
+ "use strict";
29463
+
29464
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
29465
+ if (k2 === undefined) k2 = k;
29466
+ var desc = Object.getOwnPropertyDescriptor(m, k);
29467
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
29468
+ desc = { enumerable: true, get: function() { return m[k]; } };
29469
+ }
29470
+ Object.defineProperty(o, k2, desc);
29471
+ }) : (function(o, m, k, k2) {
29472
+ if (k2 === undefined) k2 = k;
29473
+ o[k2] = m[k];
29474
+ }));
29475
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29476
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29477
+ }) : function(o, v) {
29478
+ o["default"] = v;
29479
+ });
29480
+ var __importStar = (this && this.__importStar) || (function () {
29481
+ var ownKeys = function(o) {
29482
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29483
+ var ar = [];
29484
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29485
+ return ar;
29486
+ };
29487
+ return ownKeys(o);
29488
+ };
29489
+ return function (mod) {
29490
+ if (mod && mod.__esModule) return mod;
29491
+ var result = {};
29492
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
29493
+ __setModuleDefault(result, mod);
29494
+ return result;
29495
+ };
29496
+ })();
29497
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
29498
+ exports.checkOffsetLength = checkOffsetLength;
29499
+ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
29500
+ const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
29501
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
29502
+ const _builtin_1 = __webpack_require__(/*! ../_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
29503
+ // Offsets or lengths cannot be specified for STRING or XSTRING fields
29504
+ // passed as a method parameter source. Returns true if an issue was reported.
29505
+ function checkOffsetLength(source, sourceType, method, input) {
29506
+ const chain = source.findDirectExpression(Expressions.FieldChain);
29507
+ const isCalculated = source.findDirectExpression(Expressions.Source) !== undefined;
29508
+ const hasOffsetOrLength = chain !== undefined
29509
+ && isCalculated === false
29510
+ && (chain.findDirectExpression(Expressions.FieldOffset) !== undefined
29511
+ || chain.findDirectExpression(Expressions.FieldLength) !== undefined);
29512
+ if (hasOffsetOrLength
29513
+ && !(method instanceof _builtin_1.BuiltInMethod)
29514
+ && (sourceType instanceof basic_1.StringType || sourceType instanceof basic_1.XStringType)) {
29515
+ const message = `Offsets or lengths cannot be specified for fields of type "STRING" or "XSTRING" in the current statement`;
29516
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
29517
+ return true;
29518
+ }
29519
+ return false;
29520
+ }
29521
+ //# sourceMappingURL=_check_offset_length.js.map
29522
+
29523
+ /***/ },
29524
+
29431
29525
  /***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_chain.js"
29432
29526
  /*!********************************************************************************************!*\
29433
29527
  !*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/attribute_chain.js ***!
@@ -32572,6 +32666,7 @@ const source_1 = __webpack_require__(/*! ./source */ "./node_modules/@abaplint/c
32572
32666
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
32573
32667
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
32574
32668
  const constant_1 = __webpack_require__(/*! ./constant */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/constant.js");
32669
+ const _check_offset_length_1 = __webpack_require__(/*! ./_check_offset_length */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js");
32575
32670
  class MethodCallParam {
32576
32671
  static runSyntax(node, input, method) {
32577
32672
  if (!(node.get() instanceof Expressions.MethodCallParam)) {
@@ -32632,6 +32727,9 @@ class MethodCallParam {
32632
32727
  let sourceType = undefined;
32633
32728
  if (child.get() instanceof Expressions.Source) {
32634
32729
  sourceType = source_1.Source.runSyntax(child, input, targetType);
32730
+ if ((0, _check_offset_length_1.checkOffsetLength)(child, sourceType, method, input)) {
32731
+ return;
32732
+ }
32635
32733
  }
32636
32734
  else if (child.get() instanceof Expressions.ConstantString) {
32637
32735
  sourceType = constant_1.Constant.runSyntax(child);
@@ -32888,6 +32986,7 @@ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modu
32888
32986
  const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/assert_error.js");
32889
32987
  const field_chain_1 = __webpack_require__(/*! ./field_chain */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/field_chain.js");
32890
32988
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
32989
+ const _check_offset_length_1 = __webpack_require__(/*! ./_check_offset_length */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js");
32891
32990
  class MethodParameters {
32892
32991
  constructor() {
32893
32992
  this.requiredParameters = undefined;
@@ -33058,7 +33157,6 @@ class MethodParameters {
33058
33157
  }
33059
33158
  }
33060
33159
  parameterListS(node, input, method) {
33061
- var _a;
33062
33160
  if (node === undefined) {
33063
33161
  return [];
33064
33162
  }
@@ -33066,14 +33164,21 @@ class MethodParameters {
33066
33164
  throw new assert_error_1.AssertError("parameterListS, unexpected node");
33067
33165
  }
33068
33166
  const ret = [];
33167
+ const supplied = new Set();
33069
33168
  for (const c of node.getChildren()) {
33070
33169
  if (!(c.get() instanceof Expressions.ParameterS) || !(c instanceof nodes_1.ExpressionNode)) {
33071
33170
  throw new assert_error_1.AssertError("parameterListS, unexpected node, child");
33072
33171
  }
33073
- const name = (_a = c.findDirectExpression(Expressions.ParameterName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr().toUpperCase();
33074
- if (name === undefined) {
33172
+ const nameNode = c.findDirectExpression(Expressions.ParameterName);
33173
+ const name = nameNode === null || nameNode === void 0 ? void 0 : nameNode.getFirstToken().getStr().toUpperCase();
33174
+ if (name === undefined || nameNode === undefined) {
33075
33175
  throw new assert_error_1.AssertError("parameterListS, no name determined");
33076
33176
  }
33177
+ if (supplied.has(name)) {
33178
+ const message = `Method parameter "${name}" is supplied more than once`;
33179
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameNode.getFirstToken(), message));
33180
+ }
33181
+ supplied.add(name);
33077
33182
  const source = c.findDirectExpression(Expressions.Source);
33078
33183
  if (source === undefined) {
33079
33184
  throw new assert_error_1.AssertError("parameterListS, no source found");
@@ -33091,6 +33196,7 @@ class MethodParameters {
33091
33196
  targetType = method;
33092
33197
  }
33093
33198
  let sourceType = source_1.Source.runSyntax(source, input, targetType);
33199
+ (0, _check_offset_length_1.checkOffsetLength)(source, sourceType, method, input);
33094
33200
  if (sourceType === undefined) {
33095
33201
  if (method instanceof basic_1.VoidType) {
33096
33202
  sourceType = method;
@@ -33106,7 +33212,6 @@ class MethodParameters {
33106
33212
  return ret;
33107
33213
  }
33108
33214
  parameterListT(node, input) {
33109
- var _a;
33110
33215
  if (node === undefined) {
33111
33216
  return [];
33112
33217
  }
@@ -33114,14 +33219,21 @@ class MethodParameters {
33114
33219
  throw new assert_error_1.AssertError("parameterListT, unexpected node");
33115
33220
  }
33116
33221
  const ret = [];
33222
+ const supplied = new Set();
33117
33223
  for (const c of node.getChildren()) {
33118
33224
  if (!(c.get() instanceof Expressions.ParameterT) || !(c instanceof nodes_1.ExpressionNode)) {
33119
33225
  throw new assert_error_1.AssertError("parameterListT, unexpected node, child");
33120
33226
  }
33121
- const name = (_a = c.findDirectExpression(Expressions.ParameterName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr().toUpperCase();
33122
- if (name === undefined) {
33227
+ const nameNode = c.findDirectExpression(Expressions.ParameterName);
33228
+ const name = nameNode === null || nameNode === void 0 ? void 0 : nameNode.getFirstToken().getStr().toUpperCase();
33229
+ if (name === undefined || nameNode === undefined) {
33123
33230
  throw new assert_error_1.AssertError("parameterListT, no name determined");
33124
33231
  }
33232
+ if (supplied.has(name)) {
33233
+ const message = `Method parameter "${name}" is supplied more than once`;
33234
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameNode.getFirstToken(), message));
33235
+ }
33236
+ supplied.add(name);
33125
33237
  const target = c.findDirectExpression(Expressions.Target);
33126
33238
  if (target === undefined) {
33127
33239
  throw new assert_error_1.AssertError("parameterListT, no target found");
@@ -34352,7 +34464,7 @@ const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_module
34352
34464
  */
34353
34465
  // TODO: refactor all these method parameters to objects, this is getting messy
34354
34466
  class Source {
34355
- static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false) {
34467
+ static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false, readReference = true) {
34356
34468
  var _a;
34357
34469
  if (node === undefined) {
34358
34470
  return undefined;
@@ -34392,6 +34504,7 @@ class Source {
34392
34504
  else {
34393
34505
  this.addIfInferred(node, input, foundType);
34394
34506
  }
34507
+ this.traverseRemainingChildren(children, input);
34395
34508
  return foundType ? foundType : bodyType;
34396
34509
  }
34397
34510
  case "SWITCH":
@@ -34529,7 +34642,10 @@ class Source {
34529
34642
  return undefined;
34530
34643
  }
34531
34644
  let context = new unknown_type_1.UnknownType("todo, Source type");
34532
- const type = [_reference_1.ReferenceType.DataReadReference];
34645
+ const type = [];
34646
+ if (readReference) {
34647
+ type.push(_reference_1.ReferenceType.DataReadReference);
34648
+ }
34533
34649
  if (writeReference) {
34534
34650
  type.push(_reference_1.ReferenceType.DataWriteReference);
34535
34651
  }
@@ -37462,8 +37578,11 @@ const inline_data_1 = __webpack_require__(/*! ../expressions/inline_data */ "./n
37462
37578
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
37463
37579
  class CallTransformation {
37464
37580
  runSyntax(node, input) {
37581
+ const resultParameters = node.findExpressionAfterToken("RESULT");
37582
+ const resultSources = new Set((resultParameters === null || resultParameters === void 0 ? void 0 : resultParameters.findAllExpressions(Expressions.SimpleSource3)) || []);
37465
37583
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
37466
- source_1.Source.runSyntax(s, input);
37584
+ const isResult = resultSources.has(s);
37585
+ source_1.Source.runSyntax(s, input, undefined, isResult, false, isResult === false);
37467
37586
  }
37468
37587
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
37469
37588
  dynamic_1.Dynamic.runSyntax(d, input);
@@ -37645,14 +37764,14 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
37645
37764
  exports.Catch = void 0;
37646
37765
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
37647
37766
  const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
37648
- const unknown_type_1 = __webpack_require__(/*! ../../types/basic/unknown_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/unknown_type.js");
37649
37767
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
37650
37768
  const target_1 = __webpack_require__(/*! ../expressions/target */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/target.js");
37651
37769
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
37652
37770
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
37771
+ const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
37653
37772
  class Catch {
37654
37773
  runSyntax(node, input) {
37655
- var _a, _b;
37774
+ var _a;
37656
37775
  const names = new Set();
37657
37776
  for (const c of node.findDirectExpressions(Expressions.ClassName)) {
37658
37777
  const token = c.getFirstToken();
@@ -37668,7 +37787,6 @@ class Catch {
37668
37787
  else {
37669
37788
  const message = "CATCH, unknown class " + className;
37670
37789
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, message));
37671
- return;
37672
37790
  }
37673
37791
  if (names.has(className)) {
37674
37792
  const message = "Duplicate class name in CATCH: " + className;
@@ -37678,31 +37796,57 @@ class Catch {
37678
37796
  names.add(className);
37679
37797
  }
37680
37798
  const target = node.findDirectExpression(Expressions.Target);
37681
- const firstClassName = (_a = node.findDirectExpression(Expressions.ClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
37682
37799
  if (target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData)) {
37683
- const token = (_b = target.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.getFirstToken();
37684
- const found = input.scope.existsObject(firstClassName);
37685
- if (token && firstClassName && (found === null || found === void 0 ? void 0 : found.id)) {
37686
- const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, new basic_1.ObjectReferenceType(found.id), ["inline" /* IdentifierMeta.InlineDefinition */]);
37687
- input.scope.addIdentifier(identifier);
37688
- input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
37689
- }
37690
- else if (token && input.scope.getDDIC().inErrorNamespace(firstClassName) === false) {
37691
- const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, basic_1.VoidType.get(firstClassName), ["inline" /* IdentifierMeta.InlineDefinition */]);
37692
- input.scope.addIdentifier(identifier);
37693
- input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
37694
- }
37695
- else if (token) {
37696
- const message = "Catch, could not determine type for \"" + token.getStr() + "\"";
37697
- const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, new unknown_type_1.UnknownType(message), ["inline" /* IdentifierMeta.InlineDefinition */]);
37800
+ const token = (_a = target.findFirstExpression(Expressions.TargetField)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
37801
+ if (token) {
37802
+ const classNames = Array.from(names);
37803
+ const unknownClass = classNames.find(name => input.scope.findClassDefinition(name) === undefined);
37804
+ const commonSuperclass = unknownClass === undefined
37805
+ ? this.findCommonSuperclass(classNames, input)
37806
+ : undefined;
37807
+ const type = commonSuperclass
37808
+ ? new basic_1.ObjectReferenceType(commonSuperclass)
37809
+ : basic_1.VoidType.get(unknownClass || classNames.join(" "));
37810
+ const identifier = new _typed_identifier_1.TypedIdentifier(token, input.filename, type, ["inline" /* IdentifierMeta.InlineDefinition */]);
37698
37811
  input.scope.addIdentifier(identifier);
37699
37812
  input.scope.addReference(token, identifier, _reference_1.ReferenceType.DataWriteReference, input.filename);
37700
37813
  }
37701
37814
  }
37702
37815
  else if (target) {
37703
- target_1.Target.runSyntax(target, input);
37816
+ const targetType = target_1.Target.runSyntax(target, input);
37817
+ if (targetType instanceof basic_1.ObjectReferenceType) {
37818
+ for (const c of node.findDirectExpressions(Expressions.ClassName)) {
37819
+ const token = c.getFirstToken();
37820
+ const className = token.getStr().toUpperCase();
37821
+ const found = input.scope.existsObject(className);
37822
+ if (found === null || found === void 0 ? void 0 : found.id) {
37823
+ const catchType = new basic_1.ObjectReferenceType(found.id);
37824
+ if (new _type_utils_1.TypeUtils(input.scope).isAssignableStrict(catchType, targetType) === false) {
37825
+ const message = "CATCH target not compatible with " + className;
37826
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, message));
37827
+ return;
37828
+ }
37829
+ }
37830
+ }
37831
+ }
37704
37832
  }
37705
37833
  }
37834
+ findCommonSuperclass(classNames, input) {
37835
+ var _a;
37836
+ const lineages = [];
37837
+ for (const className of classNames) {
37838
+ const lineage = [];
37839
+ let current = input.scope.findClassDefinition(className);
37840
+ const visited = new Set();
37841
+ while (current && visited.has(current.getName().toUpperCase()) === false) {
37842
+ lineage.push(current);
37843
+ visited.add(current.getName().toUpperCase());
37844
+ current = input.scope.findClassDefinition(current.getSuperClass());
37845
+ }
37846
+ lineages.push(lineage);
37847
+ }
37848
+ return (_a = lineages[0]) === null || _a === void 0 ? void 0 : _a.find(candidate => lineages.every(lineage => lineage.some(item => item.getName().toUpperCase() === candidate.getName().toUpperCase())));
37849
+ }
37706
37850
  }
37707
37851
  exports.Catch = Catch;
37708
37852
  //# sourceMappingURL=catch.js.map
@@ -38421,6 +38565,11 @@ class Concatenate {
38421
38565
  runSyntax(node, input) {
38422
38566
  const byteMode = node.findDirectTokenByText("BYTE") !== undefined;
38423
38567
  const linesMode = node.findDirectTokenByText("LINES") !== undefined;
38568
+ if (node.findFirstExpression(Expressions.TableExpression) !== undefined) {
38569
+ const message = "CONCATENATE with table expression not possible";
38570
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
38571
+ return;
38572
+ }
38424
38573
  const target = node.findFirstExpression(Expressions.Target);
38425
38574
  const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
38426
38575
  if (inline) {
@@ -52015,6 +52164,7 @@ class FunctionModuleDefinition {
52015
52164
  type: param.TYP || param.DBFIELD,
52016
52165
  optional: param.OPTIONAL === "X",
52017
52166
  defaultValue: param.DEFAULT,
52167
+ passByValue: param.REFERENCE !== "X",
52018
52168
  });
52019
52169
  }
52020
52170
  }
@@ -52029,6 +52179,7 @@ class FunctionModuleDefinition {
52029
52179
  type: param.TYP || param.DBFIELD,
52030
52180
  optional: param.OPTIONAL === "X",
52031
52181
  defaultValue: param.DEFAULT,
52182
+ passByValue: param.REFERENCE !== "X",
52032
52183
  });
52033
52184
  }
52034
52185
  }
@@ -52043,6 +52194,7 @@ class FunctionModuleDefinition {
52043
52194
  type: param.TYP || param.DBFIELD,
52044
52195
  optional: true,
52045
52196
  defaultValue: undefined,
52197
+ passByValue: param.REFERENCE !== "X",
52046
52198
  });
52047
52199
  }
52048
52200
  }
@@ -52058,6 +52210,7 @@ class FunctionModuleDefinition {
52058
52210
  type: param.DBSTRUCT || param.TYP,
52059
52211
  optional: param.OPTIONAL === "X",
52060
52212
  defaultValue: undefined,
52213
+ passByValue: false,
52061
52214
  });
52062
52215
  }
52063
52216
  }
@@ -52910,14 +53063,14 @@ class MethodParameters {
52910
53063
  }
52911
53064
  }
52912
53065
  add(target, source, input, meta, abstractMethod) {
52913
- var _a, _b;
53066
+ var _a;
52914
53067
  for (const opt of source.findAllExpressions(Expressions.MethodParamOptional)) {
52915
53068
  const p = opt.findDirectExpression(Expressions.MethodParam);
52916
53069
  if (p === undefined) {
52917
53070
  continue;
52918
53071
  }
52919
53072
  const extraMeta = [];
52920
- if (p.getFirstToken().getStr().toUpperCase() === "VALUE" && ((_a = p.getChildren()[1]) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr()) === "(") {
53073
+ if (this.isPassByValue(p)) {
52921
53074
  extraMeta.push("pass_by_value" /* IdentifierMeta.PassByValue */);
52922
53075
  }
52923
53076
  else if (meta.includes("importing" /* IdentifierMeta.MethodImporting */)) {
@@ -52936,7 +53089,7 @@ class MethodParameters {
52936
53089
  else if (opt.findFirstExpression(Expressions.Default)) {
52937
53090
  const name = target[target.length - 1].getName().toUpperCase();
52938
53091
  this.optional.push(name);
52939
- const val = (_b = opt.findFirstExpression(Expressions.Default)) === null || _b === void 0 ? void 0 : _b.getLastChild();
53092
+ const val = (_a = opt.findFirstExpression(Expressions.Default)) === null || _a === void 0 ? void 0 : _a.getLastChild();
52940
53093
  if (val && val instanceof nodes_1.ExpressionNode) {
52941
53094
  this.defaults[name] = val;
52942
53095
  }
@@ -52947,9 +53100,15 @@ class MethodParameters {
52947
53100
  }
52948
53101
  const params = source.findAllExpressions(Expressions.MethodParam);
52949
53102
  for (const param of params) {
52950
- target.push(method_param_1.MethodParam.runSyntax(param, input, meta));
53103
+ const extraMeta = this.isPassByValue(param) ? ["pass_by_value" /* IdentifierMeta.PassByValue */] : [];
53104
+ target.push(method_param_1.MethodParam.runSyntax(param, input, [...meta, ...extraMeta]));
52951
53105
  }
52952
53106
  }
53107
+ isPassByValue(param) {
53108
+ var _a;
53109
+ return param.getFirstToken().getStr().toUpperCase() === "VALUE"
53110
+ && ((_a = param.getChildren()[1]) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr()) === "(";
53111
+ }
52953
53112
  }
52954
53113
  exports.MethodParameters = MethodParameters;
52955
53114
  //# sourceMappingURL=method_parameters.js.map
@@ -53556,7 +53715,7 @@ class CDSAggregate extends combi_1.Expression {
53556
53715
  getRunnable() {
53557
53716
  const fieldAsType = (0, combi_1.seq)(_1.CDSPrefixedName, "AS", _1.CDSType);
53558
53717
  const funcAsType = (0, combi_1.seq)(_1.CDSFunction, "AS", _1.CDSType);
53559
- const value = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSCast, _1.CDSCase, funcAsType, _1.CDSFunction, fieldAsType, _1.CDSPrefixedName, _1.CDSString, "*");
53718
+ const value = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSCast, _1.CDSCase, funcAsType, _1.CDSFunction, fieldAsType, _1.CDSPrefixedName, _1.CDSString, "*");
53560
53719
  return (0, combi_1.seq)((0, combi_1.altPrio)("MAX", "MIN", "SUM", "AVG", "COUNT"), "(", (0, combi_1.optPrio)((0, combi_1.altPrio)("DISTINCT", "ALL")), value, (0, combi_1.opt)((0, combi_1.seq)("AS", _1.CDSType)), ")");
53561
53720
  }
53562
53721
  }
@@ -53681,9 +53840,10 @@ class CDSAnnotationSimple extends combi_1.Expression {
53681
53840
  getRunnable() {
53682
53841
  const ident = (0, combi_1.regex)(/^[\w_]+$/);
53683
53842
  // #(expr) where expr can be: identifier, dotted path, string, or concatenation with +
53684
- const hashArg = (0, combi_1.altPrio)(_1.CDSString, cds_prefixed_name_1.CDSPrefixedName, ident);
53843
+ const funcCall = (0, combi_1.seq)(ident, "(", (0, combi_1.altPrio)(_1.CDSString, cds_prefixed_name_1.CDSPrefixedName, ident), ")");
53844
+ const hashArg = (0, combi_1.altPrio)(_1.CDSString, funcCall, cds_prefixed_name_1.CDSPrefixedName, ident);
53685
53845
  const hashExpr = (0, combi_1.seq)(hashArg, (0, combi_1.starPrio)((0, combi_1.seq)("+", hashArg)));
53686
- const value = (0, combi_1.altPrio)(_1.CDSString, "true", "false", "null", (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.regex)(/^\d+$/), (0, combi_1.seq)("#", "(", hashExpr, ")"), (0, combi_1.regex)(/^#[\w_]+$/));
53846
+ const value = (0, combi_1.altPrio)(_1.CDSString, "true", "false", "null", (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+[eE]$/), (0, combi_1.altPrio)("+", "-"), (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+[eE]$/), (0, combi_1.altPrio)("+", "-"), (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)("-", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.seq)((0, combi_1.regex)(/^\d+$/), ".", (0, combi_1.regex)(/^\d+$/)), (0, combi_1.regex)(/^\d+$/), (0, combi_1.seq)("#", "(", hashExpr, ")"), (0, combi_1.regex)(/^#[\w_]+$/));
53687
53847
  return value;
53688
53848
  }
53689
53849
  }
@@ -53841,9 +54001,9 @@ class CDSAssociation extends combi_1.Expression {
53841
54001
  const numericCardinality = (0, combi_1.seq)("[", cardNum, (0, combi_1.optPrio)((0, combi_1.seq)(".", ".", cardNum)), "]");
53842
54002
  // Text-based OF form: "association of one to many Target on ..." — text cardinality includes "TO"
53843
54003
  const ofTextSide = (0, combi_1.altPrio)((0, combi_1.seq)("EXACT", "ONE"), "ONE", "MANY");
53844
- const ofTextForm = (0, combi_1.seq)("ASSOCIATION", "OF", ofTextSide, "TO", ofTextSide, _1.CDSRelation, "ON", _1.CDSCondition);
54004
+ const ofTextForm = (0, combi_1.seq)("ASSOCIATION", "OF", ofTextSide, "TO", ofTextSide, _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
53845
54005
  // Numeric OF form: "association of [0..1] to Target on ..."
53846
- const ofNumericForm = (0, combi_1.seq)("ASSOCIATION", "OF", numericCardinality, "TO", _1.CDSRelation, "ON", _1.CDSCondition);
54006
+ const ofNumericForm = (0, combi_1.seq)("ASSOCIATION", "OF", numericCardinality, "TO", _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
53847
54007
  // "association [0..1] to Target as _Alias on condition" — standard form
53848
54008
  const parentForm = (0, combi_1.seq)("ASSOCIATION", "TO", "PARENT", _1.CDSRelation);
53849
54009
  const standardForm = (0, combi_1.seq)("ASSOCIATION", (0, combi_1.optPrio)(cds_cardinality_1.CDSCardinality), "TO", (0, combi_1.opt)((0, combi_1.altPrio)(textCardinality, "PARENT")), _1.CDSRelation, "ON", _1.CDSCondition, (0, combi_1.opt)((0, combi_1.seq)("WITH", "DEFAULT", "FILTER", _1.CDSCondition)));
@@ -53901,7 +54061,7 @@ class CDSCase extends combi_1.Expression {
53901
54061
  // CDSArithmetics is still tried after for arithmetic like (-1)*Amount or (2*A)-B.
53902
54062
  const caseParen = (0, combi_1.seq)("(", CDSCase, ")");
53903
54063
  const value = (0, combi_1.altPrio)(_1.CDSString, CDSCase, caseParen, _1.CDSArithmetics, _1.CDSCast, _1.CDSAggregate, _1.CDSArithParen, _1.CDSFunction, _1.CDSInteger, _1.CDSPrefixedName);
53904
- const simple = (0, combi_1.seq)((0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSFunction, _1.CDSPrefixedName), (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", value, "THEN", value)));
54064
+ const simple = (0, combi_1.seq)((0, combi_1.altPrio)(_1.CDSString, _1.CDSCast, _1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSFunction, _1.CDSPrefixedName), (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", value, "THEN", value)));
53905
54065
  const complex = (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", _1.CDSCondition, "THEN", value));
53906
54066
  return (0, combi_1.seq)("CASE", (0, combi_1.altPrio)(complex, simple), (0, combi_1.optPrio)((0, combi_1.seq)("ELSE", value)), "END");
53907
54067
  }
@@ -53926,7 +54086,7 @@ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node
53926
54086
  class CDSCast extends combi_1.Expression {
53927
54087
  getRunnable() {
53928
54088
  // CDSArithmetics before CDSFunction/CDSAggregate: handles function()*n, cast()*n, sum()*n patterns
53929
- const first = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSFunction, _1.CDSArithParen, _1.CDSCase, _1.CDSAggregate, CDSCast, _1.CDSString, _1.CDSPrefixedName, _1.CDSInteger);
54089
+ const first = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSFunction, _1.CDSArithParen, _1.CDSCase, _1.CDSAggregate, CDSCast, _1.CDSInteger, _1.CDSString, _1.CDSPrefixedName);
53930
54090
  return (0, combi_1.seq)("CAST", "(", first, "AS", _1.CDSType, (0, combi_1.optPrio)((0, combi_1.seq)("PRESERVING", "TYPE")), ")");
53931
54091
  }
53932
54092
  }
@@ -53951,8 +54111,9 @@ const cds_cardinality_1 = __webpack_require__(/*! ./cds_cardinality */ "./node_m
53951
54111
  class CDSComposition extends combi_1.Expression {
53952
54112
  getRunnable() {
53953
54113
  const num = (0, combi_1.altPrio)("ONE", "MANY");
53954
- // Text cardinality after OF: "of exact one to many", "of one to many", or bare "of many" / "of one"
53955
- const textCardinality = (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.opt)("EXACT"), num, "TO", num), (0, combi_1.seq)((0, combi_1.opt)("EXACT"), num));
54114
+ const exactNum = (0, combi_1.seq)((0, combi_1.opt)("EXACT"), num);
54115
+ // Text cardinality after OF: "of exact one to exact one", "of exact one to many", "of one to many", or bare "of many" / "of one"
54116
+ const textCardinality = (0, combi_1.altPrio)((0, combi_1.seq)(exactNum, "TO", exactNum), (0, combi_1.seq)((0, combi_1.opt)("EXACT"), num));
53956
54117
  // Numeric cardinality [n..m] before OF: any non-negative integer or *
53957
54118
  const cardNum = (0, combi_1.altPrio)((0, combi_1.regex)(/^\d+$/), "*");
53958
54119
  const numericCardinality = (0, combi_1.seq)("[", cardNum, (0, combi_1.optPrio)((0, combi_1.seq)(".", ".", cardNum)), "]");
@@ -53981,7 +54142,7 @@ class CDSCondition extends combi_1.Expression {
53981
54142
  getRunnable() {
53982
54143
  // CDSArithmetics before CDSCast/CDSFunction so cast(A)-cast(B) is handled as arithmetic, not two separate casts
53983
54144
  // CDSCase allows nested case expressions on either side of a comparison
53984
- const left = (0, combi_1.altPrio)(_1.CDSString, _1.CDSArithmetics, _1.CDSCast, _1.CDSFunction, _1.CDSAggregate, _1.CDSCase, _1.CDSArithParen, _1.CDSPrefixedName);
54145
+ const left = (0, combi_1.altPrio)(_1.CDSString, _1.CDSArithmetics, _1.CDSCast, _1.CDSFunction, _1.CDSAggregate, _1.CDSCase, _1.CDSArithParen, cds_integer_1.CDSInteger, _1.CDSPrefixedName);
53985
54146
  const nonLikeOperators = (0, combi_1.altPrio)("=", (0, combi_1.seq)("!", "="), (0, combi_1.seq)("<", ">"), (0, combi_1.seq)(">", "="), (0, combi_1.seq)("<", "="), "<", ">");
53986
54147
  const likeOperators = (0, combi_1.altPrio)("LIKE", "NOT LIKE");
53987
54148
  // Right side of comparison: simple values first, then parenthesized, then full arithmetic last.
@@ -54019,7 +54180,7 @@ class CDSDefineAbstract extends combi_1.Expression {
54019
54180
  getRunnable() {
54020
54181
  const field = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)((0, combi_1.str)("KEY")), cds_name_1.CDSName, ":", _1.CDSType, ";");
54021
54182
  const compsiOrAssoci = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), cds_name_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
54022
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "DEFINE", (0, combi_1.opt)("ROOT"), "ABSTRACT", "ENTITY", cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.alt)(field, compsiOrAssoci)), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
54183
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), "ABSTRACT", "ENTITY", cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.alt)(field, compsiOrAssoci)), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
54023
54184
  }
54024
54185
  }
54025
54186
  exports.CDSDefineAbstract = CDSDefineAbstract;
@@ -54045,7 +54206,7 @@ class CDSDefineCustom extends combi_1.Expression {
54045
54206
  getRunnable() {
54046
54207
  const field = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.str)("KEY")), cds_name_1.CDSName, ":", cds_type_1.CDSType, ";");
54047
54208
  const compsiOrAssoci = (0, combi_1.seq)(cds_name_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
54048
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("DEFINE"), (0, combi_1.opt)((0, combi_1.str)("ROOT")), (0, combi_1.str)("CUSTOM ENTITY"), cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, compsiOrAssoci))), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
54209
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)((0, combi_1.str)("DEFINE")), (0, combi_1.opt)((0, combi_1.str)("ROOT")), (0, combi_1.str)("CUSTOM ENTITY"), cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, compsiOrAssoci))), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
54049
54210
  }
54050
54211
  }
54051
54212
  exports.CDSDefineCustom = CDSDefineCustom;
@@ -54067,7 +54228,7 @@ const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src
54067
54228
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54068
54229
  class CDSDefineExternalEntity extends combi_1.Expression {
54069
54230
  getRunnable() {
54070
- const extNameValue = (0, combi_1.alt)(_1.CDSName, (0, combi_1.regex)(/^"[^"]*"$/));
54231
+ const extNameValue = (0, combi_1.alt)(_1.CDSName, (0, combi_1.regex)(/^"(?:[^"]|"")*"$/));
54071
54232
  const externalName = (0, combi_1.seq)("EXTERNAL", "NAME", extNameValue);
54072
54233
  const nullability = (0, combi_1.optPrio)((0, combi_1.alt)("NOT NULL", "NULL"));
54073
54234
  const field = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, nullability, (0, combi_1.optPrio)(externalName), ";");
@@ -54075,7 +54236,7 @@ class CDSDefineExternalEntity extends combi_1.Expression {
54075
54236
  const body = (0, combi_1.plus)((0, combi_1.alt)(field, assocOrComp));
54076
54237
  const externalEntity = (0, combi_1.seq)((0, combi_1.opt)("WRITABLE"), "EXTERNAL", "ENTITY", _1.CDSName, (0, combi_1.opt)(externalName), (0, combi_1.opt)(_1.CDSWithParameters));
54077
54238
  const staticEntity = (0, combi_1.seq)("STATIC", "ENTITY", _1.CDSName, (0, combi_1.opt)(externalName));
54078
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "DEFINE", (0, combi_1.alt)(externalEntity, staticEntity), (0, combi_1.str)("{"), body, (0, combi_1.str)("}"), (0, combi_1.opt)((0, combi_1.seq)("WITH", "FEDERATED", "DATA", (0, combi_1.optPrio)((0, combi_1.alt)((0, combi_1.seq)("PROVIDED", "AT", "RUNTIME"), (0, combi_1.seq)("PROVIDED", "BY", _1.CDSName))))), (0, combi_1.opt)(";"));
54239
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), (0, combi_1.alt)(externalEntity, staticEntity), (0, combi_1.str)("{"), body, (0, combi_1.str)("}"), (0, combi_1.opt)((0, combi_1.seq)("WITH", "FEDERATED", "DATA", (0, combi_1.optPrio)((0, combi_1.alt)((0, combi_1.seq)("PROVIDED", "AT", "RUNTIME"), (0, combi_1.seq)("PROVIDED", "BY", _1.CDSName))), (0, combi_1.optPrio)((0, combi_1.seq)("ON", "UNLINKED", (0, combi_1.altPrio)("FAIL", "IGNORE"))))), (0, combi_1.opt)(";"));
54079
54240
  }
54080
54241
  }
54081
54242
  exports.CDSDefineExternalEntity = CDSDefineExternalEntity;
@@ -54103,11 +54264,11 @@ class CDSDefineHierarchy extends combi_1.Expression {
54103
54264
  const siblingsOrder = (0, combi_1.seq)("SIBLINGS", "ORDER", "BY", siblingsOrderField, (0, combi_1.star)((0, combi_1.seq)(",", siblingsOrderField)));
54104
54265
  const directory = (0, combi_1.seq)("DIRECTORY", _1.CDSName, "FILTER", "BY", _1.CDSCondition);
54105
54266
  // DATE PERIOD: period from <field> to <field> [valid from :p to :p]
54106
- const datePeriod = (0, combi_1.seq)("PERIOD", "FROM", _1.CDSName, "TO", _1.CDSName, (0, combi_1.opt)((0, combi_1.seq)("VALID", "FROM", _1.CDSPrefixedName, "TO", _1.CDSPrefixedName)));
54267
+ const datePeriod = (0, combi_1.seq)("PERIOD", "FROM", _1.CDSName, "TO", _1.CDSName, (0, combi_1.opt)((0, combi_1.seq)("VALID", "FROM", (0, combi_1.altPrio)(_1.CDSString, _1.CDSPrefixedName), "TO", (0, combi_1.altPrio)(_1.CDSString, _1.CDSPrefixedName))));
54107
54268
  const depthValue = (0, combi_1.altPrio)(_1.CDSString, _1.CDSInteger, _1.CDSPrefixedName);
54108
54269
  const loadMode = (0, combi_1.altPrio)("BULK", "INCREMENTAL", _1.CDSPrefixedName);
54109
- const hierarchyBody = (0, combi_1.seq)("SOURCE", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), "CHILD", "TO", "PARENT", "ASSOCIATION", _1.CDSName, (0, combi_1.opt)(directory), (0, combi_1.opt)(datePeriod), (0, combi_1.opt)((0, combi_1.seq)("START", "WHERE", _1.CDSCondition)), (0, combi_1.opt)(siblingsOrder), (0, combi_1.opt)((0, combi_1.seq)("LOAD", loadMode)), (0, combi_1.opt)((0, combi_1.seq)("DEPTH", depthValue)), (0, combi_1.opt)((0, combi_1.seq)("NODETYPE", _1.CDSName)), (0, combi_1.opt)((0, combi_1.seq)("MULTIPLE", "PARENTS", (0, combi_1.altPrio)("NOT ALLOWED", "ALLOWED", (0, combi_1.seq)("LEAVES", (0, combi_1.optPrio)("ONLY"))))), (0, combi_1.opt)((0, combi_1.seq)("ORPHANS", (0, combi_1.altPrio)("IGNORE", "ROOT", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("CYCLES", (0, combi_1.altPrio)("BREAKUP", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("GENERATE", "SPANTREE")), (0, combi_1.opt)((0, combi_1.seq)("CACHE", (0, combi_1.altPrio)("ON", "OFF", "FORCE"))));
54110
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "DEFINE", "HIERARCHY", _1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), "AS", "PARENT", "CHILD", "HIERARCHY", "(", hierarchyBody, ")", "{", (0, combi_1.seq)(field, (0, combi_1.star)((0, combi_1.seq)(",", field))), "}", (0, combi_1.opt)(";"));
54270
+ const hierarchyBody = (0, combi_1.seq)("SOURCE", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), "CHILD", "TO", "PARENT", "ASSOCIATION", _1.CDSName, (0, combi_1.opt)((0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.opt)(directory), datePeriod, (0, combi_1.opt)(directory)), (0, combi_1.seq)(datePeriod, (0, combi_1.opt)(directory)), directory)), (0, combi_1.opt)((0, combi_1.seq)("START", "WHERE", _1.CDSCondition)), (0, combi_1.opt)(siblingsOrder), (0, combi_1.opt)((0, combi_1.seq)("DEPTH", depthValue)), (0, combi_1.opt)((0, combi_1.seq)("NODETYPE", _1.CDSName)), (0, combi_1.opt)((0, combi_1.seq)("LOAD", loadMode)), (0, combi_1.opt)((0, combi_1.seq)("MULTIPLE", "PARENTS", (0, combi_1.altPrio)("NOT ALLOWED", "ALLOWED", (0, combi_1.seq)("LEAVES", (0, combi_1.optPrio)("ONLY"))))), (0, combi_1.opt)((0, combi_1.seq)("ORPHANS", (0, combi_1.altPrio)("IGNORE", "ROOT", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("CYCLES", (0, combi_1.altPrio)("BREAKUP", "ERROR"))), (0, combi_1.opt)((0, combi_1.seq)("GENERATE", "SPANTREE")), (0, combi_1.opt)((0, combi_1.seq)("CACHE", (0, combi_1.altPrio)("ON", "OFF", "FORCE"))));
54271
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), "HIERARCHY", _1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), "AS", "PARENT", "CHILD", "HIERARCHY", "(", hierarchyBody, ")", "{", (0, combi_1.seq)(field, (0, combi_1.star)((0, combi_1.seq)(",", field))), "}", (0, combi_1.opt)(";"));
54111
54272
  }
54112
54273
  }
54113
54274
  exports.CDSDefineHierarchy = CDSDefineHierarchy;
@@ -54130,9 +54291,14 @@ const __1 = __webpack_require__(/*! ../.. */ "./node_modules/@abaplint/core/buil
54130
54291
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54131
54292
  class CDSDefineProjection extends combi_1.Expression {
54132
54293
  getRunnable() {
54133
- // redefine association _Assoc redirected to [composition child | parent] Entity
54134
- const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSName, "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
54135
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "DEFINE", (0, combi_1.opt)("ROOT"), (0, combi_1.opt)("TRANSIENT"), "VIEW", (0, combi_1.ver)(__1.Release.v755, (0, combi_1.opt)("ENTITY")), _1.CDSName, (0, combi_1.opt)(_1.CDSProviderContract), (0, combi_1.opt)(_1.CDSWithParameters), "AS PROJECTION ON", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, redefineAssoc)), (0, combi_1.str)("{"), (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), (0, combi_1.str)("}"), (0, combi_1.opt)(_1.CDSWhere), (0, combi_1.opt)(";"));
54294
+ const redefineCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY", _1.CDSInteger, "*");
54295
+ const redefineAssocFilter = (0, combi_1.seq)("[", (0, combi_1.optPrio)((0, combi_1.seq)(redefineCard, ":")), _1.CDSCondition, "]");
54296
+ const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSPrefixedName, (0, combi_1.optPrio)(redefineAssocFilter), (0, combi_1.opt)(_1.CDSAs), "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
54297
+ const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
54298
+ const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
54299
+ const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
54300
+ const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
54301
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("TRANSIENT"), (0, combi_1.opt)("ROOT"), "VIEW", (0, combi_1.ver)(__1.Release.v755, (0, combi_1.opt)("ENTITY")), _1.CDSName, (0, combi_1.opt)(_1.CDSProviderContract), (0, combi_1.opt)(_1.CDSWithParameters), "AS PROJECTION ON", _1.CDSName, (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, redefineAssoc)), (0, combi_1.starPrio)(bindAspect), (0, combi_1.str)("{"), (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), (0, combi_1.str)("}"), (0, combi_1.opt)(_1.CDSWhere), (0, combi_1.opt)(";"));
54136
54302
  }
54137
54303
  }
54138
54304
  exports.CDSDefineProjection = CDSDefineProjection;
@@ -54161,7 +54327,7 @@ class CDSDefineTableEntity extends combi_1.Expression {
54161
54327
  const elementList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
54162
54328
  const elements = (0, combi_1.seq)((0, combi_1.str)("{"), (0, combi_1.altPrio)("*", elementList), (0, combi_1.str)("}"));
54163
54329
  const selectBody = (0, combi_1.seq)("AS", "SELECT", "FROM", _1.CDSSource, (0, combi_1.star)(_1.CDSJoin), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSComposition, _1.CDSAssociation)), (0, combi_1.opt)(elements), (0, combi_1.optPrio)(_1.CDSWhere));
54164
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "DEFINE", (0, combi_1.opt)("ROOT"), "TABLE", "ENTITY", _1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.str)("{"), inlineBody, (0, combi_1.str)("}")), selectBody), (0, combi_1.opt)(";"));
54330
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), "TABLE", "ENTITY", _1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.str)("{"), inlineBody, (0, combi_1.str)("}")), selectBody), (0, combi_1.opt)(";"));
54165
54331
  }
54166
54332
  }
54167
54333
  exports.CDSDefineTableEntity = CDSDefineTableEntity;
@@ -54212,9 +54378,9 @@ const cds_with_parameters_1 = __webpack_require__(/*! ./cds_with_parameters */ "
54212
54378
  class CDSDefineView extends combi_1.Expression {
54213
54379
  getRunnable() {
54214
54380
  const columnAlias = (0, combi_1.seq)("(", cds_name_1.CDSName, (0, combi_1.star)((0, combi_1.seq)(",", cds_name_1.CDSName)), ")");
54215
- const parenSelect = (0, combi_1.seq)("(", cds_select_1.CDSSelect, ")");
54216
- const unionBranch = (0, combi_1.altPrio)(parenSelect, cds_select_1.CDSSelect);
54217
- const topLevelSelect = (0, combi_1.altPrio)((0, combi_1.seq)(parenSelect, (0, combi_1.star)((0, combi_1.altPrio)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), unionBranch), (0, combi_1.seq)("EXCEPT", unionBranch), (0, combi_1.seq)("INTERSECT", unionBranch)))), cds_select_1.CDSSelect);
54381
+ const unionBranch = (0, combi_1.altPrio)(_1.CDSParenSelect, cds_select_1.CDSSelect);
54382
+ const unionOps = (0, combi_1.star)((0, combi_1.altPrio)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), unionBranch), (0, combi_1.seq)("EXCEPT", unionBranch), (0, combi_1.seq)("INTERSECT", unionBranch)));
54383
+ const topLevelSelect = (0, combi_1.altPrio)((0, combi_1.seq)(_1.CDSParenSelect, unionOps), (0, combi_1.seq)(cds_select_1.CDSSelect, unionOps));
54218
54384
  return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.opt)("DEFINE"), (0, combi_1.opt)("ROOT"), (0, combi_1.opt)("WRITABLE"), "VIEW", (0, combi_1.ver)(__1.Release.v755, (0, combi_1.opt)("ENTITY")), cds_name_1.CDSName, (0, combi_1.opt)(columnAlias), (0, combi_1.opt)(cds_with_parameters_1.CDSWithParameters), "AS", topLevelSelect, (0, combi_1.opt)((0, combi_1.seq)("WITH", "HIERARCHY", cds_name_1.CDSName)), (0, combi_1.opt)(";"));
54219
54385
  }
54220
54386
  }
@@ -54239,16 +54405,16 @@ const cds_as_1 = __webpack_require__(/*! ./cds_as */ "./node_modules/@abaplint/c
54239
54405
  const cds_cast_1 = __webpack_require__(/*! ./cds_cast */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_cast.js");
54240
54406
  class CDSElement extends combi_1.Expression {
54241
54407
  getRunnable() {
54242
- const redirected = (0, combi_1.seq)(": REDIRECTED TO", (0, combi_1.optPrio)((0, combi_1.altPrio)("PARENT", "COMPOSITION CHILD")), _1.CDSName);
54408
+ const redirected = (0, combi_1.seq)(": REDIRECTED TO", (0, combi_1.optPrio)((0, combi_1.altPrio)("PARENT", "COMPOSITION CHILD")), _1.CDSName, (0, combi_1.optPrio)(_1.CDSParametersSelect));
54243
54409
  const colonThing = (0, combi_1.seq)(":", (0, combi_1.altPrio)(_1.CDSType, _1.CDSName, "LOCALIZED"));
54244
54410
  const extensionWildcard = (0, combi_1.seq)("$extension", ".", "*");
54245
54411
  const excludingNames = (0, combi_1.seq)(_1.CDSName, (0, combi_1.starPrio)((0, combi_1.seq)(",", _1.CDSName)));
54246
54412
  const excluding = (0, combi_1.seq)("EXCLUDING", "{", excludingNames, "}");
54247
- const includeElement = (0, combi_1.seq)("INCLUDE", _1.CDSPrefixedName, (0, combi_1.optPrio)(excluding), (0, combi_1.optPrio)("SIGNATURE ONLY"));
54413
+ const includeElement = (0, combi_1.seq)("INCLUDE", (0, combi_1.stopBefore1)("AS", "KEY", "VIRTUAL", "}"), _1.CDSPrefixedName, (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("SIGNATURE ONLY", (0, combi_1.optPrio)(excluding)), (0, combi_1.seq)(excluding, (0, combi_1.optPrio)("SIGNATURE ONLY")))));
54248
54414
  const typedVirtual = (0, combi_1.seq)("VIRTUAL", _1.CDSName, ":", _1.CDSType);
54249
54415
  const pathSegment = (0, combi_1.seq)(".", (0, combi_1.altPrio)(_1.CDSString, _1.CDSName, "*"), (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.CDSParametersSelect, _1.CDSParameters)));
54250
54416
  const funcWithPath = (0, combi_1.seq)(_1.CDSFunction, (0, combi_1.plusPrio)(pathSegment));
54251
- const body = (0, combi_1.altPrio)(extensionWildcard, includeElement, _1.CDSArithmetics, _1.CDSAggregate, _1.CDSString, _1.CDSArithParen, funcWithPath, _1.CDSFunction, cds_cast_1.CDSCast, _1.CDSCase, (0, combi_1.seq)("(", _1.CDSCase, ")"), (0, combi_1.seq)(_1.CDSPrefixedName, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.optPrio)((0, combi_1.altPrio)(redirected, colonThing))), _1.CDSInteger);
54417
+ const body = (0, combi_1.altPrio)(extensionWildcard, includeElement, _1.CDSArithmetics, _1.CDSAggregate, _1.CDSString, _1.CDSArithParen, funcWithPath, _1.CDSFunction, cds_cast_1.CDSCast, _1.CDSCase, (0, combi_1.seq)("(", _1.CDSCase, ")"), _1.CDSInteger, (0, combi_1.seq)(_1.CDSPrefixedName, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.optPrio)((0, combi_1.altPrio)(redirected, colonThing))));
54252
54418
  const elementBody = (0, combi_1.altPrio)(typedVirtual, (0, combi_1.seq)((0, combi_1.altPrio)("KEY", "VIRTUAL"), body), body);
54253
54419
  return (0, combi_1.seq)((0, combi_1.starPrio)(_1.CDSAnnotation), elementBody, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.starPrio)(_1.CDSAnnotation));
54254
54420
  }
@@ -54274,10 +54440,20 @@ class CDSExtendView extends combi_1.Expression {
54274
54440
  getRunnable() {
54275
54441
  const namedot = (0, combi_1.seq)(_1.CDSName, (0, combi_1.optPrio)((0, combi_1.seq)(".", _1.CDSName)), (0, combi_1.optPrio)(_1.CDSAs));
54276
54442
  const valueNested = (0, combi_1.seq)("{", namedot, (0, combi_1.star)((0, combi_1.seq)(",", namedot)), "}");
54277
- const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSPrefixedName, (0, combi_1.optPrio)((0, combi_1.seq)("[", _1.CDSCondition, "]")), (0, combi_1.opt)(_1.CDSAs), "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
54443
+ const redefineCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY", _1.CDSInteger, "*");
54444
+ const redefineAssocFilter = (0, combi_1.seq)("[", (0, combi_1.optPrio)((0, combi_1.seq)(redefineCard, ":")), _1.CDSCondition, "]");
54445
+ const redefineAssoc = (0, combi_1.seq)("REDEFINE", "ASSOCIATION", _1.CDSPrefixedName, (0, combi_1.optPrio)(redefineAssocFilter), (0, combi_1.opt)(_1.CDSAs), "REDIRECTED", "TO", (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)("COMPOSITION", "CHILD"), "PARENT")), _1.CDSName);
54278
54446
  const elementList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
54279
54447
  const elementNested = (0, combi_1.seq)("{", (0, combi_1.altPrio)("*", elementList), "}");
54280
- const extendView = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("EXTEND VIEW"), (0, combi_1.opt)((0, combi_1.str)("ENTITY")), _1.CDSName, (0, combi_1.str)("WITH"), (0, combi_1.opt)(_1.CDSName), (0, combi_1.star)(redefineAssoc), (0, combi_1.star)(_1.CDSAssociation), (0, combi_1.altPrio)(elementNested, valueNested), (0, combi_1.opt)(";"));
54448
+ const unionElemList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
54449
+ const unionBranchBody = (0, combi_1.seq)((0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.altPrio)("*", unionElemList), "}", (0, combi_1.optPrio)(_1.CDSGroupBy));
54450
+ const parenUnionBody = (0, combi_1.seq)("(", (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), "}", (0, combi_1.star)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), "{", (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(",")), "}")), ")");
54451
+ const unionSuffix = (0, combi_1.seq)((0, combi_1.optPrio)(_1.CDSGroupBy), (0, combi_1.star)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), (0, combi_1.altPrio)(parenUnionBody, unionBranchBody))));
54452
+ const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
54453
+ const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
54454
+ const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
54455
+ const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
54456
+ const extendView = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("EXTEND VIEW"), (0, combi_1.opt)((0, combi_1.str)("ENTITY")), _1.CDSName, (0, combi_1.str)("WITH"), (0, combi_1.opt)(_1.CDSName), (0, combi_1.star)(redefineAssoc), (0, combi_1.star)((0, combi_1.altPrio)(_1.CDSAssociation, _1.CDSComposition)), (0, combi_1.starPrio)(bindAspect), (0, combi_1.altPrio)(parenUnionBody, elementNested, valueNested), unionSuffix, (0, combi_1.opt)(";"));
54281
54457
  const field = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, ";");
54282
54458
  const assocOrComp = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), _1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
54283
54459
  const entityBody = (0, combi_1.seq)("{", (0, combi_1.plus)((0, combi_1.alt)(field, assocOrComp)), "}");
@@ -54357,6 +54533,7 @@ class CDSFunction extends combi_1.Expression {
54357
54533
  const occurrencesRegexpr = (0, combi_1.seq)("OCCURRENCES_REGEXPR", "(", conversionInputs, ")");
54358
54534
  const substrRegexpr = (0, combi_1.seq)("SUBSTR_REGEXPR", "(", conversionInputs, ")");
54359
54535
  const locateRegexpr = (0, combi_1.seq)("LOCATE_REGEXPR", "(", conversionInputs, ")");
54536
+ const sqrt = (0, combi_1.seq)("SQRT", "(", _1.CDSFunctionInput, ")");
54360
54537
  const extFuncName = (0, combi_1.regex)(/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/i);
54361
54538
  const genericArgs = (0, combi_1.seq)(_1.CDSFunctionInput, (0, combi_1.starPrio)((0, combi_1.seq)(",", _1.CDSFunctionInput)));
54362
54539
  const namedArgValue = (0, combi_1.altPrio)((0, combi_1.seq)("INTERVAL", _1.CDSFunctionInput, _1.CDSName), _1.CDSFunctionInput, _1.CDSName);
@@ -54364,7 +54541,7 @@ class CDSFunction extends combi_1.Expression {
54364
54541
  const namedArgColon = (0, combi_1.seq)(_1.CDSName, ":", namedArgValue);
54365
54542
  const namedArgs = (0, combi_1.seq)((0, combi_1.altPrio)(namedArgArrow, namedArgColon), (0, combi_1.starPrio)((0, combi_1.seq)(",", (0, combi_1.altPrio)(namedArgArrow, namedArgColon))));
54366
54543
  const genericFunc = (0, combi_1.seq)(extFuncName, "(", (0, combi_1.optPrio)((0, combi_1.altPrio)(namedArgs, genericArgs)), ")");
54367
- return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, upper, lower, abs, ceil, floor, round, div, division, concat_with_space, dats_is_valid, tims_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, utcl_current, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod, left, right, lpad, rpad, instr, length, ltrim, rtrim, replace, unitConversion, currencyConversion, decimalShift, fltp_to_dec, ratioOf, replaceRegexpr, matchesRegexpr, occurrencesRegexpr, substrRegexpr, locateRegexpr, curr_to_decfloat_amount, genericFunc);
54544
+ return (0, combi_1.altPrio)(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims, upper, lower, abs, ceil, floor, round, div, division, concat_with_space, dats_is_valid, tims_is_valid, dats_days_between, tstmp_add_seconds, tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, utcl_current, abap_system_timezone, abap_user_timezone, bintohex, hextobin, dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod, left, right, lpad, rpad, instr, length, ltrim, rtrim, replace, unitConversion, currencyConversion, decimalShift, fltp_to_dec, ratioOf, replaceRegexpr, matchesRegexpr, occurrencesRegexpr, substrRegexpr, locateRegexpr, curr_to_decfloat_amount, sqrt, genericFunc);
54368
54545
  }
54369
54546
  }
54370
54547
  exports.CDSFunction = CDSFunction;
@@ -54386,8 +54563,9 @@ const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src
54386
54563
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54387
54564
  class CDSFunctionInput extends combi_1.Expression {
54388
54565
  getRunnable() {
54389
- const input = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSCast, _1.CDSFunction, _1.CDSCase, _1.CDSString, _1.CDSPrefixedName, _1.CDSInteger);
54390
- return input;
54566
+ const positional = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSArithParen, _1.CDSAggregate, _1.CDSCast, _1.CDSFunction, _1.CDSCase, _1.CDSString, _1.CDSPrefixedName, _1.CDSInteger);
54567
+ const named = (0, combi_1.seq)(_1.CDSName, "=", ">", positional);
54568
+ return (0, combi_1.altPrio)(named, positional);
54391
54569
  }
54392
54570
  }
54393
54571
  exports.CDSFunctionInput = CDSFunctionInput;
@@ -54516,10 +54694,14 @@ exports.CDSJoin = CDSJoin;
54516
54694
  Object.defineProperty(exports, "__esModule", ({ value: true }));
54517
54695
  exports.CDSName = void 0;
54518
54696
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54697
+ const KEYWORDS = ["AS", "ON", "WHERE", "WITH", "UNION", "GROUP", "HAVING",
54698
+ "AND", "OR", "BETWEEN", "LIKE", "IN", "EXISTS",
54699
+ "WHEN", "THEN", "ELSE", "END", "CASE", "CAST"];
54519
54700
  class CDSName extends combi_1.Expression {
54520
54701
  getRunnable() {
54521
- const pre = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w_]+$/), "/");
54522
- return (0, combi_1.altPrio)((0, combi_1.regex)(/^"(?:[^"]|"")*"$/), (0, combi_1.seq)((0, combi_1.optPrio)(":"), (0, combi_1.optPrio)(pre), (0, combi_1.regex)(/^\$?#?[\w_]+$/)));
54702
+ const word = (0, combi_1.regex)(/^\$?#?[\w_]+$/);
54703
+ const slashName = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w]+$/), "/", (0, combi_1.stopBefore1)(...KEYWORDS), (0, combi_1.regex)(/^[\w_]+$/));
54704
+ return (0, combi_1.altPrio)((0, combi_1.regex)(/^"(?:[^"]|"")*"$/), (0, combi_1.seq)((0, combi_1.optPrio)(":"), slashName), (0, combi_1.seq)((0, combi_1.optPrio)(":"), word));
54523
54705
  }
54524
54706
  }
54525
54707
  exports.CDSName = CDSName;
@@ -54566,7 +54748,8 @@ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node
54566
54748
  class CDSParametersSelect extends combi_1.Expression {
54567
54749
  getRunnable() {
54568
54750
  const name = (0, combi_1.seq)(_1.CDSName, (0, combi_1.opt)((0, combi_1.seq)(".", _1.CDSName)));
54569
- const value = (0, combi_1.alt)(_1.CDSInteger, name, _1.CDSString);
54751
+ const typedLiteral = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
54752
+ const value = (0, combi_1.altPrio)(typedLiteral, _1.CDSInteger, name, _1.CDSString);
54570
54753
  const colonPair = (0, combi_1.seq)(name, ":", value, (0, combi_1.optPrio)("DEFAULT"));
54571
54754
  const arrowPair = (0, combi_1.seq)(name, "=", ">", value);
54572
54755
  const nameValue = (0, combi_1.altPrio)(colonPair, arrowPair);
@@ -54578,6 +54761,30 @@ exports.CDSParametersSelect = CDSParametersSelect;
54578
54761
 
54579
54762
  /***/ },
54580
54763
 
54764
+ /***/ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_paren_select.js"
54765
+ /*!***********************************************************************************!*\
54766
+ !*** ./node_modules/@abaplint/core/build/src/cds/expressions/cds_paren_select.js ***!
54767
+ \***********************************************************************************/
54768
+ (__unused_webpack_module, exports, __webpack_require__) {
54769
+
54770
+ "use strict";
54771
+
54772
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
54773
+ exports.CDSParenSelect = void 0;
54774
+ const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src/cds/expressions/index.js");
54775
+ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54776
+ class CDSParenSelect extends combi_1.Expression {
54777
+ getRunnable() {
54778
+ const unionBranch = (0, combi_1.altPrio)(CDSParenSelect, _1.CDSSelect);
54779
+ const unionOps = (0, combi_1.star)((0, combi_1.altPrio)((0, combi_1.seq)("UNION", (0, combi_1.opt)("ALL"), unionBranch), (0, combi_1.seq)("EXCEPT", unionBranch), (0, combi_1.seq)("INTERSECT", unionBranch)));
54780
+ return (0, combi_1.seq)("(", (0, combi_1.altPrio)((0, combi_1.seq)(CDSParenSelect, unionOps), (0, combi_1.seq)(_1.CDSSelect, unionOps)), ")");
54781
+ }
54782
+ }
54783
+ exports.CDSParenSelect = CDSParenSelect;
54784
+ //# sourceMappingURL=cds_paren_select.js.map
54785
+
54786
+ /***/ },
54787
+
54581
54788
  /***/ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_prefixed_name.js"
54582
54789
  /*!************************************************************************************!*\
54583
54790
  !*** ./node_modules/@abaplint/core/build/src/cds/expressions/cds_prefixed_name.js ***!
@@ -54590,10 +54797,10 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
54590
54797
  exports.CDSPrefixedName = void 0;
54591
54798
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54592
54799
  const cds_name_1 = __webpack_require__(/*! ./cds_name */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_name.js");
54800
+ const cds_integer_1 = __webpack_require__(/*! ./cds_integer */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_integer.js");
54593
54801
  const cds_parameters_1 = __webpack_require__(/*! ./cds_parameters */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_parameters.js");
54594
54802
  const cds_parameters_select_1 = __webpack_require__(/*! ./cds_parameters_select */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_parameters_select.js");
54595
54803
  const cds_condition_1 = __webpack_require__(/*! ./cds_condition */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_condition.js");
54596
- const cds_integer_1 = __webpack_require__(/*! ./cds_integer */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_integer.js");
54597
54804
  const cds_string_1 = __webpack_require__(/*! ./cds_string */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_string.js");
54598
54805
  class CDSPrefixedName extends combi_1.Expression {
54599
54806
  getRunnable() {
@@ -54603,13 +54810,17 @@ class CDSPrefixedName extends combi_1.Expression {
54603
54810
  const cardinalityJoin = (0, combi_1.seq)("[", cardSpec, ":", joinType, "]");
54604
54811
  const cardinalityJoinWhere = (0, combi_1.seq)("[", cardSpec, ":", joinType, "WHERE", cds_condition_1.CDSCondition, "]");
54605
54812
  const joinWhere = (0, combi_1.seq)("[", joinType, "WHERE", cds_condition_1.CDSCondition, "]");
54606
- const textCard = (0, combi_1.altPrio)("MANY TO EXACT ONE", "MANY TO ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY");
54813
+ const textCard = (0, combi_1.altPrio)("EXACT ONE TO EXACT ONE", "EXACT ONE TO MANY", "EXACT ONE TO ONE", "MANY TO EXACT ONE", "MANY TO MANY", "MANY TO ONE", "ONE TO EXACT ONE", "ONE TO MANY", "ONE TO ONE", "TO EXACT ONE", "TO ONE", "TO MANY");
54607
54814
  const textCardFilter = (0, combi_1.seq)("[", textCard, (0, combi_1.optPrio)((0, combi_1.seq)(":", (0, combi_1.altPrio)((0, combi_1.seq)(joinType, "WHERE", cds_condition_1.CDSCondition), joinType, cds_condition_1.CDSCondition))), "]");
54608
54815
  const cardNum = (0, combi_1.altPrio)(cds_integer_1.CDSInteger, "*");
54609
54816
  const rangeCard = (0, combi_1.seq)(cds_integer_1.CDSInteger, ".", ".", cardNum);
54610
54817
  const rangeCardFilter = (0, combi_1.seq)("[", rangeCard, ":", cds_condition_1.CDSCondition, "]");
54611
- const pathFilter = (0, combi_1.altPrio)(cardinalityJoinWhere, joinWhere, cardinalityJoin, joinRedirect, textCardFilter, rangeCardFilter, (0, combi_1.seq)("[", cardSpec, ":", cds_condition_1.CDSCondition, "]"), (0, combi_1.seq)("[", cds_condition_1.CDSCondition, "]"));
54612
- const segment = (0, combi_1.seq)(".", (0, combi_1.altPrio)(cds_string_1.CDSString, cds_name_1.CDSName, "*"), (0, combi_1.optPrio)((0, combi_1.altPrio)(cds_parameters_select_1.CDSParametersSelect, cds_parameters_1.CDSParameters)), (0, combi_1.optPrio)(pathFilter));
54818
+ const rangeOnly = (0, combi_1.seq)("[", rangeCard, "]");
54819
+ const numToText = (0, combi_1.seq)(cds_integer_1.CDSInteger, (0, combi_1.altPrio)("TO EXACT ONE", "TO ONE", "TO MANY"));
54820
+ const numTextCardFilter = (0, combi_1.seq)("[", numToText, (0, combi_1.optPrio)((0, combi_1.seq)(":", cds_condition_1.CDSCondition)), "]");
54821
+ const numToNum = (0, combi_1.seq)("[", cds_integer_1.CDSInteger, "TO", cds_integer_1.CDSInteger, (0, combi_1.optPrio)((0, combi_1.seq)(":", cds_condition_1.CDSCondition)), "]");
54822
+ const pathFilter = (0, combi_1.altPrio)(cardinalityJoinWhere, joinWhere, cardinalityJoin, joinRedirect, numToNum, numTextCardFilter, textCardFilter, rangeCardFilter, rangeOnly, (0, combi_1.seq)("[", cardSpec, ":", cds_condition_1.CDSCondition, "]"), (0, combi_1.seq)("[", cardSpec, "]"), (0, combi_1.seq)("[", cds_condition_1.CDSCondition, "]"));
54823
+ const segment = (0, combi_1.seq)(".", (0, combi_1.altPrio)(cds_string_1.CDSString, cds_integer_1.CDSInteger, cds_name_1.CDSName, "*"), (0, combi_1.optPrio)((0, combi_1.altPrio)(cds_parameters_select_1.CDSParametersSelect, cds_parameters_1.CDSParameters)), (0, combi_1.optPrio)(pathFilter));
54613
54824
  return (0, combi_1.seq)(cds_name_1.CDSName, (0, combi_1.optPrio)((0, combi_1.altPrio)(cds_parameters_1.CDSParameters, cds_parameters_select_1.CDSParametersSelect)), (0, combi_1.optPrio)(pathFilter), (0, combi_1.star)(segment));
54614
54825
  }
54615
54826
  }
@@ -54651,10 +54862,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
54651
54862
  exports.CDSRelation = void 0;
54652
54863
  const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src/cds/expressions/index.js");
54653
54864
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54865
+ const KEYWORDS = ["AS", "ON", "WHERE", "WITH", "UNION", "GROUP", "HAVING",
54866
+ "AND", "OR", "BETWEEN", "LIKE", "IN", "EXISTS",
54867
+ "WHEN", "THEN", "ELSE", "END", "CASE", "CAST"];
54654
54868
  class CDSRelation extends combi_1.Expression {
54655
54869
  getRunnable() {
54656
- const pre = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w_]+$/), "/");
54657
- return (0, combi_1.seq)((0, combi_1.opt)(pre), (0, combi_1.regex)(/^[\w_]+$/), (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs));
54870
+ const word = (0, combi_1.regex)(/^[\w_]+$/);
54871
+ const slashName = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w]+$/), "/", (0, combi_1.stopBefore1)(...KEYWORDS), (0, combi_1.regex)(/^[\w_]+$/));
54872
+ const name = (0, combi_1.altPrio)(slashName, word);
54873
+ return (0, combi_1.seq)(name, (0, combi_1.opt)(_1.CDSParametersSelect), (0, combi_1.opt)(_1.CDSAs));
54658
54874
  }
54659
54875
  }
54660
54876
  exports.CDSRelation = CDSRelation;
@@ -54678,11 +54894,12 @@ const cds_association_1 = __webpack_require__(/*! ./cds_association */ "./node_m
54678
54894
  const cds_join_1 = __webpack_require__(/*! ./cds_join */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_join.js");
54679
54895
  class CDSSelect extends combi_1.Expression {
54680
54896
  getRunnable() {
54681
- const fields = (0, combi_1.seq)((0, combi_1.star)((0, combi_1.seq)(_1.CDSElement, ",")), _1.CDSElement);
54897
+ const fields = (0, combi_1.seq)((0, combi_1.stopBefore1)("FROM"), (0, combi_1.star)((0, combi_1.seq)(_1.CDSElement, ",")), _1.CDSElement);
54682
54898
  const distinct = (0, combi_1.str)("DISTINCT");
54683
54899
  const elementList = (0, combi_1.seq)(_1.CDSElement, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSElement)), (0, combi_1.opt)(","));
54684
54900
  const elements = (0, combi_1.seq)((0, combi_1.str)("{"), (0, combi_1.altPrio)("*", elementList), (0, combi_1.str)("}"));
54685
- const aspectValue = (0, combi_1.altPrio)(_1.CDSString, _1.CDSPrefixedName);
54901
+ const typedLiteralVal = (0, combi_1.seq)(_1.CDSType, _1.CDSString);
54902
+ const aspectValue = (0, combi_1.altPrio)(typedLiteralVal, _1.CDSString, _1.CDSPrefixedName);
54686
54903
  const aspectBinding = (0, combi_1.seq)(_1.CDSPrefixedName, "=", ">", aspectValue);
54687
54904
  const bindAspect = (0, combi_1.seq)("BIND", "ASPECT", _1.CDSName, "(", aspectBinding, (0, combi_1.starPrio)((0, combi_1.seq)(",", aspectBinding)), ")", (0, combi_1.optPrio)((0, combi_1.seq)("AS", _1.CDSName)));
54688
54905
  const parenSelect = (0, combi_1.seq)("(", CDSSelect, ")");
@@ -54757,16 +54974,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
54757
54974
  exports.CDSTableField = void 0;
54758
54975
  const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src/cds/expressions/index.js");
54759
54976
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54760
- // A single field or association/composition inside a `define table entity { ... }`
54761
- // inline body. Wraps annotations + name + type together so tooling can iterate
54762
- // per-field with associated field-level annotations (matches the CDSElement
54763
- // shape used for select-list elements).
54764
54977
  class CDSTableField extends combi_1.Expression {
54765
54978
  getRunnable() {
54766
54979
  const nullability = (0, combi_1.optPrio)((0, combi_1.alt)("NOT NULL", "NULL"));
54980
+ const excludingNames = (0, combi_1.seq)(_1.CDSName, (0, combi_1.star)((0, combi_1.seq)(",", _1.CDSName)));
54981
+ const excluding = (0, combi_1.seq)("EXCLUDING", "{", excludingNames, "}");
54982
+ const includeField = (0, combi_1.seq)("INCLUDE", _1.CDSPrefixedName, (0, combi_1.optPrio)((0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.str)("SIGNATURE ONLY"), (0, combi_1.optPrio)(excluding)), (0, combi_1.seq)(excluding, (0, combi_1.optPrio)((0, combi_1.str)("SIGNATURE ONLY"))))));
54767
54983
  const field = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.str)("KEY")), _1.CDSName, ":", _1.CDSType, nullability);
54768
54984
  const assocOrComp = (0, combi_1.seq)(_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation));
54769
- return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, assocOrComp), ";");
54985
+ return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.altPrio)(includeField, assocOrComp, field), ";");
54770
54986
  }
54771
54987
  }
54772
54988
  exports.CDSTableField = CDSTableField;
@@ -54833,7 +55049,9 @@ const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src
54833
55049
  const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
54834
55050
  class CDSWithParameters extends combi_1.Expression {
54835
55051
  getRunnable() {
54836
- const param = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), _1.CDSName, ":", _1.CDSType, (0, combi_1.star)(_1.CDSAnnotation));
55052
+ const extNameValue = (0, combi_1.altPrio)(_1.CDSName, (0, combi_1.regex)(/^"(?:[^"]|"")*"$/));
55053
+ const externalName = (0, combi_1.seq)("EXTERNAL", "NAME", extNameValue);
55054
+ const param = (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), _1.CDSName, ":", _1.CDSType, (0, combi_1.opt)(externalName), (0, combi_1.star)(_1.CDSAnnotation));
54837
55055
  return (0, combi_1.seq)("WITH PARAMETERS", param, (0, combi_1.star)((0, combi_1.seq)(",", param)));
54838
55056
  }
54839
55057
  }
@@ -54887,6 +55105,7 @@ __exportStar(__webpack_require__(/*! ./cds_define_hierarchy */ "./node_modules/@
54887
55105
  __exportStar(__webpack_require__(/*! ./cds_define_projection */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_define_projection.js"), exports);
54888
55106
  __exportStar(__webpack_require__(/*! ./cds_define_table_entity */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_define_table_entity.js"), exports);
54889
55107
  __exportStar(__webpack_require__(/*! ./cds_define_table_function */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_define_table_function.js"), exports);
55108
+ __exportStar(__webpack_require__(/*! ./cds_paren_select */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_paren_select.js"), exports);
54890
55109
  __exportStar(__webpack_require__(/*! ./cds_define_view */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_define_view.js"), exports);
54891
55110
  __exportStar(__webpack_require__(/*! ./cds_element */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_element.js"), exports);
54892
55111
  __exportStar(__webpack_require__(/*! ./cds_extend_view */ "./node_modules/@abaplint/core/build/src/cds/expressions/cds_extend_view.js"), exports);
@@ -55103,7 +55322,7 @@ class Config {
55103
55322
  }
55104
55323
  return (0, version_1.versionToABAPRelease)(v);
55105
55324
  }
55106
- getOpenABAP() {
55325
+ isOpenABAP() {
55107
55326
  return this.getRelease() === version_1.Release["open-abap"];
55108
55327
  }
55109
55328
  getVersion() {
@@ -59823,10 +60042,10 @@ class ABAPObject extends _abstract_object_1.AbstractObject {
59823
60042
  return undefined;
59824
60043
  }
59825
60044
  getMainABAPFile() {
59826
- // todo, uris, https://github.com/abaplint/abaplint/issues/673
59827
60045
  const search = this.getName().replace(/\//g, "#").toLowerCase() + "." + this.getType().toLowerCase() + ".abap";
60046
+ const encodedSearch = search.replace(/#/g, "%23");
59828
60047
  for (const file of this.getABAPFiles()) {
59829
- if (file.getFilename().endsWith(search)) {
60048
+ if (file.getFilename().endsWith(search) || file.getFilename().endsWith(encodedSearch)) {
59830
60049
  return file;
59831
60050
  }
59832
60051
  }
@@ -69250,7 +69469,7 @@ class Registry {
69250
69469
  }
69251
69470
  static abaplintVersion() {
69252
69471
  // magic, see build script "version.js"
69253
- return "2.119.65";
69472
+ return "2.120.4";
69254
69473
  }
69255
69474
  getDDICReferences() {
69256
69475
  return this.ddicReferences;
@@ -73953,6 +74172,223 @@ exports.ClassicExceptionsOverlap = ClassicExceptionsOverlap;
73953
74172
 
73954
74173
  /***/ },
73955
74174
 
74175
+ /***/ "./node_modules/@abaplint/core/build/src/rules/clear_exporting_parameters.js"
74176
+ /*!***********************************************************************************!*\
74177
+ !*** ./node_modules/@abaplint/core/build/src/rules/clear_exporting_parameters.js ***!
74178
+ \***********************************************************************************/
74179
+ (__unused_webpack_module, exports, __webpack_require__) {
74180
+
74181
+ "use strict";
74182
+
74183
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
74184
+ exports.ClearExportingParameters = exports.ClearExportingParametersConf = void 0;
74185
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
74186
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
74187
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
74188
+ const syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js");
74189
+ const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
74190
+ const _scope_type_1 = __webpack_require__(/*! ../abap/5_syntax/_scope_type */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_scope_type.js");
74191
+ const _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
74192
+ const objects_1 = __webpack_require__(/*! ../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
74193
+ const _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
74194
+ const basic_1 = __webpack_require__(/*! ../abap/types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
74195
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
74196
+ class ClearExportingParametersConf extends _basic_rule_config_1.BasicRuleConfig {
74197
+ constructor() {
74198
+ super(...arguments);
74199
+ /** Skip specific parameter names, case insensitive
74200
+ * @uniqueItems true
74201
+ */
74202
+ this.skipNames = [];
74203
+ }
74204
+ }
74205
+ exports.ClearExportingParametersConf = ClearExportingParametersConf;
74206
+ class ClearExportingParameters {
74207
+ constructor() {
74208
+ this.conf = new ClearExportingParametersConf();
74209
+ }
74210
+ getMetadata() {
74211
+ return {
74212
+ key: "clear_exporting_parameters",
74213
+ title: "Clear EXPORTING parameters",
74214
+ shortDescription: `Checks that EXPORTING parameters passed by reference are cleared or assigned before they are read`,
74215
+ extendedInformation: `An EXPORTING parameter passed by reference behaves like a CHANGING parameter: it is not
74216
+ initialized when the method is called, so it can still contain a value supplied by the caller. Clear or overwrite it
74217
+ before reading it, so a leftover value is not accidentally used.
74218
+
74219
+ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#clear-or-overwrite-exporting-reference-parameters
74220
+
74221
+ https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenref_transf_output_param_guidl.htm
74222
+
74223
+ Note: EXPORTING parameters passed by VALUE are always initialized and are therefore not reported.
74224
+ Reading and writing the parameter in the same statement (e.g. "ev_result = ev_result + 1") is reported,
74225
+ as the source is evaluated before the parameter is assigned.
74226
+ Objects containing parser or syntax errors are not reported.
74227
+
74228
+ Class and interface method implementations and function modules are checked.`,
74229
+ tags: [_irule_1.RuleTag.Styleguide],
74230
+ badExample: `CLASS lcl DEFINITION.
74231
+ PUBLIC SECTION.
74232
+ METHODS foo EXPORTING ev_result TYPE i.
74233
+ ENDCLASS.
74234
+ CLASS lcl IMPLEMENTATION.
74235
+ METHOD foo.
74236
+ ev_result = ev_result + 1.
74237
+ ENDMETHOD.
74238
+ ENDCLASS.`,
74239
+ goodExample: `CLASS lcl DEFINITION.
74240
+ PUBLIC SECTION.
74241
+ METHODS foo EXPORTING ev_result TYPE i.
74242
+ ENDCLASS.
74243
+ CLASS lcl IMPLEMENTATION.
74244
+ METHOD foo.
74245
+ CLEAR ev_result.
74246
+ ev_result = ev_result + 1.
74247
+ ENDMETHOD.
74248
+ ENDCLASS.`,
74249
+ };
74250
+ }
74251
+ getConfig() {
74252
+ return this.conf;
74253
+ }
74254
+ setConfig(conf) {
74255
+ this.conf = conf;
74256
+ if (this.conf.skipNames === undefined) {
74257
+ this.conf.skipNames = [];
74258
+ }
74259
+ }
74260
+ initialize(reg) {
74261
+ this.reg = reg;
74262
+ return this;
74263
+ }
74264
+ run(obj) {
74265
+ if (!(obj instanceof _abap_object_1.ABAPObject) || obj instanceof objects_1.Interface) {
74266
+ return [];
74267
+ }
74268
+ for (const file of obj.getABAPFiles()) {
74269
+ for (const statement of file.getStatements()) {
74270
+ if (statement.get() instanceof _statement_1.Unknown) {
74271
+ return []; // contains parser errors
74272
+ }
74273
+ }
74274
+ }
74275
+ const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
74276
+ if (syntax.issues.length > 0) {
74277
+ return []; // contains syntax errors
74278
+ }
74279
+ const issues = [];
74280
+ this.traverse(syntax.spaghetti.getTop(), obj, issues);
74281
+ return issues;
74282
+ }
74283
+ traverse(node, obj, issues) {
74284
+ if (node.getIdentifier().stype === _scope_type_1.ScopeType.Method
74285
+ || node.getIdentifier().stype === _scope_type_1.ScopeType.FunctionModule) {
74286
+ this.checkProcedure(node, obj, issues);
74287
+ }
74288
+ for (const child of node.getChildren()) {
74289
+ this.traverse(child, obj, issues);
74290
+ }
74291
+ }
74292
+ checkProcedure(node, obj, issues) {
74293
+ const references = this.collectReferences(node);
74294
+ const parameters = this.findExportingByReference(node, references);
74295
+ if (parameters.length === 0) {
74296
+ return;
74297
+ }
74298
+ for (const parameter of parameters) {
74299
+ const issue = this.checkParameter(parameter, references, obj);
74300
+ if (issue !== undefined) {
74301
+ issues.push(issue);
74302
+ }
74303
+ }
74304
+ }
74305
+ findExportingByReference(node, references) {
74306
+ var _a;
74307
+ const ret = [];
74308
+ const candidates = new Set(Object.values(node.getData().vars));
74309
+ for (const reference of references) {
74310
+ if (reference.resolved instanceof _typed_identifier_1.TypedIdentifier) {
74311
+ candidates.add(reference.resolved);
74312
+ }
74313
+ }
74314
+ for (const parameter of candidates) {
74315
+ const meta = parameter.getMeta();
74316
+ const exporting = meta.includes("exporting" /* IdentifierMeta.MethodExporting */)
74317
+ || meta.includes("function_module_exporting" /* IdentifierMeta.FunctionModuleExporting */);
74318
+ if (exporting === false
74319
+ || meta.includes("pass_by_value" /* IdentifierMeta.PassByValue */) === true) {
74320
+ continue;
74321
+ }
74322
+ else if ((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.some(s => s.toUpperCase() === parameter.getName().toUpperCase())) {
74323
+ continue;
74324
+ }
74325
+ const type = parameter.getType();
74326
+ if (type instanceof basic_1.VoidType || type instanceof basic_1.UnknownType) {
74327
+ continue; // e.g. RAP magic parameters, or unresolved types
74328
+ }
74329
+ ret.push(parameter);
74330
+ }
74331
+ return ret;
74332
+ }
74333
+ collectReferences(node) {
74334
+ // procedures do not nest, so all descendant scopes (FOR, LET, ...) belong to this procedure
74335
+ const ret = [...node.getData().references];
74336
+ for (const child of node.getChildren()) {
74337
+ ret.push(...this.collectReferences(child));
74338
+ }
74339
+ return ret;
74340
+ }
74341
+ checkParameter(parameter, references, obj) {
74342
+ let firstRead = undefined;
74343
+ let earliestWrite = undefined;
74344
+ for (const reference of references) {
74345
+ if (reference.resolved === undefined
74346
+ || parameter.equals(reference.resolved) === false
74347
+ || parameter.getName().toUpperCase() !== reference.resolved.getName().toUpperCase()) {
74348
+ continue;
74349
+ }
74350
+ const pos = reference.position.getStart();
74351
+ if (reference.referenceType === _reference_1.ReferenceType.DataReadReference) {
74352
+ if (firstRead === undefined || pos.isBefore(firstRead.position.getStart())) {
74353
+ firstRead = reference;
74354
+ }
74355
+ }
74356
+ else if (reference.referenceType === _reference_1.ReferenceType.DataWriteReference) {
74357
+ if (earliestWrite === undefined || pos.isBefore(earliestWrite.position.getStart())) {
74358
+ earliestWrite = reference;
74359
+ }
74360
+ }
74361
+ }
74362
+ if (firstRead === undefined) {
74363
+ return undefined; // never read, no hazard
74364
+ }
74365
+ // the parameter is safe only if it is written in a statement strictly before the first read
74366
+ const readStatement = this.statementStart(firstRead, obj);
74367
+ const writeStatement = earliestWrite === undefined ? undefined : this.statementStart(earliestWrite, obj);
74368
+ if (writeStatement !== undefined && readStatement !== undefined && writeStatement.isBefore(readStatement)) {
74369
+ return undefined;
74370
+ }
74371
+ const message = `EXPORTING parameter "${parameter.getName().toLowerCase()}" read before it is cleared or assigned`;
74372
+ return issue_1.Issue.atIdentifier(firstRead.position, message, this.getMetadata().key, this.conf.severity);
74373
+ }
74374
+ statementStart(reference, obj) {
74375
+ const file = obj.getABAPFileByName(reference.position.getFilename());
74376
+ for (const statement of (file === null || file === void 0 ? void 0 : file.getStatements()) || []) {
74377
+ const pos = reference.position.getStart();
74378
+ const start = statement.getStart();
74379
+ const end = statement.getEnd();
74380
+ if (pos.equals(start) || (pos.isAfter(start) && pos.isBefore(end))) {
74381
+ return start;
74382
+ }
74383
+ }
74384
+ return undefined;
74385
+ }
74386
+ }
74387
+ exports.ClearExportingParameters = ClearExportingParameters;
74388
+ //# sourceMappingURL=clear_exporting_parameters.js.map
74389
+
74390
+ /***/ },
74391
+
73956
74392
  /***/ "./node_modules/@abaplint/core/build/src/rules/cloud_types.js"
73957
74393
  /*!********************************************************************!*\
73958
74394
  !*** ./node_modules/@abaplint/core/build/src/rules/cloud_types.js ***!
@@ -75868,7 +76304,7 @@ Make sure to test the downported code, it might not always be completely correct
75868
76304
  initialize(reg) {
75869
76305
  this.lowReg = reg;
75870
76306
  const config = this.lowReg.getConfig();
75871
- if (config.getRelease() === version_1.Release.v702 || config.getOpenABAP()) {
76307
+ if (config.getRelease() === version_1.Release.v702 || config.isOpenABAP()) {
75872
76308
  this.initHighReg();
75873
76309
  }
75874
76310
  return this;
@@ -75901,7 +76337,7 @@ Make sure to test the downported code, it might not always be completely correct
75901
76337
  const ret = [];
75902
76338
  this.counter = 1;
75903
76339
  const config = this.lowReg.getConfig();
75904
- if (config.getRelease() !== version_1.Release.v702 && !config.getOpenABAP()) {
76340
+ if (config.getRelease() !== version_1.Release.v702 && !config.isOpenABAP()) {
75905
76341
  return ret;
75906
76342
  }
75907
76343
  else if (!(lowObj instanceof _abap_object_1.ABAPObject)) {
@@ -75995,6 +76431,18 @@ Make sure to test the downported code, it might not always be completely correct
75995
76431
  }
75996
76432
  }
75997
76433
  }
76434
+ // INTO after WHERE parses as a valid SELECT in the low version, but is only allowed in
76435
+ // strict SQL syntax, so move it also when the statement is no longer Unknown
76436
+ if (ret.length === 0) {
76437
+ for (let i = 0; i < lowStatements.length; i++) {
76438
+ const low = lowStatements[i];
76439
+ const high = highStatements[i];
76440
+ const issue = this.downportSQLMoveInto(low, high, lowFile, highSyntax);
76441
+ if (issue) {
76442
+ ret.push(issue);
76443
+ }
76444
+ }
76445
+ }
75998
76446
  }
75999
76447
  return ret;
76000
76448
  }
@@ -76238,10 +76686,14 @@ Make sure to test the downported code, it might not always be completely correct
76238
76686
  return undefined;
76239
76687
  }
76240
76688
  //////////////////////////////////////////
76241
- /** move INTO from after WHERE to after FROM */
76689
+ /** move INTO from after WHERE to after FROM,
76690
+ * note that INTO after WHERE is only valid in strict SQL syntax, so it must be moved when
76691
+ * downporting; this can happen both while the statement is still Unknown(from the main loop)
76692
+ * and after the @ and FIELDS have been removed, leaving a SELECT that parses in the low version */
76242
76693
  downportSQLMoveInto(low, high, lowFile, _highSyntax) {
76243
76694
  var _a;
76244
- if (!(low.get() instanceof _statement_1.Unknown)) {
76695
+ if (!(high.get() instanceof Statements.Select)
76696
+ && !(high.get() instanceof Statements.SelectLoop)) {
76245
76697
  return undefined;
76246
76698
  }
76247
76699
  // note: SQLCond is also used in JOIN(FROM) conditions
@@ -76249,6 +76701,7 @@ Make sure to test the downported code, it might not always be completely correct
76249
76701
  if (where === undefined) {
76250
76702
  return undefined;
76251
76703
  }
76704
+ // the FIELDS list sits between FROM and WHERE, wait for it to be removed first
76252
76705
  if (high.findFirstExpression(Expressions.SQLFields) !== undefined) {
76253
76706
  return undefined;
76254
76707
  }
@@ -76756,7 +77209,7 @@ ${indentation}`);
76756
77209
  outlineCatchSimple(node, lowFile) {
76757
77210
  // outlines "CATCH cx_bcs INTO DATA(lx_bcs_excep).", note that this does not need to look at types
76758
77211
  var _a, _b;
76759
- if (this.lowReg.getConfig().getOpenABAP()) {
77212
+ if (this.lowReg.getConfig().isOpenABAP()) {
76760
77213
  return undefined;
76761
77214
  }
76762
77215
  if (!(node.get() instanceof Statements.Catch)) {
@@ -76805,7 +77258,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
76805
77258
  if (!(node.get() instanceof Statements.Move)) {
76806
77259
  return undefined;
76807
77260
  }
76808
- if (this.lowReg.getConfig().getOpenABAP()) {
77261
+ if (this.lowReg.getConfig().isOpenABAP()) {
76809
77262
  return undefined;
76810
77263
  }
76811
77264
  const target = node.findFirstExpression(Expressions.Target);
@@ -76861,7 +77314,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
76861
77314
  return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
76862
77315
  }
76863
77316
  partiallyImplemented(node, lowFile) {
76864
- if (this.lowReg.getConfig().getOpenABAP()) {
77317
+ if (this.lowReg.getConfig().isOpenABAP()) {
76865
77318
  return undefined;
76866
77319
  }
76867
77320
  if (node.get() instanceof Statements.InterfaceDef) {
@@ -77537,7 +77990,7 @@ ${indentation} output = ${uniqueName}.\n`;
77537
77990
  if (!(node.get() instanceof Statements.Loop)) {
77538
77991
  return undefined;
77539
77992
  }
77540
- if (this.lowReg.getConfig().getOpenABAP()) {
77993
+ if (this.lowReg.getConfig().isOpenABAP()) {
77541
77994
  return undefined;
77542
77995
  }
77543
77996
  const source = (_a = node.findDirectExpression(Expressions.LoopSource)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.SimpleSource2);
@@ -78213,7 +78666,7 @@ ${indentation} output = ${uniqueName}.\n`;
78213
78666
  outlineData(node, lowFile, highSyntax) {
78214
78667
  // hmm, no guard here, as DATA(SDF) is valid in 702
78215
78668
  var _a, _b;
78216
- if (this.lowReg.getConfig().getOpenABAP()) {
78669
+ if (this.lowReg.getConfig().isOpenABAP()) {
78217
78670
  return undefined;
78218
78671
  }
78219
78672
  for (const i of node.findAllExpressionsRecursive(Expressions.InlineData)) {
@@ -78432,7 +78885,7 @@ ${indentation} output = ${uniqueName}.\n`;
78432
78885
  return false;
78433
78886
  }
78434
78887
  replaceXsdBool(node, lowFile, highSyntax) {
78435
- if (this.lowReg.getConfig().getOpenABAP()) {
78888
+ if (this.lowReg.getConfig().isOpenABAP()) {
78436
78889
  return undefined;
78437
78890
  }
78438
78891
  const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
@@ -78561,7 +79014,7 @@ ${indentation} output = ${uniqueName}.\n`;
78561
79014
  }
78562
79015
  replaceLineFunctions(node, lowFile, highSyntax, highFile) {
78563
79016
  var _a, _b;
78564
- if (this.lowReg.getConfig().getOpenABAP()) {
79017
+ if (this.lowReg.getConfig().isOpenABAP()) {
78565
79018
  return undefined;
78566
79019
  }
78567
79020
  const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
@@ -82735,6 +83188,7 @@ __exportStar(__webpack_require__(/*! ./check_subrc */ "./node_modules/@abaplint/
82735
83188
  __exportStar(__webpack_require__(/*! ./check_syntax */ "./node_modules/@abaplint/core/build/src/rules/check_syntax.js"), exports);
82736
83189
  __exportStar(__webpack_require__(/*! ./check_text_elements */ "./node_modules/@abaplint/core/build/src/rules/check_text_elements.js"), exports);
82737
83190
  __exportStar(__webpack_require__(/*! ./check_transformation_exists */ "./node_modules/@abaplint/core/build/src/rules/check_transformation_exists.js"), exports);
83191
+ __exportStar(__webpack_require__(/*! ./clear_exporting_parameters */ "./node_modules/@abaplint/core/build/src/rules/clear_exporting_parameters.js"), exports);
82738
83192
  __exportStar(__webpack_require__(/*! ./class_attribute_names */ "./node_modules/@abaplint/core/build/src/rules/class_attribute_names.js"), exports);
82739
83193
  __exportStar(__webpack_require__(/*! ./classic_exceptions_overlap */ "./node_modules/@abaplint/core/build/src/rules/classic_exceptions_overlap.js"), exports);
82740
83194
  __exportStar(__webpack_require__(/*! ./cloud_types */ "./node_modules/@abaplint/core/build/src/rules/cloud_types.js"), exports);
@@ -82840,6 +83294,7 @@ __exportStar(__webpack_require__(/*! ./preferred_compare_operator */ "./node_mod
82840
83294
  __exportStar(__webpack_require__(/*! ./prefix_is_current_class */ "./node_modules/@abaplint/core/build/src/rules/prefix_is_current_class.js"), exports);
82841
83295
  __exportStar(__webpack_require__(/*! ./reduce_procedural_code */ "./node_modules/@abaplint/core/build/src/rules/reduce_procedural_code.js"), exports);
82842
83296
  __exportStar(__webpack_require__(/*! ./reduce_string_templates */ "./node_modules/@abaplint/core/build/src/rules/reduce_string_templates.js"), exports);
83297
+ __exportStar(__webpack_require__(/*! ./redundant_conversion */ "./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js"), exports);
82843
83298
  __exportStar(__webpack_require__(/*! ./release_idoc */ "./node_modules/@abaplint/core/build/src/rules/release_idoc.js"), exports);
82844
83299
  __exportStar(__webpack_require__(/*! ./remove_descriptions */ "./node_modules/@abaplint/core/build/src/rules/remove_descriptions.js"), exports);
82845
83300
  __exportStar(__webpack_require__(/*! ./rfc_error_handling */ "./node_modules/@abaplint/core/build/src/rules/rfc_error_handling.js"), exports);
@@ -83045,7 +83500,7 @@ class InlineDataOldVersions extends _abap_rule_1.ABAPRule {
83045
83500
  runParsed(file) {
83046
83501
  const issues = [];
83047
83502
  if ((0, version_1.releaseAtLeast)(this.reg.getConfig().getRelease(), version_1.Release.v740sp02)
83048
- || this.reg.getConfig().getOpenABAP()
83503
+ || this.reg.getConfig().isOpenABAP()
83049
83504
  || this.reg.getConfig().getLanguageVersion() === version_1.LanguageVersion.Cloud) {
83050
83505
  return [];
83051
83506
  }
@@ -87167,7 +87622,7 @@ Not considered optional branches:
87167
87622
  const release = this.reg.getConfig().getRelease();
87168
87623
  if (release === version_1.Release.v700
87169
87624
  || release === version_1.Release.v702
87170
- || this.reg.getConfig().getOpenABAP()) {
87625
+ || this.reg.getConfig().isOpenABAP()) {
87171
87626
  return [];
87172
87627
  }
87173
87628
  const struc = file.getStructure();
@@ -91318,6 +91773,269 @@ exports.ReduceStringTemplates = ReduceStringTemplates;
91318
91773
 
91319
91774
  /***/ },
91320
91775
 
91776
+ /***/ "./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js"
91777
+ /*!*****************************************************************************!*\
91778
+ !*** ./node_modules/@abaplint/core/build/src/rules/redundant_conversion.js ***!
91779
+ \*****************************************************************************/
91780
+ (__unused_webpack_module, exports, __webpack_require__) {
91781
+
91782
+ "use strict";
91783
+
91784
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
91785
+ if (k2 === undefined) k2 = k;
91786
+ var desc = Object.getOwnPropertyDescriptor(m, k);
91787
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
91788
+ desc = { enumerable: true, get: function() { return m[k]; } };
91789
+ }
91790
+ Object.defineProperty(o, k2, desc);
91791
+ }) : (function(o, m, k, k2) {
91792
+ if (k2 === undefined) k2 = k;
91793
+ o[k2] = m[k];
91794
+ }));
91795
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
91796
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
91797
+ }) : function(o, v) {
91798
+ o["default"] = v;
91799
+ });
91800
+ var __importStar = (this && this.__importStar) || (function () {
91801
+ var ownKeys = function(o) {
91802
+ ownKeys = Object.getOwnPropertyNames || function (o) {
91803
+ var ar = [];
91804
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
91805
+ return ar;
91806
+ };
91807
+ return ownKeys(o);
91808
+ };
91809
+ return function (mod) {
91810
+ if (mod && mod.__esModule) return mod;
91811
+ var result = {};
91812
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
91813
+ __setModuleDefault(result, mod);
91814
+ return result;
91815
+ };
91816
+ })();
91817
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
91818
+ exports.RedundantConversion = exports.RedundantConversionConf = void 0;
91819
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
91820
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
91821
+ const _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
91822
+ const constant_1 = __webpack_require__(/*! ../abap/5_syntax/expressions/constant */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/constant.js");
91823
+ const syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js");
91824
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
91825
+ const _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
91826
+ const basic_1 = __webpack_require__(/*! ../abap/types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
91827
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
91828
+ const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
91829
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
91830
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
91831
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
91832
+ const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
91833
+ class RedundantConversionConf extends _basic_rule_config_1.BasicRuleConfig {
91834
+ }
91835
+ exports.RedundantConversionConf = RedundantConversionConf;
91836
+ class RedundantConversion {
91837
+ constructor() {
91838
+ this.conf = new RedundantConversionConf();
91839
+ }
91840
+ getMetadata() {
91841
+ return {
91842
+ key: "redundant_conversion",
91843
+ title: "Redundant Conversion",
91844
+ shortDescription: `Find redundant CONV expressions`,
91845
+ extendedInformation: `Reports CONV expressions whose operand already has the conversion's target type.`,
91846
+ tags: [_irule_1.RuleTag.Quickfix],
91847
+ badExample: `DATA text TYPE string.
91848
+ text = CONV string( text ).`,
91849
+ goodExample: `DATA text TYPE string.
91850
+ text = text.`,
91851
+ };
91852
+ }
91853
+ getConfig() {
91854
+ return this.conf;
91855
+ }
91856
+ setConfig(conf) {
91857
+ this.conf = conf;
91858
+ }
91859
+ initialize(reg) {
91860
+ this.reg = reg;
91861
+ return this;
91862
+ }
91863
+ run(obj) {
91864
+ var _a, _b;
91865
+ if (!(0, version_1.releaseAtLeast)(this.reg.getConfig().getRelease(), version_1.Release.v740sp02)
91866
+ && !this.reg.getConfig().isOpenABAP()) {
91867
+ return [];
91868
+ }
91869
+ if (!(obj instanceof _abap_object_1.ABAPObject)) {
91870
+ return [];
91871
+ }
91872
+ const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
91873
+ if (syntax.issues.length > 0) {
91874
+ return [];
91875
+ }
91876
+ const issues = [];
91877
+ for (const file of obj.getABAPFiles()) {
91878
+ const structure = file.getStructure();
91879
+ if (structure === undefined) {
91880
+ continue;
91881
+ }
91882
+ for (const source of structure.findAllExpressions(Expressions.Source)) {
91883
+ if (source.getFirstToken().getStr().toUpperCase() !== "CONV") {
91884
+ continue;
91885
+ }
91886
+ const typeExpression = source.findDirectExpression(Expressions.TypeNameOrInfer);
91887
+ const bodySource = (_a = source.findDirectExpression(Expressions.ConvBody)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Source);
91888
+ if (typeExpression === undefined
91889
+ || bodySource === undefined) {
91890
+ continue;
91891
+ }
91892
+ const scope = syntax.spaghetti.lookupPosition(source.getFirstToken().getStart(), file.getFilename());
91893
+ if (scope === undefined) {
91894
+ continue;
91895
+ }
91896
+ const target = (_b = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.InferredType
91897
+ && reference.position.getStart().equals(typeExpression.getFirstToken().getStart()))) === null || _b === void 0 ? void 0 : _b.resolved;
91898
+ const operandType = this.sourceType(bodySource, scope);
91899
+ if (!(target instanceof _typed_identifier_1.TypedIdentifier)) {
91900
+ continue;
91901
+ }
91902
+ const operandHasSameType = operandType !== undefined && this.sameType(target.getType(), operandType);
91903
+ const arithmeticHasSameContext = this.arithmeticUsesSameTargetType(source, bodySource, file, scope, target.getType());
91904
+ if (operandHasSameType === false && arithmeticHasSameContext === false) {
91905
+ continue;
91906
+ }
91907
+ const closingParen = source.getDirectTokens().find(token => token.getStr() === ")" && token.getStart().isAfter(bodySource.getLastToken().getStart()));
91908
+ if (closingParen === undefined) {
91909
+ continue;
91910
+ }
91911
+ const preserveParentheses = bodySource.findDirectExpression(Expressions.ArithOperator) !== undefined
91912
+ || bodySource.findDirectTokenByText("&&") !== undefined;
91913
+ // Apply the later edit first so the original positions remain valid when
91914
+ // both parts of the CONV wrapper are changed on the same line.
91915
+ const fix = edit_helper_1.EditHelper.merge(edit_helper_1.EditHelper.replaceRange(file, bodySource.getLastToken().getEnd(), closingParen.getEnd(), preserveParentheses ? ")" : ""), edit_helper_1.EditHelper.replaceRange(file, source.getFirstToken().getStart(), bodySource.getFirstToken().getStart(), preserveParentheses ? "(" : ""));
91916
+ issues.push(issue_1.Issue.atRange(file, source.getFirstToken().getStart(), closingParen.getEnd(), "Redundant CONV expression", this.getMetadata().key, this.conf.severity, fix));
91917
+ }
91918
+ }
91919
+ return issues;
91920
+ }
91921
+ arithmeticUsesSameTargetType(conversion, bodySource, file, scope, conversionType) {
91922
+ var _a, _b;
91923
+ if (bodySource.findDirectExpression(Expressions.ArithOperator) === undefined) {
91924
+ return false;
91925
+ }
91926
+ const statement = file.getStatements().find(candidate => candidate.includesToken(conversion.getFirstToken()));
91927
+ if (!((statement === null || statement === void 0 ? void 0 : statement.get()) instanceof Statements.Move)) {
91928
+ return false;
91929
+ }
91930
+ const targetToken = (_a = statement.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
91931
+ if (targetToken === undefined) {
91932
+ return false;
91933
+ }
91934
+ const assignmentTarget = (_b = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataWriteReference
91935
+ && reference.position.getStart().equals(targetToken.getStart()))) === null || _b === void 0 ? void 0 : _b.resolved;
91936
+ return assignmentTarget instanceof _typed_identifier_1.TypedIdentifier
91937
+ && this.sameType(conversionType, assignmentTarget.getType());
91938
+ }
91939
+ sourceType(source, scope) {
91940
+ let context;
91941
+ for (const child of source.getChildren()) {
91942
+ if (!(child instanceof nodes_1.ExpressionNode)) {
91943
+ continue;
91944
+ }
91945
+ else if (child.get() instanceof Expressions.FieldChain) {
91946
+ context = this.fieldChainType(child, scope);
91947
+ if (context === undefined) {
91948
+ return undefined;
91949
+ }
91950
+ }
91951
+ else if (child.get() instanceof Expressions.Constant) {
91952
+ context = this.infer(context, constant_1.Constant.runSyntax(child));
91953
+ }
91954
+ else if (child.get() instanceof Expressions.Source) {
91955
+ context = this.infer(context, this.sourceType(child, scope));
91956
+ }
91957
+ else if (child.get() instanceof Expressions.ArithOperator) {
91958
+ if (child.concatTokens() === "**") {
91959
+ context = new basic_1.FloatType();
91960
+ }
91961
+ }
91962
+ else {
91963
+ return undefined;
91964
+ }
91965
+ }
91966
+ if (source.findDirectTokenByText("&&")) {
91967
+ return basic_1.StringType.get();
91968
+ }
91969
+ return context;
91970
+ }
91971
+ fieldChainType(fieldChain, scope) {
91972
+ var _a;
91973
+ const operand = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataReadReference
91974
+ && reference.position.getStart().equals(fieldChain.getFirstToken().getStart()))) === null || _a === void 0 ? void 0 : _a.resolved;
91975
+ if (!(operand instanceof _typed_identifier_1.TypedIdentifier)) {
91976
+ return undefined;
91977
+ }
91978
+ let type = operand.getType();
91979
+ for (const child of fieldChain.getChildren()) {
91980
+ if (!(child instanceof nodes_1.ExpressionNode)
91981
+ || child.get() instanceof Expressions.SourceField) {
91982
+ continue;
91983
+ }
91984
+ else if (child.get() instanceof Expressions.ComponentName) {
91985
+ if (type instanceof basic_1.TableType) {
91986
+ type = type.getRowType();
91987
+ }
91988
+ if (!(type instanceof basic_1.StructureType)) {
91989
+ return undefined;
91990
+ }
91991
+ type = type.getComponentByName(child.concatTokens());
91992
+ }
91993
+ else {
91994
+ // Offsets, table expressions, attributes, and dereferences need more
91995
+ // context than the initial data reference provides.
91996
+ return undefined;
91997
+ }
91998
+ }
91999
+ return type;
92000
+ }
92001
+ infer(context, found) {
92002
+ if (context instanceof basic_1.FloatType && found instanceof basic_1.IntegerType) {
92003
+ return context;
92004
+ }
92005
+ else if (context instanceof basic_1.IntegerType && found instanceof basic_1.HexType) {
92006
+ return context;
92007
+ }
92008
+ else if ((context instanceof basic_1.IntegerType || context instanceof basic_1.FloatType) && (found === null || found === void 0 ? void 0 : found.isGeneric())) {
92009
+ return context;
92010
+ }
92011
+ return found;
92012
+ }
92013
+ sameType(first, second) {
92014
+ var _a, _b;
92015
+ if (first instanceof basic_1.UnknownType
92016
+ || second instanceof basic_1.UnknownType
92017
+ || first instanceof basic_1.VoidType
92018
+ || second instanceof basic_1.VoidType
92019
+ || first.isGeneric()
92020
+ || second.isGeneric()) {
92021
+ return false;
92022
+ }
92023
+ if (first.constructor !== second.constructor) {
92024
+ return false;
92025
+ }
92026
+ if (first instanceof basic_1.StructureType || first instanceof basic_1.TableType) {
92027
+ const firstName = (_a = first.getQualifiedName()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
92028
+ const secondName = (_b = second.getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toUpperCase();
92029
+ return firstName !== undefined && firstName === secondName;
92030
+ }
92031
+ return first.toABAP() === second.toABAP();
92032
+ }
92033
+ }
92034
+ exports.RedundantConversion = RedundantConversion;
92035
+ //# sourceMappingURL=redundant_conversion.js.map
92036
+
92037
+ /***/ },
92038
+
91321
92039
  /***/ "./node_modules/@abaplint/core/build/src/rules/release_idoc.js"
91322
92040
  /*!*********************************************************************!*\
91323
92041
  !*** ./node_modules/@abaplint/core/build/src/rules/release_idoc.js ***!
@@ -92828,7 +93546,8 @@ ENDCLASS.`,
92828
93546
  }
92829
93547
  for (const v in vars) {
92830
93548
  const id = vars[v];
92831
- if (id.getMeta().includes("pass_by_value" /* IdentifierMeta.PassByValue */) === false) {
93549
+ if (id.getMeta().includes("importing" /* IdentifierMeta.MethodImporting */) === false
93550
+ || id.getMeta().includes("pass_by_value" /* IdentifierMeta.PassByValue */) === false) {
92832
93551
  continue;
92833
93552
  }
92834
93553
  else if (this.reg.isFileDependency(id.getFilename()) === true) {
@@ -93270,7 +93989,7 @@ class SQLEscapeHostVariables extends _abap_rule_1.ABAPRule {
93270
93989
  }
93271
93990
  if (!(0, version_1.releaseAtLeast)(this.reg.getConfig().getRelease(), version_1.Release.v740sp02)
93272
93991
  && this.reg.getConfig().getLanguageVersion() !== version_1.LanguageVersion.Cloud
93273
- && !this.reg.getConfig().getOpenABAP()) {
93992
+ && !this.reg.getConfig().isOpenABAP()) {
93274
93993
  return [];
93275
93994
  }
93276
93995
  for (const s of file.getStatements()) {
@@ -97308,7 +98027,7 @@ ENDIF.`,
97308
98027
  }
97309
98028
  const release = this.reg.getConfig().getRelease();
97310
98029
  const langVers = this.reg.getConfig().getLanguageVersion();
97311
- if (this.reg.getConfig().getOpenABAP()) {
98030
+ if (this.reg.getConfig().isOpenABAP()) {
97312
98031
  return [];
97313
98032
  }
97314
98033
  else if (!(0, version_1.releaseAtLeast)(release, version_1.Release.v740sp02) && langVers !== version_1.LanguageVersion.Cloud) {
@@ -99371,9 +100090,14 @@ abaplint:
99371
100090
  // Keeps track of source maps as generated code is added
99372
100091
  class Chunk {
99373
100092
  raw;
100093
+ // tracked incrementally so appends never re-scan the whole buffer
100094
+ lineCount;
100095
+ lastLineLength;
99374
100096
  mappings = [];
99375
100097
  constructor(str) {
99376
100098
  this.raw = "";
100099
+ this.lineCount = 1;
100100
+ this.lastLineLength = 0;
99377
100101
  this.mappings = [];
99378
100102
  if (str) {
99379
100103
  this.appendString(str);
@@ -99392,63 +100116,85 @@ class Chunk {
99392
100116
  if (append.getCode() === "") {
99393
100117
  return this;
99394
100118
  }
99395
- const lines = this.raw.split("\n");
99396
- const lineCount = lines.length;
99397
- const lastLine = lines[lines.length - 1];
99398
100119
  for (const m of append.mappings) {
99399
- // original stays the same, but adjust the generated positions
99400
- const add = m;
99401
- if (add.generated.line === 1 && this.raw.endsWith("\n") === false) {
99402
- add.generated.column += lastLine.length;
99403
- }
99404
- else {
99405
- add.generated.line += lineCount - 1;
100120
+ // deep copy so the appended chunk's mappings are never mutated,
100121
+ // otherwise appending the same chunk twice double-shifts its positions
100122
+ const add = {
100123
+ source: m.source,
100124
+ name: m.name,
100125
+ generated: { line: m.generated.line, column: m.generated.column },
100126
+ original: { line: m.original.line, column: m.original.column },
100127
+ };
100128
+ // original stays the same, but adjust the generated positions:
100129
+ // the appended content begins at the end of the current buffer, so its
100130
+ // first line continues the current last line, and every line moves down
100131
+ if (add.generated.line === 1) {
100132
+ add.generated.column += this.lastLineLength;
99406
100133
  }
100134
+ add.generated.line += this.lineCount - 1;
99407
100135
  this.mappings.push(add);
99408
100136
  }
99409
- this.raw += append.getCode();
99410
- return this;
100137
+ return this.appendString(append.getCode());
100138
+ }
100139
+ originalPosition(pos) {
100140
+ if (pos instanceof abaplint.Position || pos instanceof abaplint.Token) {
100141
+ return { line: pos.getRow(), column: pos.getCol() - 1 };
100142
+ }
100143
+ else {
100144
+ return { line: pos.getFirstToken().getRow(), column: pos.getFirstToken().getCol() - 1 };
100145
+ }
99411
100146
  }
99412
100147
  append(input, pos, traversal) {
99413
100148
  if (input === "") {
99414
100149
  return this;
99415
100150
  }
99416
100151
  if (pos && input !== "\n") {
99417
- const lines = this.raw.split("\n");
99418
- const lastLine = lines[lines.length - 1];
99419
- let originalLine = 0;
99420
- let originalColumn = 0;
99421
- if (pos instanceof abaplint.Position || pos instanceof abaplint.Token) {
99422
- originalLine = pos.getRow();
99423
- originalColumn = pos.getCol() - 1;
99424
- }
99425
- else {
99426
- originalLine = pos.getFirstToken().getRow();
99427
- originalColumn = pos.getFirstToken().getCol() - 1;
99428
- }
99429
100152
  this.mappings.push({
99430
100153
  source: traversal.getFilename(),
99431
100154
  generated: {
99432
- line: lines.length,
99433
- column: lastLine.length,
99434
- },
99435
- original: {
99436
- line: originalLine,
99437
- column: originalColumn,
100155
+ line: this.lineCount,
100156
+ column: this.lastLineLength,
99438
100157
  },
100158
+ original: this.originalPosition(pos),
99439
100159
  });
99440
100160
  }
99441
- this.raw += input;
100161
+ return this.appendString(input);
100162
+ }
100163
+ /**
100164
+ * Baseline fallback so statements whose transpiler emitted no mappings still
100165
+ * resolve to their ABAP source. Adds a single mapping from the start of this
100166
+ * chunk (generated line 1, column 0) to `pos`. No-op if the chunk is empty or
100167
+ * already carries mappings, so it never overrides finer-grained mappings.
100168
+ */
100169
+ ensureStartMapping(pos, traversal) {
100170
+ if (this.raw === "" || this.mappings.length > 0) {
100171
+ return this;
100172
+ }
100173
+ this.mappings.push({
100174
+ source: traversal.getFilename(),
100175
+ generated: { line: 1, column: 0 },
100176
+ original: this.originalPosition(pos),
100177
+ });
99442
100178
  return this;
99443
100179
  }
99444
100180
  appendString(input) {
99445
100181
  this.raw += input;
100182
+ const lastNewline = input.lastIndexOf("\n");
100183
+ if (lastNewline < 0) {
100184
+ this.lastLineLength += input.length;
100185
+ }
100186
+ else {
100187
+ this.lineCount += input.split("\n").length - 1;
100188
+ this.lastLineLength = input.length - lastNewline - 1;
100189
+ }
99446
100190
  return this;
99447
100191
  }
99448
100192
  stripLastNewline() {
99449
100193
  // note: this will not change the source map
99450
100194
  if (this.raw.endsWith("\n")) {
99451
100195
  this.raw = this.raw.substring(0, this.raw.length - 1);
100196
+ this.lineCount--;
100197
+ this.lastLineLength = this.raw.length - this.raw.lastIndexOf("\n") - 1;
99452
100198
  }
99453
100199
  }
99454
100200
  getCode() {
@@ -99468,16 +100214,18 @@ class Chunk {
99468
100214
  if (l.startsWith("}")) {
99469
100215
  i = i - 1;
99470
100216
  }
99471
- if (i > 0) {
99472
- output.push(" ".repeat(i * 2) + l);
100217
+ // clamp so unbalanced braces never produce a negative indent/shift
100218
+ const indent = i > 0 ? i * 2 : 0;
100219
+ if (indent > 0) {
100220
+ output.push(" ".repeat(indent) + l);
99473
100221
  }
99474
100222
  else {
99475
100223
  output.push(l);
99476
100224
  }
99477
- // fix maps
100225
+ // fix maps: shift columns by the indentation actually applied to this line
99478
100226
  for (const m of this.mappings) {
99479
100227
  if (m.generated.line === line) {
99480
- m.generated.column += i * 2;
100228
+ m.generated.column += indent;
99481
100229
  }
99482
100230
  }
99483
100231
  if (l.endsWith(" {")) {
@@ -99486,11 +100234,28 @@ class Chunk {
99486
100234
  line++;
99487
100235
  }
99488
100236
  this.raw = output.join("\n");
100237
+ // line structure is unchanged, but the last line may have been indented
100238
+ this.lastLineLength = output[output.length - 1].length;
99489
100239
  return this;
99490
100240
  }
99491
- getMap(generatedFilename) {
100241
+ /**
100242
+ * @param generatedFilename name written to the "file" field of the map
100243
+ * @param options.generatedLineOffset number of lines prepended to the generated
100244
+ * output after this chunk was built (e.g. a runtime import line); every mapping
100245
+ * is shifted down by this amount so the map stays aligned with the file on disk
100246
+ * @param options.sourcePaths maps a mapping "source" (the bare abap filename) to
100247
+ * the path that should appear in the map, avoiding fragile post-hoc string edits
100248
+ */
100249
+ getMap(generatedFilename, options) {
100250
+ const offset = options?.generatedLineOffset ?? 0;
100251
+ const sourcePaths = options?.sourcePaths ?? {};
99492
100252
  const sourceMapGenerator = new sourceMap.SourceMapGenerator();
99493
- this.mappings.forEach(m => sourceMapGenerator.addMapping(m));
100253
+ this.mappings.forEach(m => sourceMapGenerator.addMapping({
100254
+ source: sourcePaths[m.source] ?? m.source,
100255
+ name: m.name,
100256
+ original: m.original,
100257
+ generated: { line: m.generated.line + offset, column: m.generated.column },
100258
+ }));
99494
100259
  const json = sourceMapGenerator.toJSON();
99495
100260
  json.file = generatedFilename;
99496
100261
  json.sourceRoot = "";
@@ -102992,6 +103757,7 @@ exports.ReceiveParametersTranspiler = ReceiveParametersTranspiler;
102992
103757
  Object.defineProperty(exports, "__esModule", ({ value: true }));
102993
103758
  exports.ReduceBodyTranspiler = void 0;
102994
103759
  const core_1 = __webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js");
103760
+ const traversal_1 = __webpack_require__(/*! ../traversal */ "./node_modules/@abaplint/transpiler/build/src/traversal.js");
102995
103761
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
102996
103762
  const transpile_types_1 = __webpack_require__(/*! ../transpile_types */ "./node_modules/@abaplint/transpiler/build/src/transpile_types.js");
102997
103763
  const target_1 = __webpack_require__(/*! ./target */ "./node_modules/@abaplint/transpiler/build/src/expressions/target.js");
@@ -103011,10 +103777,14 @@ class ReduceBodyTranspiler {
103011
103777
  else if (forExpressions.length > 1) {
103012
103778
  throw new Error("ReduceBodyTranspiler, multiple FOR not supported, " + body.concatTokens());
103013
103779
  }
103014
- else if (["THEN", "UNTIL", "WHILE", "FROM", "TO", "GROUPS"].some(token => forExpressions[0].findDirectTokenByText(token))) {
103780
+ const loopExpression = forExpression.findDirectExpression(core_1.Expressions.InlineLoopDefinition);
103781
+ if (loopExpression === undefined) {
103782
+ // index based FOR, eg. "FOR i = 1 WHILE i <= 5"
103783
+ return this.transpileIndex(body, forExpression, traversal);
103784
+ }
103785
+ else if (["THEN", "UNTIL", "WHILE", "FROM", "TO", "GROUPS"].some(token => forExpression.findDirectTokenByText(token))) {
103015
103786
  throw new Error("ValueBody FOR todo, " + body.concatTokens());
103016
103787
  }
103017
- const loopExpression = forExpression.findDirectExpression(core_1.Expressions.InlineLoopDefinition);
103018
103788
  const loopSource = traversal.traverse(loopExpression?.findDirectExpression(core_1.Expressions.Source)).getCode();
103019
103789
  const loopVariable = traversal.traverse(loopExpression?.findDirectExpression(core_1.Expressions.TargetField)
103020
103790
  || loopExpression?.findDirectExpression(core_1.Expressions.TargetFieldSymbol)).getCode();
@@ -103032,6 +103802,75 @@ class ReduceBodyTranspiler {
103032
103802
  const returnId = UniqueIdentifier.get();
103033
103803
  ret.appendString(`const ${returnId} = ${target};\n`);
103034
103804
  */
103805
+ const returnField = this.declareInit(body, traversal, ret);
103806
+ ret.appendString(`for await (const ${loopVariable} of abap.statements.loop(${loopSource}${loopWhere})) {\n`);
103807
+ ret.appendString(this.transpileNext(body, traversal));
103808
+ ret.appendString(`}\n`);
103809
+ ret.appendString(`return ${returnField};\n`);
103810
+ ret.appendString("})())");
103811
+ return ret;
103812
+ }
103813
+ transpileIndex(body, forExpression, traversal) {
103814
+ if (["FROM", "TO", "GROUPS"].some(token => forExpression.findDirectTokenByText(token))) {
103815
+ throw new Error("ValueBody FOR todo, " + body.concatTokens());
103816
+ }
103817
+ const counter = forExpression.findDirectExpression(core_1.Expressions.InlineFieldDefinition);
103818
+ if (counter === undefined) {
103819
+ throw new Error("ValueBody FOR todo, " + body.concatTokens());
103820
+ }
103821
+ const cond = forExpression.findDirectExpression(core_1.Expressions.Cond);
103822
+ if (cond === undefined) {
103823
+ throw new Error("ValueBody FOR missing condition, " + body.concatTokens());
103824
+ }
103825
+ const hasUntil = forExpression.findDirectTokenByText("UNTIL") !== undefined;
103826
+ const hasWhile = forExpression.findDirectTokenByText("WHILE") !== undefined;
103827
+ if ((hasUntil ? 1 : 0) + (hasWhile ? 1 : 0) !== 1) {
103828
+ throw new Error("ValueBody FOR todo, condition, " + body.concatTokens());
103829
+ }
103830
+ const fieldName = counter.findDirectExpression(core_1.Expressions.Field)?.concatTokens().toLowerCase();
103831
+ if (fieldName === undefined) {
103832
+ throw new Error("ValueBody FOR todo, inline field, " + body.concatTokens());
103833
+ }
103834
+ const scope = traversal.findCurrentScopeByToken(counter.getFirstToken());
103835
+ const variable = scope?.findVariable(fieldName);
103836
+ if (variable === undefined) {
103837
+ throw new Error("ValueBody FOR todo, variable, " + body.concatTokens());
103838
+ }
103839
+ const counterName = traversal_1.Traversal.prefixVariable(fieldName);
103840
+ const startSource = counter.findDirectExpression(core_1.Expressions.Source);
103841
+ if (startSource === undefined) {
103842
+ throw new Error("ValueBody FOR missing initial value, " + body.concatTokens());
103843
+ }
103844
+ const start = traversal.traverse(startSource).getCode();
103845
+ const thenExpr = forExpression.findExpressionAfterToken("THEN");
103846
+ let incrementExpression = "";
103847
+ if (thenExpr && thenExpr instanceof core_1.Nodes.ExpressionNode) {
103848
+ incrementExpression = traversal.traverse(thenExpr).getCode();
103849
+ }
103850
+ else {
103851
+ incrementExpression = `abap.operators.add(${counterName}, new abap.types.Integer().set(1))`;
103852
+ }
103853
+ const condCode = traversal.traverse(cond).getCode();
103854
+ const ret = new chunk_1.Chunk();
103855
+ ret.appendString("(await (async () => {\n");
103856
+ const returnField = this.declareInit(body, traversal, ret);
103857
+ ret.appendString(transpile_types_1.TranspileTypes.declare(variable) + `\n`);
103858
+ ret.appendString(`${counterName}.set(${start});\n`);
103859
+ ret.appendString(`while (true) {\n`);
103860
+ if (hasWhile) {
103861
+ ret.appendString(`if (!(${condCode})) {\nbreak;\n}\n`);
103862
+ }
103863
+ ret.appendString(this.transpileNext(body, traversal));
103864
+ ret.appendString(`${counterName}.set(${incrementExpression});\n`);
103865
+ if (hasUntil) {
103866
+ ret.appendString(`if (${condCode}) {\nbreak;\n}\n`);
103867
+ }
103868
+ ret.appendString(`}\n`);
103869
+ ret.appendString(`return ${returnField};\n`);
103870
+ ret.appendString("})())");
103871
+ return ret;
103872
+ }
103873
+ declareInit(body, traversal, ret) {
103035
103874
  let returnField = "";
103036
103875
  for (const init of body.findDirectExpressions(core_1.Expressions.InlineFieldDefinition)) {
103037
103876
  const fieldName = init.findDirectExpression(core_1.Expressions.Field).concatTokens().toLowerCase();
@@ -103043,18 +103882,18 @@ class ReduceBodyTranspiler {
103043
103882
  }
103044
103883
  ret.appendString(transpile_types_1.TranspileTypes.declare(variable) + `\n`);
103045
103884
  }
103046
- ret.appendString(`for await (const ${loopVariable} of abap.statements.loop(${loopSource}${loopWhere})) {\n`);
103885
+ return returnField;
103886
+ }
103887
+ transpileNext(body, traversal) {
103888
+ let ret = "";
103047
103889
  for (const nextChild of body.findDirectExpression(core_1.Expressions.ReduceNext)?.getChildren() || []) {
103048
103890
  if (nextChild.get() instanceof core_1.Expressions.SimpleTarget && nextChild instanceof core_1.Nodes.ExpressionNode) {
103049
- ret.appendString(new target_1.TargetTranspiler().transpile(nextChild, traversal).getCode() + ".set(");
103891
+ ret += new target_1.TargetTranspiler().transpile(nextChild, traversal).getCode() + ".set(";
103050
103892
  }
103051
103893
  else if (nextChild.get() instanceof core_1.Expressions.Source && nextChild instanceof core_1.Nodes.ExpressionNode) {
103052
- ret.appendString(traversal.traverse(nextChild).getCode() + ");\n");
103894
+ ret += traversal.traverse(nextChild).getCode() + ");\n";
103053
103895
  }
103054
103896
  }
103055
- ret.appendString(`}\n`);
103056
- ret.appendString(`return ${returnField};\n`);
103057
- ret.appendString("})())");
103058
103897
  return ret;
103059
103898
  }
103060
103899
  }
@@ -104878,6 +105717,9 @@ class SwitchBodyTranspiler {
104878
105717
  else if (c.concatTokens() === "THEN") {
104879
105718
  mode = "THEN";
104880
105719
  }
105720
+ else if (c.concatTokens() === "ELSE") {
105721
+ mode = "";
105722
+ }
104881
105723
  }
104882
105724
  else if (mode === "WHEN" && c instanceof core_1.Nodes.ExpressionNode) {
104883
105725
  currentWhenThen.whenOr.push(c);
@@ -105274,6 +106116,7 @@ class ValueBodyTranspiler {
105274
106116
  }
105275
106117
  let post = "";
105276
106118
  let extraFields = "";
106119
+ let baseCode = undefined;
105277
106120
  const hasLines = body.findDirectExpression(core_1.Expressions.ValueBodyLine) !== undefined;
105278
106121
  const children = body.getChildren();
105279
106122
  for (let i = 0; i < children.length; i++) {
@@ -105289,7 +106132,8 @@ class ValueBodyTranspiler {
105289
106132
  }
105290
106133
  else if (child.get() instanceof core_1.Expressions.ValueBase && child instanceof core_1.Nodes.ExpressionNode) {
105291
106134
  const source = traversal.traverse(child.findDirectExpression(core_1.Expressions.Source));
105292
- ret = new chunk_1.Chunk().appendString(source.getCode() + ".clone()");
106135
+ baseCode = source.getCode() + ".clone()";
106136
+ ret = new chunk_1.Chunk().appendString(baseCode);
105293
106137
  }
105294
106138
  else if (child.get() instanceof core_1.Expressions.ValueBodyLine && child instanceof core_1.Nodes.ExpressionNode) {
105295
106139
  if (!(context instanceof core_1.BasicTypes.TableType)) {
@@ -105316,7 +106160,7 @@ class ValueBodyTranspiler {
105316
106160
  }
105317
106161
  }
105318
106162
  i = idx - 1;
105319
- const result = this.buildForChain(forNodes, typ, traversal, body);
106163
+ const result = this.buildForChain(forNodes, typ, traversal, body, baseCode);
105320
106164
  ret = result.chunk;
105321
106165
  post = result.post;
105322
106166
  }
@@ -105327,6 +106171,8 @@ class ValueBodyTranspiler {
105327
106171
  const pre = `(await (async () => { try { return `;
105328
106172
  ret = new chunk_1.Chunk().appendString(pre + ret.getCode());
105329
106173
  post += `; } catch (error) { if (abap.isLineNotFound(error)) { return ${deflt}; } throw error; } })())`;
106174
+ // the default value Source is part of this DEFAULT handling, stop processing further children
106175
+ break;
105330
106176
  }
105331
106177
  else if (child instanceof core_1.Nodes.TokenNode && child.getFirstToken().getStr().toUpperCase() === "OPTIONAL") {
105332
106178
  // note: this is last in the body, so its okay to prepend and postpend
@@ -105340,8 +106186,8 @@ class ValueBodyTranspiler {
105340
106186
  }
105341
106187
  return ret.appendString(post);
105342
106188
  }
105343
- buildForChain(forNodes, typ, traversal, body) {
105344
- const val = new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
106189
+ buildForChain(forNodes, typ, traversal, body, baseCode) {
106190
+ const val = baseCode ?? new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
105345
106191
  const chunk = new chunk_1.Chunk();
105346
106192
  const preLoopDecls = [];
105347
106193
  const descriptors = [];
@@ -105957,8 +106803,11 @@ class HandleFUGR {
105957
106803
  const contents = new traversal_1.Traversal(spaghetti, file, obj, reg, this.options).traverse(rearranged);
105958
106804
  chunk.appendChunk(contents);
105959
106805
  chunk.stripLastNewline();
105960
- chunk.runIndentationLogic(this.options?.ignoreSourceMap);
105961
106806
  }
106807
+ // indentation must run once over the accumulated chunk: running it per
106808
+ // appended file re-indents the earlier files, drifting the brace counter
106809
+ // and shifting their mapping columns multiple times
106810
+ chunk.runIndentationLogic(this.options?.ignoreSourceMap);
105962
106811
  chunk.appendString("\n}");
105963
106812
  const output = {
105964
106813
  object: {
@@ -108589,17 +109438,14 @@ const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/tr
108589
109438
  class ClearTranspiler {
108590
109439
  transpile(node, traversal) {
108591
109440
  const target = traversal.traverse(node.findDirectExpression(abaplint.Expressions.Target));
109441
+ // Reference implementation for the source-map convention:
109442
+ // - keep the target's own expression-level mappings by appending its Chunk
109443
+ // (do NOT flatten with target.getCode(), that discards the mappings)
109444
+ // - map the trailing generated syntax to the statement's last token, not
109445
+ // getEnd() which points one column past the statement
108592
109446
  const ret = new chunk_1.Chunk();
108593
- /*
108594
109447
  ret.appendChunk(target);
108595
- ret.append(".clear();", node.getLastToken().getEnd(), traversal);
108596
- */
108597
- ret.append(target.getCode() + ".clear();", node.getLastToken().getEnd(), traversal);
108598
- // ret.append(target.getCode() + ".clear();", node, traversal);
108599
- /*
108600
- ret.append(target.getCode(), node.getFirstToken().getStart(), traversal);
108601
- ret.append(".clear();", node.getLastToken().getEnd(), traversal);
108602
- */
109448
+ ret.append(".clear();", node.getLastToken(), traversal);
108603
109449
  return ret;
108604
109450
  }
108605
109451
  }
@@ -112007,8 +112853,11 @@ class LoopTranspiler {
112007
112853
  const source = traversal.traverse(loopSource).getCode();
112008
112854
  this.unique = unique_identifier_1.UniqueIdentifier.get();
112009
112855
  let target = "";
112856
+ // the abap expression the target-assignment line should map back to
112857
+ let targetNode = undefined;
112010
112858
  const into = this.determineInto(node);
112011
112859
  if (into && this.skipInto !== true) {
112860
+ targetNode = into;
112012
112861
  const concat = node.concatTokens().toUpperCase();
112013
112862
  const t = traversal.traverse(into).getCode();
112014
112863
  const scope = traversal.findCurrentScopeByToken(node.getFirstToken());
@@ -112028,6 +112877,7 @@ class LoopTranspiler {
112028
112877
  else if (this.skipInto !== true) {
112029
112878
  const assigning = node.findFirstExpression(abaplint.Expressions.FSTarget)?.findFirstExpression(abaplint.Expressions.FieldSymbol);
112030
112879
  if (assigning) {
112880
+ targetNode = assigning;
112031
112881
  target = traversal.traverse(assigning).getCode() + ".assign(" + this.unique + ");";
112032
112882
  }
112033
112883
  }
@@ -112108,7 +112958,15 @@ class LoopTranspiler {
112108
112958
  if (extra.length > 0) {
112109
112959
  concat = ",{" + extra.join(",") + "}";
112110
112960
  }
112111
- return new chunk_1.Chunk(`for await (const ${this.unique} of abap.statements.loop(${source}${concat})) {\n${target}`);
112961
+ // map the loop head to the statement start and the target-assignment line
112962
+ // (foo.set(unique)) back to the INTO/ASSIGNING target expression
112963
+ const ret = new chunk_1.Chunk();
112964
+ ret.append(`for await (const ${this.unique} of abap.statements.loop(${source}${concat})) {`, node, traversal);
112965
+ ret.appendString("\n");
112966
+ if (target !== "") {
112967
+ ret.append(target, targetNode ?? node, traversal);
112968
+ }
112969
+ return ret;
112112
112970
  }
112113
112971
  }
112114
112972
  exports.LoopTranspiler = LoopTranspiler;
@@ -113242,7 +114100,7 @@ class PerformTranspiler {
113242
114100
  index++;
113243
114101
  }
113244
114102
  index = 0;
113245
- for (const c of node.findDirectExpression(abaplint.Expressions.PerformChanging)?.findDirectExpressions(abaplint.Expressions.Source) || []) {
114103
+ for (const c of node.findDirectExpression(abaplint.Expressions.PerformChanging)?.findDirectExpressions(abaplint.Expressions.Target) || []) {
113246
114104
  const name = def?.getChangingParameters()[index].getName().toLowerCase();
113247
114105
  if (name === undefined) {
113248
114106
  continue;
@@ -116943,9 +117801,11 @@ class ConstantsTranspiler {
116943
117801
  if (name === undefined) {
116944
117802
  throw "ConstantsTranspilerName";
116945
117803
  }
116946
- let ret = new statements_1.DataTranspiler().transpile(begin, traversal).getCode() + "\n";
116947
- ret += ConstantsTranspiler.handleValues(name, node, traversal);
116948
- return new chunk_1.Chunk(ret);
117804
+ const ret = new chunk_1.Chunk();
117805
+ ret.appendChunk(new statements_1.DataTranspiler().transpile(begin, traversal).ensureStartMapping(begin, traversal));
117806
+ ret.appendString("\n");
117807
+ ret.appendString(ConstantsTranspiler.handleValues(name, node, traversal));
117808
+ return ret;
116949
117809
  }
116950
117810
  static handleValues(prefix, node, traversal) {
116951
117811
  let ret = "";
@@ -117021,7 +117881,7 @@ class DataTranspiler {
117021
117881
  return new chunk_1.Chunk("");
117022
117882
  }
117023
117883
  const topName = begin.findDirectExpression(abaplint.Expressions.DefinitionName)?.concatTokens().toLowerCase();
117024
- const chunk = new statements_1.DataTranspiler().transpile(begin, traversal);
117884
+ const chunk = new statements_1.DataTranspiler().transpile(begin, traversal).ensureStartMapping(begin, traversal);
117025
117885
  for (const d of node.findDirectStatements(abaplint.Statements.Data)) {
117026
117886
  const subName = d.findFirstExpression(abaplint.Expressions.DefinitionName)?.concatTokens().toLowerCase();
117027
117887
  if (subName && topName) {
@@ -117113,7 +117973,7 @@ class DoTranspiler {
117113
117973
  for (const c of node.getChildren()) {
117114
117974
  if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.Do) {
117115
117975
  traversal.registerDoOrWhileIndexBackup(c, syIndexBackup);
117116
- ret.appendChunk(new statements_1.DoTranspiler(syIndexBackup).transpile(c, traversal));
117976
+ ret.appendChunk(new statements_1.DoTranspiler(syIndexBackup).transpile(c, traversal).ensureStartMapping(c, traversal));
117117
117977
  ret.appendString("\n");
117118
117978
  }
117119
117979
  else if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.EndDo) {
@@ -117250,7 +118110,7 @@ const transpile_types_1 = __webpack_require__(/*! ../transpile_types */ "./node_
117250
118110
  const unique_identifier_1 = __webpack_require__(/*! ../unique_identifier */ "./node_modules/@abaplint/transpiler/build/src/unique_identifier.js");
117251
118111
  class FunctionModuleTranspiler {
117252
118112
  transpile(node, traversal) {
117253
- let r = "";
118113
+ const chunk = new chunk_1.Chunk();
117254
118114
  let name = "";
117255
118115
  for (const c of node.getChildren()) {
117256
118116
  if (c.get() instanceof abaplint.Statements.FunctionModule && c instanceof abaplint.Nodes.StatementNode) {
@@ -117258,19 +118118,19 @@ class FunctionModuleTranspiler {
117258
118118
  if (name === undefined) {
117259
118119
  name = "FunctionModuleTranspilerNameNotFound";
117260
118120
  }
117261
- r += `async function ${traversal_1.Traversal.escapeNamespace(name)}(INPUT) {\n`;
117262
- r += this.findSignature(traversal, name, c);
118121
+ chunk.append(`async function ${traversal_1.Traversal.escapeNamespace(name)}(INPUT) {\n`, c, traversal);
118122
+ chunk.appendString(this.findSignature(traversal, name, c));
117263
118123
  }
117264
118124
  else if (c.get() instanceof abaplint.Statements.EndFunction) {
117265
- r += "}\n";
117266
- r += `abap.FunctionModules['${name.toUpperCase()}'] = ${traversal_1.Traversal.escapeNamespace(name)};\n`;
118125
+ chunk.append("}\n", c, traversal);
118126
+ chunk.appendString(`abap.FunctionModules['${name.toUpperCase()}'] = ${traversal_1.Traversal.escapeNamespace(name)};\n`);
117267
118127
  }
117268
118128
  else {
117269
- r += traversal.traverse(c).getCode();
118129
+ chunk.appendChunk(traversal.traverse(c));
117270
118130
  }
117271
118131
  }
117272
118132
  unique_identifier_1.UniqueIdentifier.resetIndexBackup();
117273
- return new chunk_1.Chunk(r);
118133
+ return chunk;
117274
118134
  }
117275
118135
  //////////////////////
117276
118136
  findSignature(traversal, name, node) {
@@ -117599,6 +118459,7 @@ class LoopTranspiler {
117599
118459
  ret.appendString(`let ${tabix} = undefined;\n`);
117600
118460
  }
117601
118461
  const loop = new statements_1.LoopTranspiler();
118462
+ // LoopStatementTranspiler maps its own head, so no ensureStartMapping needed here
117602
118463
  ret.appendChunk(loop.transpile(c, traversal));
117603
118464
  ret.appendString("\n");
117604
118465
  if (hasAt === true) {
@@ -117789,7 +118650,8 @@ class SelectTranspiler {
117789
118650
  const targetName = unique_identifier_1.UniqueIdentifier.get();
117790
118651
  const loopName = unique_identifier_1.UniqueIdentifier.get();
117791
118652
  ret.appendString(`let ${targetName} = new abap.types.Table(abap.DDIC["${from}"].type());\n`);
117792
- ret.appendChunk(new select_1.SelectTranspiler().transpile(selectStatement, traversal, targetName));
118653
+ const selectHead = new select_1.SelectTranspiler().transpile(selectStatement, traversal, targetName);
118654
+ ret.appendChunk(selectHead.ensureStartMapping(selectStatement, traversal));
117793
118655
  // todo: optimize, it should do real streaming?
117794
118656
  const packageSize = selectStatement.findFirstExpression(abaplint.Expressions.SQLPackageSize)
117795
118657
  ?.findFirstExpression(abaplint.Expressions.SQLSource);
@@ -118114,7 +118976,7 @@ class WhileTranspiler {
118114
118976
  for (const c of node.getChildren()) {
118115
118977
  if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.While) {
118116
118978
  traversal.registerDoOrWhileIndexBackup(c, syIndexBackup);
118117
- ret.appendChunk(new statements_1.WhileTranspiler(syIndexBackup).transpile(c, traversal));
118979
+ ret.appendChunk(new statements_1.WhileTranspiler(syIndexBackup).transpile(c, traversal).ensureStartMapping(c, traversal));
118118
118980
  ret.appendString("\n");
118119
118981
  }
118120
118982
  else if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.EndWhile) {
@@ -119321,6 +120183,8 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
119321
120183
  if (list[search]) {
119322
120184
  const transpiler = new list[search]();
119323
120185
  const chunk = transpiler.transpile(node, this);
120186
+ // baseline: statements that emitted no mappings still resolve to their source
120187
+ chunk.ensureStartMapping(node, this);
119324
120188
  chunk.appendString("\n");
119325
120189
  return chunk;
119326
120190
  }