@abaplint/transpiler-cli 2.12.10 → 2.12.12

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 +280 -153
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -7266,11 +7266,14 @@ class SQLField extends combi_1.Expression {
7266
7266
  getRunnable() {
7267
7267
  const abap = (0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WAt), _1.SimpleFieldChain2), version_1.Version.OpenABAP);
7268
7268
  const as = (0, combi_1.seq)("AS", _1.SQLAsName);
7269
- const paren = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), _1.SQLFieldName, (0, combi_1.altPrio)((0, combi_1.tok)(tokens_1.WParenRightW), (0, combi_1.tok)(tokens_1.WParenRight)));
7270
- const field = (0, combi_1.altPrio)(_1.SQLAggregation, _1.SQLCase, _1.SQLCast, sql_function_1.SQLFunction, sql_path_1.SQLPath, _1.SQLFieldName, abap, _1.Constant, paren);
7271
- const sub = (0, combi_1.plusPrio)((0, combi_1.seq)((0, combi_1.altPrio)("+", "-", "*", "/", "&&"), (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenLeftW)), field, (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenRightW))));
7269
+ const parenFieldName = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), _1.SQLFieldName, (0, combi_1.altPrio)((0, combi_1.tok)(tokens_1.WParenRightW), (0, combi_1.tok)(tokens_1.WParenRight)));
7270
+ const field = (0, combi_1.altPrio)(_1.SQLAggregation, _1.SQLCase, _1.SQLCast, sql_function_1.SQLFunction, sql_path_1.SQLPath, _1.SQLFieldName, abap, _1.Constant, parenFieldName);
7271
+ const parenField = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), field, (0, combi_1.tok)(tokens_1.WParenRightW));
7272
+ const sub = (0, combi_1.plusPrio)((0, combi_1.seq)((0, combi_1.altPrio)("+", "-", "*", "/", "&&"), (0, combi_1.altPrio)(parenField, field)));
7272
7273
  const arith = (0, combi_1.ver)(version_1.Version.v740sp05, sub);
7273
- return (0, combi_1.seq)(field, (0, combi_1.optPrio)(arith), (0, combi_1.optPrio)(as));
7274
+ const arithSequence = (0, combi_1.seq)(field, (0, combi_1.optPrio)(arith));
7275
+ const parenArithSequence = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), arithSequence, (0, combi_1.tok)(tokens_1.WParenRightW));
7276
+ return (0, combi_1.seq)((0, combi_1.altPrio)(parenArithSequence, arithSequence), (0, combi_1.optPrio)(as));
7274
7277
  }
7275
7278
  }
7276
7279
  exports.SQLField = SQLField;
@@ -10728,17 +10731,18 @@ class Convert {
10728
10731
  const intoTime = (0, combi_1.seq)("TIME", expressions_1.Target);
10729
10732
  const intoDate = (0, combi_1.seq)("DATE", expressions_1.Target);
10730
10733
  const into = (0, combi_1.seq)("INTO", (0, combi_1.per)(intoTime, intoDate));
10731
- const daylight = (0, combi_1.seq)("DAYLIGHT SAVING TIME", expressions_1.Source);
10734
+ const daylightSource = (0, combi_1.seq)("DAYLIGHT SAVING TIME", expressions_1.Source);
10735
+ const daylightTarget = (0, combi_1.seq)("DAYLIGHT SAVING TIME", expressions_1.Target);
10732
10736
  const zone = (0, combi_1.seq)("TIME ZONE", expressions_1.Source);
10733
- const time = (0, combi_1.seq)("TIME STAMP", expressions_1.Source, (0, combi_1.per)(zone, into, daylight));
10737
+ const time = (0, combi_1.seq)("TIME STAMP", expressions_1.Source, (0, combi_1.per)(zone, into, daylightTarget));
10734
10738
  const dat = (0, combi_1.seq)("DATE", expressions_1.Source);
10735
10739
  const tim = (0, combi_1.seq)("TIME", expressions_1.Source);
10736
10740
  const stamp = (0, combi_1.seq)("INTO TIME STAMP", expressions_1.Target);
10737
10741
  const intoutc = (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("INTO UTCLONG", expressions_1.Target));
10738
10742
  const invert = (0, combi_1.seq)("INTO INVERTED-DATE", expressions_1.Target);
10739
- const date = (0, combi_1.seq)((0, combi_1.per)(dat, tim), (0, combi_1.per)(daylight, stamp, zone, invert, intoutc));
10743
+ const date = (0, combi_1.seq)((0, combi_1.per)(dat, tim), (0, combi_1.per)(daylightSource, stamp, zone, invert, intoutc));
10740
10744
  const inv = (0, combi_1.seq)("INVERTED-DATE", expressions_1.Source, "INTO DATE", expressions_1.Target);
10741
- const utclong = (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("UTCLONG", expressions_1.Source, (0, combi_1.per)(zone, into, daylight)));
10745
+ const utclong = (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("UTCLONG", expressions_1.Source, (0, combi_1.per)(zone, into, daylightSource)));
10742
10746
  return (0, combi_1.seq)("CONVERT", (0, combi_1.alt)(time, date, inv, utclong));
10743
10747
  }
10744
10748
  }
@@ -23101,7 +23105,6 @@ class BasicTypes {
23101
23105
  return undefined;
23102
23106
  }
23103
23107
  resolveLikeName(node, headerLogic = true) {
23104
- var _a;
23105
23108
  if (node === undefined) {
23106
23109
  return undefined;
23107
23110
  }
@@ -23147,7 +23150,12 @@ class BasicTypes {
23147
23150
  this.input.scope.addReference(chain === null || chain === void 0 ? void 0 : chain.getFirstToken(), found, _reference_1.ReferenceType.TypeReference, this.input.filename);
23148
23151
  }
23149
23152
  if (type === undefined) {
23150
- type = (_a = this.input.scope.getDDIC().lookupNoVoid(name)) === null || _a === void 0 ? void 0 : _a.type;
23153
+ const found = this.input.scope.getDDIC().lookupNoVoid(name);
23154
+ if (found !== undefined) {
23155
+ const using = { filename: this.input.filename, token: chain.getFirstToken(), object: found.object };
23156
+ this.input.scope.getDDICReferences().addUsing(this.input.scope.getParentObj(), using);
23157
+ }
23158
+ type = found === null || found === void 0 ? void 0 : found.type;
23151
23159
  }
23152
23160
  if (type === undefined && this.input.scope.isAnyOO() === false && this.input.scope.getDDIC().inErrorNamespace(name) === false) {
23153
23161
  this.input.scope.addReference(chain.getChildren()[0].getFirstToken(), undefined, _reference_1.ReferenceType.VoidType, this.input.filename);
@@ -24524,7 +24532,9 @@ class ComponentName {
24524
24532
  return ret;
24525
24533
  }
24526
24534
  }
24527
- input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameToken, "Not a structure, ComponentName, \"" + name + "\""));
24535
+ if (!(context instanceof Basic.UnknownType)) {
24536
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameToken, "Not a structure, ComponentName, \"" + name + "\", (" + (context === null || context === void 0 ? void 0 : context.constructor.name) + ")"));
24537
+ }
24528
24538
  return Basic.VoidType.get(_syntax_input_1.CheckSyntaxKey);
24529
24539
  }
24530
24540
  }
@@ -27843,7 +27853,7 @@ class SQLForAllEntries {
27843
27853
  }
27844
27854
  if (s) {
27845
27855
  const type = source_1.Source.runSyntax(s, input);
27846
- if (type instanceof basic_1.VoidType) {
27856
+ if (type instanceof basic_1.VoidType || type instanceof basic_1.UnknownType) {
27847
27857
  return;
27848
27858
  }
27849
27859
  if (!(type instanceof basic_1.TableType)) {
@@ -28198,8 +28208,9 @@ class Target {
28198
28208
  currentIndex++;
28199
28209
  if (current.get() instanceof tokens_1.Dash) {
28200
28210
  if (context instanceof unknown_type_1.UnknownType) {
28201
- const message = "Not a structure, type unknown, target";
28202
- input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
28211
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
28212
+ }
28213
+ else if (context instanceof basic_1.TableType && context.isWithHeader() && context.getRowType() instanceof unknown_type_1.UnknownType) {
28203
28214
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
28204
28215
  }
28205
28216
  else if (!(context instanceof basic_1.StructureType)
@@ -30194,14 +30205,21 @@ class Convert {
30194
30205
  for (const s of node.findDirectExpressions(Expressions.Source)) {
30195
30206
  source_1.Source.runSyntax(s, input);
30196
30207
  }
30197
- const timeTarget = node.findExpressionAfterToken("TIME");
30198
- if ((timeTarget === null || timeTarget === void 0 ? void 0 : timeTarget.get()) instanceof Expressions.Target) {
30199
- const inline = timeTarget === null || timeTarget === void 0 ? void 0 : timeTarget.findDirectExpression(Expressions.InlineData);
30200
- if (inline) {
30201
- inline_data_1.InlineData.runSyntax(inline, input, new basic_1.TimeType());
30202
- }
30203
- else {
30204
- target_1.Target.runSyntax(timeTarget, input);
30208
+ const timeTargets = node.findExpressionsAfterToken("TIME");
30209
+ for (const timeTarget of timeTargets) {
30210
+ const concat = node.concatTokens().toUpperCase();
30211
+ if ((timeTarget === null || timeTarget === void 0 ? void 0 : timeTarget.get()) instanceof Expressions.Target) {
30212
+ const inline = timeTarget === null || timeTarget === void 0 ? void 0 : timeTarget.findDirectExpression(Expressions.InlineData);
30213
+ if (inline) {
30214
+ let targetType = new basic_1.TimeType();
30215
+ if (concat.includes("DAYLIGHT SAVING TIME " + inline.concatTokens().toUpperCase())) {
30216
+ targetType = new basic_1.CharacterType(1);
30217
+ }
30218
+ inline_data_1.InlineData.runSyntax(inline, input, targetType);
30219
+ }
30220
+ else {
30221
+ target_1.Target.runSyntax(timeTarget, input);
30222
+ }
30205
30223
  }
30206
30224
  }
30207
30225
  const dateTarget = node.findExpressionAfterToken("DATE");
@@ -31519,27 +31537,27 @@ const basic_types_1 = __webpack_require__(/*! ../basic_types */ "./node_modules/
31519
31537
  const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifier */ "./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js");
31520
31538
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
31521
31539
  const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/assert_error.js");
31540
+ const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
31522
31541
  class IncludeType {
31523
31542
  runSyntax(node, input) {
31524
- var _a, _b, _c, _d, _e;
31543
+ var _a, _b;
31525
31544
  const components = [];
31526
31545
  const iname = node.findFirstExpression(Expressions.TypeName);
31527
31546
  if (iname === undefined) {
31528
31547
  throw new assert_error_1.AssertError("IncludeType, unexpected node structure");
31529
31548
  }
31530
- const name = iname.getFirstToken().getStr();
31549
+ const firstToken = iname.getFirstToken();
31550
+ const name = firstToken.getStr();
31531
31551
  const isStructure = node.findDirectTokenByText("STRUCTURE") !== undefined;
31532
31552
  let ityp = new basic_types_1.BasicTypes(input).parseType(iname);
31533
- if (ityp instanceof basic_1.VoidType && isStructure) {
31534
- const found = (_a = input.scope.findVariable(name)) === null || _a === void 0 ? void 0 : _a.getType();
31553
+ if ((ityp instanceof basic_1.VoidType && isStructure) || ityp instanceof basic_1.UnknownType) {
31554
+ const found = input.scope.findVariable(name);
31535
31555
  if (found) {
31536
- ityp = found;
31556
+ input.scope.addReference(firstToken, found, _reference_1.ReferenceType.DataReadReference, input.filename);
31557
+ ityp = found.getType();
31537
31558
  }
31538
31559
  }
31539
- else if (ityp instanceof basic_1.UnknownType) {
31540
- ityp = (_c = (_b = input.scope.findVariable(name)) === null || _b === void 0 ? void 0 : _b.getType()) !== null && _c !== void 0 ? _c : ityp;
31541
- }
31542
- const as = (_d = node.findExpressionAfterToken("AS")) === null || _d === void 0 ? void 0 : _d.concatTokens();
31560
+ const as = (_a = node.findExpressionAfterToken("AS")) === null || _a === void 0 ? void 0 : _a.concatTokens();
31543
31561
  if (as && ityp instanceof basic_1.StructureType) {
31544
31562
  ityp = new basic_1.StructureType(ityp.getComponents().concat([{
31545
31563
  name: as,
@@ -31561,7 +31579,7 @@ class IncludeType {
31561
31579
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, iname.getFirstToken(), message));
31562
31580
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
31563
31581
  }
31564
- const suffix = (_e = node.findExpressionAfterToken("SUFFIX")) === null || _e === void 0 ? void 0 : _e.concatTokens();
31582
+ const suffix = (_b = node.findExpressionAfterToken("SUFFIX")) === null || _b === void 0 ? void 0 : _b.concatTokens();
31565
31583
  if (suffix && ityp instanceof basic_1.StructureType) {
31566
31584
  const components = [];
31567
31585
  for (const c of ityp.getComponents()) {
@@ -32960,6 +32978,9 @@ class ReadTable {
32960
32978
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
32961
32979
  return;
32962
32980
  }
32981
+ else if (sourceType instanceof basic_1.UnknownType) {
32982
+ // do nothing, ok
32983
+ }
32963
32984
  else if (!(sourceType instanceof basic_1.TableType) && !(sourceType instanceof basic_1.VoidType)) {
32964
32985
  const message = "Read table, not a table type";
32965
32986
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
@@ -53783,7 +53804,7 @@ class Registry {
53783
53804
  }
53784
53805
  static abaplintVersion() {
53785
53806
  // magic, see build script "version.sh"
53786
- return "2.113.240";
53807
+ return "2.113.246";
53787
53808
  }
53788
53809
  getDDICReferences() {
53789
53810
  return this.ddicReferences;
@@ -56694,6 +56715,7 @@ const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./nod
56694
56715
  const include_graph_1 = __webpack_require__(/*! ../utils/include_graph */ "./node_modules/@abaplint/core/build/src/utils/include_graph.js");
56695
56716
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
56696
56717
  const objects_1 = __webpack_require__(/*! ../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
56718
+ const severity_1 = __webpack_require__(/*! ../severity */ "./node_modules/@abaplint/core/build/src/severity.js");
56697
56719
  class CheckIncludeConf extends _basic_rule_config_1.BasicRuleConfig {
56698
56720
  }
56699
56721
  exports.CheckIncludeConf = CheckIncludeConf;
@@ -56722,7 +56744,7 @@ class CheckInclude {
56722
56744
  }
56723
56745
  initialize(reg) {
56724
56746
  this.reg = reg;
56725
- this.graph = new include_graph_1.IncludeGraph(this.reg);
56747
+ this.graph = new include_graph_1.IncludeGraph(this.reg, this.getConfig().severity || severity_1.Severity.Error);
56726
56748
  return this;
56727
56749
  }
56728
56750
  run(obj) {
@@ -77420,10 +77442,11 @@ class Graph {
77420
77442
  }
77421
77443
  }
77422
77444
  class IncludeGraph {
77423
- constructor(reg) {
77445
+ constructor(reg, severity = severity_1.Severity.Error) {
77424
77446
  this.reg = reg;
77425
77447
  this.issues = [];
77426
77448
  this.graph = new Graph();
77449
+ this.severity = severity;
77427
77450
  this.build();
77428
77451
  }
77429
77452
  listMainForInclude(filename) {
@@ -77453,7 +77476,7 @@ class IncludeGraph {
77453
77476
  if (f === undefined) {
77454
77477
  throw new Error("findUnusedIncludes internal error");
77455
77478
  }
77456
- const issue = issue_1.Issue.atPosition(f, new position_1.Position(1, 1), "INCLUDE not used anywhere", new check_include_1.CheckInclude().getMetadata().key, severity_1.Severity.Error);
77479
+ const issue = issue_1.Issue.atPosition(f, new position_1.Position(1, 1), "INCLUDE not used anywhere", new check_include_1.CheckInclude().getMetadata().key, this.severity);
77457
77480
  ret.push(issue);
77458
77481
  }
77459
77482
  return ret;
@@ -77481,12 +77504,12 @@ class IncludeGraph {
77481
77504
  if (found === undefined) {
77482
77505
  const ifFound = s.concatTokens().toUpperCase().includes("IF FOUND");
77483
77506
  if (ifFound === false) {
77484
- const issue = issue_1.Issue.atStatement(f, s, "Include " + name + " not found", new check_include_1.CheckInclude().getMetadata().key, severity_1.Severity.Error);
77507
+ const issue = issue_1.Issue.atStatement(f, s, "Include " + name + " not found", new check_include_1.CheckInclude().getMetadata().key, this.severity);
77485
77508
  this.issues.push(issue);
77486
77509
  }
77487
77510
  }
77488
77511
  else if (found.include === false) {
77489
- const issue = issue_1.Issue.atStatement(f, s, "Not possible to INCLUDE a main program, " + name, new check_include_1.CheckInclude().getMetadata().key, severity_1.Severity.Error);
77512
+ const issue = issue_1.Issue.atStatement(f, s, "Not possible to INCLUDE a main program, " + name, new check_include_1.CheckInclude().getMetadata().key, this.severity);
77490
77513
  this.issues.push(issue);
77491
77514
  }
77492
77515
  else {
@@ -78782,13 +78805,13 @@ class CompareTranspiler {
78782
78805
  const field = concat.replace(" IS NOT REQUESTED", "").toLowerCase();
78783
78806
  return new chunk_1.Chunk().appendString(pre + "INPUT && INPUT." + field + " === undefined && INPUT.importing?." + field + " === undefined");
78784
78807
  }
78785
- if (concat.startsWith("NOT ") || concat.includes(" IS NOT INSTANCE OF ")) {
78786
- const cname = node.findDirectExpression(core_1.Expressions.ClassName)?.concatTokens();
78787
- return new chunk_1.Chunk().appendString("abap.compare.instance_of(").appendChunk(s0).appendString(`, ${cname}) === false`);
78788
- }
78789
- else if (concat.includes(" IS INSTANCE OF ")) {
78790
- const cname = node.findDirectExpression(core_1.Expressions.ClassName)?.concatTokens();
78791
- return new chunk_1.Chunk().appendString("abap.compare.instance_of(").appendChunk(s0).appendString(`, ${cname})`);
78808
+ if (concat.includes(" IS INSTANCE OF ")) {
78809
+ const notted = concat.startsWith("NOT ") || concat.includes(" IS NOT INSTANCE OF ");
78810
+ const falsed = notted ? " === false" : "";
78811
+ const expr = node.findDirectExpression(core_1.Expressions.ClassName);
78812
+ const cname = expr?.concatTokens();
78813
+ const lookup = traversal.lookupClassOrInterface(cname, expr?.getFirstToken());
78814
+ return new chunk_1.Chunk().appendString("abap.compare.instance_of(").appendChunk(s0).appendString(`, ${lookup})` + falsed);
78792
78815
  }
78793
78816
  }
78794
78817
  else if (sources.length === 2 && node.findDirectTokenByText("IN")) {
@@ -82497,7 +82520,9 @@ class ValueBodyTranspiler {
82497
82520
  let post = "";
82498
82521
  let extraFields = "";
82499
82522
  const hasLines = body.findDirectExpression(core_1.Expressions.ValueBodyLine) !== undefined;
82500
- for (const child of body.getChildren()) {
82523
+ const children = body.getChildren();
82524
+ for (let i = 0; i < children.length; i++) {
82525
+ const child = children[i];
82501
82526
  if (child.get() instanceof core_1.Expressions.FieldAssignment && child instanceof core_1.Nodes.ExpressionNode) {
82502
82527
  const transpiled = new field_assignment_1.FieldAssignmentTranspiler().transpile(child, traversal, context).getCode();
82503
82528
  if (hasLines === false) {
@@ -82523,117 +82548,22 @@ class ValueBodyTranspiler {
82523
82548
  ret.appendString(".set(" + source.getCode() + ".clone())");
82524
82549
  }
82525
82550
  else if (child.get() instanceof core_1.Expressions.For && child instanceof core_1.Nodes.ExpressionNode) {
82526
- const loop = child.findDirectExpression(core_1.Expressions.InlineLoopDefinition);
82527
- if (loop) {
82528
- if (["THEN", "UNTIL", "WHILE", "FROM", "TO", "GROUPS"].some(token => child.findDirectTokenByText(token))) {
82529
- throw new Error("ValueBody FOR todo, " + body.concatTokens());
82530
- }
82531
- let loopWhere = "";
82532
- const whereNode = child?.findDirectExpression(core_1.Expressions.ComponentCond);
82533
- if (whereNode) {
82534
- const where = traversal.traverse(whereNode).getCode();
82535
- loopWhere = `, {"where": async ` + where + `}`;
82536
- }
82537
- const base = loop.findDirectExpression(core_1.Expressions.ValueBase);
82538
- if (base) {
82539
- throw new Error("ValueBody FOR todo, base, " + body.concatTokens());
82540
- }
82541
- let targetDeclare = "";
82542
- let targetAction = "";
82543
- const fs = loop.findDirectExpression(core_1.Expressions.TargetFieldSymbol);
82544
- if (fs) {
82545
- targetDeclare = new statements_1.FieldSymbolTranspiler().transpile(fs, traversal).getCode();
82546
- const targetName = new source_field_symbol_1.SourceFieldSymbolTranspiler().transpile(fs, traversal).getCode();
82547
- targetAction = `${targetName}.assign(unique1);`;
82548
- }
82549
- else {
82550
- const field = traversal.traverse(loop.findDirectExpression(core_1.Expressions.TargetField));
82551
- if (field === undefined) {
82552
- throw new Error("ValueBody FOR empty field todo, " + body.concatTokens());
82553
- }
82554
- targetAction = `const ${field.getCode()} = unique1.clone();`;
82555
- }
82556
- const llet = child.findDirectExpression(core_1.Expressions.Let);
82557
- if (llet) {
82558
- targetAction += new let_1.LetTranspiler().transpile(llet, traversal).getCode();
82559
- }
82560
- const source = traversal.traverse(loop.findDirectExpression(core_1.Expressions.Source)).getCode();
82561
- const val = new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
82562
- ret = new chunk_1.Chunk().appendString(`await (async () => {
82563
- ${targetDeclare}
82564
- const VAL = ${val};
82565
- for await (const unique1 of abap.statements.loop(${source}${loopWhere})) {
82566
- ${targetAction}
82567
- VAL`);
82568
- post = ";\n}\nreturn VAL;\n})()";
82569
- }
82570
- else {
82571
- const counter = child.findDirectExpression(core_1.Expressions.InlineFieldDefinition);
82572
- if (counter === undefined) {
82573
- throw new Error("ValueBody FOR todo, " + body.concatTokens());
82574
- }
82575
- if (["GROUPS", "FROM", "TO"].some(token => child.findDirectTokenByText(token))) {
82576
- throw new Error("ValueBody FOR todo, " + body.concatTokens());
82577
- }
82578
- if (child.findDirectExpression(core_1.Expressions.ComponentCond)) {
82579
- throw new Error("ValueBody FOR todo, component cond, " + body.concatTokens());
82580
- }
82581
- const cond = child.findDirectExpression(core_1.Expressions.Cond);
82582
- if (cond === undefined) {
82583
- throw new Error("ValueBody FOR missing condition, " + body.concatTokens());
82584
- }
82585
- const hasUntil = child.findDirectTokenByText("UNTIL") !== undefined;
82586
- const hasWhile = child.findDirectTokenByText("WHILE") !== undefined;
82587
- if ((hasUntil ? 1 : 0) + (hasWhile ? 1 : 0) !== 1) {
82588
- throw new Error("ValueBody FOR todo, condition, " + body.concatTokens());
82589
- }
82590
- const fieldExpr = counter.findDirectExpression(core_1.Expressions.Field);
82591
- const fieldName = fieldExpr?.concatTokens().toLowerCase();
82592
- if (fieldName === undefined) {
82593
- throw new Error("ValueBody FOR todo, inline field, " + body.concatTokens());
82594
- }
82595
- const scope = traversal.findCurrentScopeByToken(counter.getFirstToken());
82596
- const variable = scope?.findVariable(fieldName);
82597
- if (variable === undefined) {
82598
- throw new Error("ValueBody FOR todo, variable, " + body.concatTokens());
82599
- }
82600
- const declare = transpile_types_1.TranspileTypes.declare(variable);
82601
- const counterName = traversal_1.Traversal.prefixVariable(fieldName);
82602
- const startSource = counter.findDirectExpression(core_1.Expressions.Source);
82603
- if (startSource === undefined) {
82604
- throw new Error("ValueBody FOR missing initial value, " + body.concatTokens());
82605
- }
82606
- const start = traversal.traverse(startSource).getCode();
82607
- const thenExpr = child.findExpressionAfterToken("THEN");
82608
- let incrementExpression = "";
82609
- if (thenExpr && thenExpr instanceof core_1.Nodes.ExpressionNode) {
82610
- incrementExpression = traversal.traverse(thenExpr).getCode();
82551
+ const forNodes = [];
82552
+ let idx = i;
82553
+ while (idx < children.length) {
82554
+ const candidate = children[idx];
82555
+ if (candidate.get() instanceof core_1.Expressions.For && candidate instanceof core_1.Nodes.ExpressionNode) {
82556
+ forNodes.push(candidate);
82557
+ idx++;
82611
82558
  }
82612
82559
  else {
82613
- incrementExpression = `abap.operators.add(${counterName}, new abap.types.Integer().set(1))`;
82614
- }
82615
- const incrementLine = `${counterName}.set(${incrementExpression});`;
82616
- const llet = child.findDirectExpression(core_1.Expressions.Let);
82617
- let letCode = "";
82618
- if (llet) {
82619
- letCode = new let_1.LetTranspiler().transpile(llet, traversal).getCode();
82620
- }
82621
- const letSection = letCode === "" ? "" : " " + letCode.replace(/\n/g, "\n ") + "\n";
82622
- const condCode = traversal.traverse(cond).getCode();
82623
- const val = new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
82624
- const preCheck = hasWhile ? ` if (!(${condCode})) {\n break;\n }\n` : "";
82625
- let postLoop = ` ${incrementLine}\n`;
82626
- if (hasUntil) {
82627
- postLoop += ` if (${condCode}) {\n break;\n }\n`;
82560
+ break;
82628
82561
  }
82629
- ret = new chunk_1.Chunk().appendString(`await (async () => {
82630
- ${declare}
82631
- ${counterName}.set(${start});
82632
- const VAL = ${val};
82633
- while (true) {
82634
- ${preCheck}${letSection} VAL`);
82635
- post = ";\n" + postLoop + "}\nreturn VAL;\n})()";
82636
82562
  }
82563
+ i = idx - 1;
82564
+ const result = this.buildForChain(forNodes, typ, traversal, body);
82565
+ ret = result.chunk;
82566
+ post = result.post;
82637
82567
  }
82638
82568
  else if (child instanceof core_1.Nodes.TokenNode && child.getFirstToken().getStr().toUpperCase() === "DEFAULT") {
82639
82569
  // note: this is last in the body, so its okay to prepend and postpend
@@ -82655,6 +82585,203 @@ ${preCheck}${letSection} VAL`);
82655
82585
  }
82656
82586
  return ret.appendString(post);
82657
82587
  }
82588
+ buildForChain(forNodes, typ, traversal, body) {
82589
+ const val = new type_name_or_infer_1.TypeNameOrInfer().transpile(typ, traversal).getCode();
82590
+ const chunk = new chunk_1.Chunk();
82591
+ const preLoopDecls = [];
82592
+ const descriptors = [];
82593
+ const levelIndents = [];
82594
+ let uniqueCounter = 1;
82595
+ for (const child of forNodes) {
82596
+ const loop = child.findDirectExpression(core_1.Expressions.InlineLoopDefinition);
82597
+ if (loop) {
82598
+ if (["THEN", "UNTIL", "WHILE", "FROM", "TO", "GROUPS"].some(token => child.findDirectTokenByText(token))) {
82599
+ throw new Error("ValueBody FOR todo, " + body.concatTokens());
82600
+ }
82601
+ let loopWhere = "";
82602
+ const whereNode = child.findDirectExpression(core_1.Expressions.ComponentCond);
82603
+ if (whereNode) {
82604
+ const where = traversal.traverse(whereNode).getCode();
82605
+ loopWhere = `, {"where": async ` + where + `}`;
82606
+ }
82607
+ const base = loop.findDirectExpression(core_1.Expressions.ValueBase);
82608
+ if (base) {
82609
+ throw new Error("ValueBody FOR todo, base, " + body.concatTokens());
82610
+ }
82611
+ let targetDeclare = "";
82612
+ let targetAction = "";
82613
+ const fs = loop.findDirectExpression(core_1.Expressions.TargetFieldSymbol);
82614
+ const uniqueName = `unique${uniqueCounter++}`;
82615
+ if (fs) {
82616
+ targetDeclare = new statements_1.FieldSymbolTranspiler().transpile(fs, traversal).getCode();
82617
+ const targetName = new source_field_symbol_1.SourceFieldSymbolTranspiler().transpile(fs, traversal).getCode();
82618
+ targetAction = `${targetName}.assign(${uniqueName});`;
82619
+ }
82620
+ else {
82621
+ const field = traversal.traverse(loop.findDirectExpression(core_1.Expressions.TargetField));
82622
+ if (field === undefined) {
82623
+ throw new Error("ValueBody FOR empty field todo, " + body.concatTokens());
82624
+ }
82625
+ targetAction = `const ${field.getCode()} = ${uniqueName}.clone();`;
82626
+ }
82627
+ const llet = child.findDirectExpression(core_1.Expressions.Let);
82628
+ if (llet) {
82629
+ targetAction += new let_1.LetTranspiler().transpile(llet, traversal).getCode();
82630
+ }
82631
+ const preBodyStatements = [];
82632
+ if (targetAction !== "") {
82633
+ preBodyStatements.push(targetAction);
82634
+ }
82635
+ const source = traversal.traverse(loop.findDirectExpression(core_1.Expressions.Source)).getCode();
82636
+ if (targetDeclare !== "") {
82637
+ preLoopDecls.push(targetDeclare);
82638
+ }
82639
+ const descriptor = {
82640
+ beforeLoop: [],
82641
+ open: `for await (const ${uniqueName} of abap.statements.loop(${source}${loopWhere})) {`,
82642
+ preBody: preBodyStatements,
82643
+ postBody: [],
82644
+ close: "}",
82645
+ };
82646
+ const loopTokens = loop.concatTokens().toUpperCase();
82647
+ const indexTarget = loopTokens.includes("INDEX INTO") ? loop.findExpressionAfterToken("INTO") : undefined;
82648
+ if (indexTarget && indexTarget instanceof core_1.Nodes.ExpressionNode) {
82649
+ const indexCode = traversal.traverse(indexTarget).getCode();
82650
+ const counterName = `unique${uniqueCounter++}`;
82651
+ descriptor.beforeLoop.push(`let ${counterName} = 1;`);
82652
+ descriptor.preBody.push(`const ${indexCode} = new abap.types.Integer().set(${counterName});`);
82653
+ descriptor.postBody.push(`${counterName}++;`);
82654
+ }
82655
+ descriptors.push(descriptor);
82656
+ }
82657
+ else {
82658
+ const counter = child.findDirectExpression(core_1.Expressions.InlineFieldDefinition);
82659
+ if (counter === undefined) {
82660
+ throw new Error("ValueBody FOR todo, " + body.concatTokens());
82661
+ }
82662
+ if (["GROUPS", "FROM", "TO"].some(token => child.findDirectTokenByText(token))) {
82663
+ throw new Error("ValueBody FOR todo, " + body.concatTokens());
82664
+ }
82665
+ if (child.findDirectExpression(core_1.Expressions.ComponentCond)) {
82666
+ throw new Error("ValueBody FOR todo, component cond, " + body.concatTokens());
82667
+ }
82668
+ const cond = child.findDirectExpression(core_1.Expressions.Cond);
82669
+ if (cond === undefined) {
82670
+ throw new Error("ValueBody FOR missing condition, " + body.concatTokens());
82671
+ }
82672
+ const hasUntil = child.findDirectTokenByText("UNTIL") !== undefined;
82673
+ const hasWhile = child.findDirectTokenByText("WHILE") !== undefined;
82674
+ if ((hasUntil ? 1 : 0) + (hasWhile ? 1 : 0) !== 1) {
82675
+ throw new Error("ValueBody FOR todo, condition, " + body.concatTokens());
82676
+ }
82677
+ const fieldExpr = counter.findDirectExpression(core_1.Expressions.Field);
82678
+ const fieldName = fieldExpr?.concatTokens().toLowerCase();
82679
+ if (fieldName === undefined) {
82680
+ throw new Error("ValueBody FOR todo, inline field, " + body.concatTokens());
82681
+ }
82682
+ const scope = traversal.findCurrentScopeByToken(counter.getFirstToken());
82683
+ const variable = scope?.findVariable(fieldName);
82684
+ if (variable === undefined) {
82685
+ throw new Error("ValueBody FOR todo, variable, " + body.concatTokens());
82686
+ }
82687
+ const declare = transpile_types_1.TranspileTypes.declare(variable);
82688
+ const counterName = traversal_1.Traversal.prefixVariable(fieldName);
82689
+ const startSource = counter.findDirectExpression(core_1.Expressions.Source);
82690
+ if (startSource === undefined) {
82691
+ throw new Error("ValueBody FOR missing initial value, " + body.concatTokens());
82692
+ }
82693
+ const start = traversal.traverse(startSource).getCode();
82694
+ const thenExpr = child.findExpressionAfterToken("THEN");
82695
+ let incrementExpression = "";
82696
+ if (thenExpr && thenExpr instanceof core_1.Nodes.ExpressionNode) {
82697
+ incrementExpression = traversal.traverse(thenExpr).getCode();
82698
+ }
82699
+ else {
82700
+ incrementExpression = `abap.operators.add(${counterName}, new abap.types.Integer().set(1))`;
82701
+ }
82702
+ const incrementLine = `${counterName}.set(${incrementExpression});`;
82703
+ const llet = child.findDirectExpression(core_1.Expressions.Let);
82704
+ let letCode = "";
82705
+ if (llet) {
82706
+ letCode = new let_1.LetTranspiler().transpile(llet, traversal).getCode();
82707
+ }
82708
+ const condCode = traversal.traverse(cond).getCode();
82709
+ const preCheck = hasWhile ? `if (!(${condCode})) {\n break;\n}` : "";
82710
+ const postLoop = [];
82711
+ postLoop.push(incrementLine);
82712
+ if (hasUntil) {
82713
+ postLoop.push(`if (${condCode}) {\n break;\n}`);
82714
+ }
82715
+ descriptors.push({
82716
+ beforeLoop: [declare, `${counterName}.set(${start});`],
82717
+ open: "while (true) {",
82718
+ preBody: [preCheck, letCode].filter(s => s !== ""),
82719
+ postBody: postLoop,
82720
+ close: "}",
82721
+ });
82722
+ }
82723
+ }
82724
+ if (descriptors.length === 0) {
82725
+ throw new Error("ValueBodyTranspiler FOR internal error");
82726
+ }
82727
+ chunk.appendString("await (async () => {\n");
82728
+ this.appendBlocks(chunk, preLoopDecls, "");
82729
+ chunk.appendString(`const VAL = ${val};\n`);
82730
+ let indent = "";
82731
+ for (const desc of descriptors) {
82732
+ this.appendBlocks(chunk, desc.beforeLoop, indent);
82733
+ chunk.appendString(indent + desc.open + "\n");
82734
+ indent += " ";
82735
+ levelIndents.push(indent);
82736
+ this.appendBlocks(chunk, desc.preBody, indent);
82737
+ }
82738
+ chunk.appendString(indent + "VAL");
82739
+ let post = ";\n";
82740
+ for (let i = descriptors.length - 1; i >= 0; i--) {
82741
+ const desc = descriptors[i];
82742
+ const currentIndent = levelIndents[i] ?? "";
82743
+ post += this.blocksToString(desc.postBody, currentIndent);
82744
+ const parentIndent = currentIndent.substring(0, Math.max(0, currentIndent.length - 2));
82745
+ post += parentIndent + desc.close + "\n";
82746
+ }
82747
+ post += "return VAL;\n})()";
82748
+ return { chunk, post };
82749
+ }
82750
+ appendBlocks(chunk, blocks, indent) {
82751
+ for (const block of blocks) {
82752
+ this.appendBlock(chunk, block, indent);
82753
+ }
82754
+ }
82755
+ appendBlock(chunk, block, indent) {
82756
+ if (block === "") {
82757
+ return;
82758
+ }
82759
+ const lines = block.split("\n");
82760
+ for (const line of lines) {
82761
+ const clean = line.replace(/\r/g, "");
82762
+ if (clean.trim() === "") {
82763
+ continue;
82764
+ }
82765
+ chunk.appendString(indent + clean + "\n");
82766
+ }
82767
+ }
82768
+ blocksToString(blocks, indent) {
82769
+ let ret = "";
82770
+ for (const block of blocks) {
82771
+ if (block === "") {
82772
+ continue;
82773
+ }
82774
+ const lines = block.split("\n");
82775
+ for (const line of lines) {
82776
+ const clean = line.replace(/\r/g, "");
82777
+ if (clean.trim() === "") {
82778
+ continue;
82779
+ }
82780
+ ret += indent + clean + "\n";
82781
+ }
82782
+ }
82783
+ return ret;
82784
+ }
82658
82785
  }
82659
82786
  exports.ValueBodyTranspiler = ValueBodyTranspiler;
82660
82787
  //# sourceMappingURL=value_body.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.12.10",
3
+ "version": "2.12.12",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,8 +27,8 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.113.240",
31
- "@abaplint/transpiler": "^2.12.10",
30
+ "@abaplint/core": "^2.113.246",
31
+ "@abaplint/transpiler": "^2.12.12",
32
32
  "@types/glob": "^8.1.0",
33
33
  "@types/node": "^24.10.1",
34
34
  "@types/progress": "^2.0.7",