@abaplint/core 2.93.16 → 2.93.17

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.
@@ -14,7 +14,7 @@ class For extends combi_1.Expression {
14
14
  const then = (0, combi_1.seq)("THEN", _1.Source);
15
15
  const whil = (0, combi_1.seq)((0, combi_1.altPrio)("UNTIL", "WHILE"), _1.Cond);
16
16
  const itera = (0, combi_1.seq)(_1.InlineFieldDefinition, (0, combi_1.opt)(then), whil);
17
- const groupBy = (0, combi_1.seq)("GROUP BY", field_chain_1.FieldChain);
17
+ const groupBy = (0, combi_1.seq)("GROUP BY", (0, combi_1.alt)(field_chain_1.FieldChain, (0, combi_1.seq)("(", (0, combi_1.plus)(_1.LoopGroupByComponent), ")")));
18
18
  const groups = (0, combi_1.ver)(version_1.Version.v740sp08, (0, combi_1.seq)("GROUPS", field_chain_1.FieldChain, "OF", _1.Target, "IN", _1.Source, (0, combi_1.optPrio)(groupBy)));
19
19
  const f = (0, combi_1.seq)("FOR", (0, combi_1.alt)(itera, inn, groups), (0, combi_1.optPrio)(_1.Let));
20
20
  return (0, combi_1.ver)(version_1.Version.v740sp05, f);
@@ -10,12 +10,14 @@ const component_cond_1 = require("./component_cond");
10
10
  const cond_1 = require("./cond");
11
11
  class For {
12
12
  runSyntax(node, scope, filename) {
13
+ let scoped = false;
13
14
  const inlineLoop = node.findDirectExpressions(Expressions.InlineLoopDefinition);
14
15
  const inlineField = node.findAllExpressions(Expressions.InlineFieldDefinition);
15
16
  const addScope = inlineLoop.length > 0 || inlineField.length > 0;
16
17
  if (addScope) {
17
18
  // this scope is popped in parent expressions
18
19
  scope.push(_scope_type_1.ScopeType.For, "FOR", node.getFirstToken().getStart(), filename);
20
+ scoped = true;
19
21
  }
20
22
  for (const s of inlineLoop) {
21
23
  new inline_loop_definition_1.InlineLoopDefinition().runSyntax(s, scope, filename);
@@ -32,6 +34,7 @@ class For {
32
34
  for (const s of node.findDirectExpressions(Expressions.Cond)) {
33
35
  new cond_1.Cond().runSyntax(s, scope, filename);
34
36
  }
37
+ return scoped;
35
38
  }
36
39
  }
37
40
  exports.For = For;
@@ -6,20 +6,23 @@ const for_1 = require("./for");
6
6
  const source_1 = require("./source");
7
7
  const let_1 = require("./let");
8
8
  const field_assignment_1 = require("./field_assignment");
9
- const _scope_type_1 = require("../_scope_type");
10
9
  const basic_1 = require("../../types/basic");
11
10
  class ValueBody {
12
11
  runSyntax(node, scope, filename, targetType) {
13
12
  if (node === undefined) {
14
13
  return targetType;
15
14
  }
15
+ let forScopes = 0;
16
16
  for (const forNode of node.findDirectExpressions(Expressions.For) || []) {
17
- new for_1.For().runSyntax(forNode, scope, filename);
17
+ const scoped = new for_1.For().runSyntax(forNode, scope, filename);
18
+ if (scoped === true) {
19
+ forScopes++;
20
+ }
18
21
  }
19
- let scoped = false;
22
+ let letScoped = false;
20
23
  const letNode = node.findDirectExpression(Expressions.Let);
21
24
  if (letNode) {
22
- scoped = new let_1.Let().runSyntax(letNode, scope, filename);
25
+ letScoped = new let_1.Let().runSyntax(letNode, scope, filename);
23
26
  }
24
27
  for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) {
25
28
  new field_assignment_1.FieldAssignment().runSyntax(s, scope, filename, targetType);
@@ -52,10 +55,10 @@ class ValueBody {
52
55
  new source_1.Source().runSyntax(s, scope, filename);
53
56
  }
54
57
  }
55
- if (scoped === true) {
58
+ if (letScoped === true) {
56
59
  scope.pop(node.getLastToken().getEnd());
57
60
  }
58
- while (scope.getType() === _scope_type_1.ScopeType.For) {
61
+ for (let i = 0; i < forScopes; i++) {
59
62
  scope.pop(node.getLastToken().getEnd());
60
63
  }
61
64
  if ((targetType === null || targetType === void 0 ? void 0 : targetType.isGeneric()) && type) {
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.93.16";
66
+ return "2.93.17";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -222,6 +222,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
222
222
  if (found) {
223
223
  return found;
224
224
  }
225
+ found = this.downportCorrespondingSimple(high, lowFile);
226
+ if (found) {
227
+ return found;
228
+ }
225
229
  found = this.downportRef(low, high, lowFile, highSyntax);
226
230
  if (found) {
227
231
  return found;
@@ -873,6 +877,28 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
873
877
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
874
878
  return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, call function parameter", this.getMetadata().key, this.conf.severity, fix);
875
879
  }
880
+ downportCorrespondingSimple(high, lowFile) {
881
+ var _a;
882
+ if (!(high.get() instanceof Statements.Move)
883
+ || high.getChildren().length !== 4
884
+ || high.getChildren()[2].getFirstToken().getStr().toUpperCase() !== "CORRESPONDING") {
885
+ return undefined;
886
+ }
887
+ const target = high.findDirectExpression(Expressions.Target);
888
+ if (target === undefined) {
889
+ console.dir("sdf1");
890
+ return undefined;
891
+ }
892
+ const sourceRef = (_a = high.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.findFirstExpression(Expressions.CorrespondingBody);
893
+ if (sourceRef === undefined || sourceRef.getChildren().length !== 1) {
894
+ return;
895
+ }
896
+ const code = `MOVE-CORRESPONDING ${sourceRef.concatTokens()} TO ${target.concatTokens()}`;
897
+ const start = high.getFirstToken().getStart();
898
+ const end = high.getLastToken().getStart();
899
+ const fix = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, code);
900
+ return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, simple CORRESPONDING move", this.getMetadata().key, this.conf.severity, fix);
901
+ }
876
902
  downportRefSimple(high, lowFile) {
877
903
  var _a;
878
904
  if (!(high.get() instanceof Statements.Move)
@@ -895,7 +921,7 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
895
921
  return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, simple REF move", this.getMetadata().key, this.conf.severity, fix);
896
922
  }
897
923
  downportLoopGroup(high, lowFile, highSyntax, highFile) {
898
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
924
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
899
925
  if (!(high.get() instanceof Statements.Loop)) {
900
926
  return undefined;
901
927
  }
@@ -907,6 +933,7 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
907
933
  const loopSourceName = ((_b = high.findFirstExpression(Expressions.SimpleSource2)) === null || _b === void 0 ? void 0 : _b.concatTokens()) || "nameNotFound";
908
934
  const loopTargetName = ((_c = high.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "nameNotFound";
909
935
  const groupTarget = ((_d = group.findDirectExpression(Expressions.LoopGroupByTarget)) === null || _d === void 0 ? void 0 : _d.concatTokens()) || "";
936
+ const isReference = (_e = high.findFirstExpression(Expressions.LoopTarget)) === null || _e === void 0 ? void 0 : _e.concatTokens().toUpperCase().startsWith("REFERENCE INTO ");
910
937
  let loopSourceRowType = "typeNotFound";
911
938
  const spag = highSyntax.spaghetti.lookupPosition(high.getFirstToken().getStart(), lowFile.getFilename());
912
939
  if (spag !== undefined) {
@@ -921,8 +948,8 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
921
948
  let groupCountName = undefined;
922
949
  for (const c of group.findAllExpressions(Expressions.LoopGroupByComponent)) {
923
950
  const name = c.findFirstExpression(Expressions.ComponentName);
924
- let type = ((_e = c.findFirstExpression(Expressions.Source)) === null || _e === void 0 ? void 0 : _e.concatTokens()) || "todo";
925
- if ((_f = c.concatTokens()) === null || _f === void 0 ? void 0 : _f.toUpperCase().endsWith(" = GROUP SIZE")) {
951
+ let type = ((_f = c.findFirstExpression(Expressions.Source)) === null || _f === void 0 ? void 0 : _f.concatTokens()) || "todo";
952
+ if ((_g = c.concatTokens()) === null || _g === void 0 ? void 0 : _g.toUpperCase().endsWith(" = GROUP SIZE")) {
926
953
  type = "i";
927
954
  groupCountName = name === null || name === void 0 ? void 0 : name.concatTokens();
928
955
  }
@@ -939,29 +966,31 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
939
966
  END OF ${groupTargetName}type.
940
967
  DATA ${groupTargetName}tab TYPE STANDARD TABLE OF ${groupTargetName}type WITH DEFAULT KEY.
941
968
  DATA ${uniqueName} LIKE LINE OF ${groupTargetName}tab.
942
- LOOP AT ${loopSourceName} ${(_g = high.findFirstExpression(Expressions.LoopTarget)) === null || _g === void 0 ? void 0 : _g.concatTokens()}.
969
+ LOOP AT ${loopSourceName} ${(_h = high.findFirstExpression(Expressions.LoopTarget)) === null || _h === void 0 ? void 0 : _h.concatTokens()}.
943
970
  READ TABLE ${groupTargetName}tab ASSIGNING FIELD-SYMBOL(<${uniqueFS}>) WITH KEY ${condition}.
944
- IF sy-subrc = 0.
945
- <${uniqueFS}>-${groupCountName} = <${uniqueFS}>-${groupCountName} + 1.
946
- INSERT ${loopTargetName}->* INTO TABLE <${uniqueFS}>-items.
971
+ IF sy-subrc = 0.\n`;
972
+ if (groupCountName !== undefined) {
973
+ code += ` <${uniqueFS}>-${groupCountName} = <${uniqueFS}>-${groupCountName} + 1.\n`;
974
+ }
975
+ code += ` INSERT ${loopTargetName}${isReference ? "->*" : ""} INTO TABLE <${uniqueFS}>-items.
947
976
  ELSE.\n`;
948
977
  code += ` CLEAR ${uniqueName}.\n`;
949
978
  for (const c of group.findAllExpressions(Expressions.LoopGroupByComponent)) {
950
979
  code += ` ${uniqueName}-${c.concatTokens().replace("GROUP SIZE", "1")}.\n`;
951
980
  }
952
- code += ` INSERT ${loopTargetName}->* INTO TABLE ${uniqueName}-items.\n`;
981
+ code += ` INSERT ${loopTargetName}${isReference ? "->*" : ""} INTO TABLE ${uniqueName}-items.\n`;
953
982
  code += ` INSERT ${uniqueName} INTO TABLE ${groupTargetName}tab.\n`;
954
983
  code += `ENDIF.
955
984
  ENDLOOP.
956
985
  LOOP AT ${groupTargetName}tab ${groupTarget}.`;
957
986
  let fix = edit_helper_1.EditHelper.replaceRange(lowFile, high.getFirstToken().getStart(), high.getLastToken().getEnd(), code);
958
- for (const l of ((_h = highFile.getStructure()) === null || _h === void 0 ? void 0 : _h.findAllStructures(Structures.Loop)) || []) {
987
+ for (const l of ((_j = highFile.getStructure()) === null || _j === void 0 ? void 0 : _j.findAllStructures(Structures.Loop)) || []) {
959
988
  // make sure to find the correct/current loop statement
960
989
  if (l.findDirectStatement(Statements.Loop) !== high) {
961
990
  continue;
962
991
  }
963
992
  for (const loop of l.findAllStatements(Statements.Loop)) {
964
- if ((_j = loop.concatTokens()) === null || _j === void 0 ? void 0 : _j.toUpperCase().startsWith("LOOP AT GROUP ")) {
993
+ if ((_k = loop.concatTokens()) === null || _k === void 0 ? void 0 : _k.toUpperCase().startsWith("LOOP AT GROUP ")) {
965
994
  const subLoopSource = loop.findFirstExpression(Expressions.SimpleSource2);
966
995
  if (subLoopSource === undefined) {
967
996
  continue;
@@ -1362,8 +1391,22 @@ ${indentation} output = ${topTarget}.`;
1362
1391
  from = from ? " FROM " + from : "";
1363
1392
  let to = (_j = forLoop.findExpressionAfterToken("TO")) === null || _j === void 0 ? void 0 : _j.concatTokens();
1364
1393
  to = to ? " TO " + to : "";
1394
+ let gby = "";
1395
+ for (const lg of forLoop.findDirectExpressions(Expressions.LoopGroupByComponent)) {
1396
+ if (gby !== "") {
1397
+ gby += " ";
1398
+ }
1399
+ gby = lg.concatTokens();
1400
+ }
1401
+ if (gby !== "") {
1402
+ gby = " GROUP BY ( " + gby + " )";
1403
+ }
1404
+ const groups = forLoop.findExpressionAfterToken("GROUPS");
1405
+ if (groups) {
1406
+ gby += " INTO DATA(" + groups.concatTokens() + ")";
1407
+ }
1365
1408
  // todo, also backup sy-index / sy-tabix here?
1366
- body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField})${from}${to}${cond}.\n`;
1409
+ body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField})${from}${to}${cond}${gby}.\n`;
1367
1410
  if (indexInto) {
1368
1411
  body += indentation + " DATA(" + indexInto + ") = sy-tabix.\n";
1369
1412
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.93.16",
3
+ "version": "2.93.17",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",