@abaplint/core 2.91.11 → 2.91.14

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.
@@ -105,7 +105,8 @@ class StatementParser {
105
105
  for (let statement of wa.statements) {
106
106
  // dont use CALL METHOD, when executing lazy, it easily gives a Move for the last statment if lazy logic is evaluated
107
107
  if (statement.get() instanceof _statement_1.Unknown
108
- && statement.concatTokens().toUpperCase().startsWith("CALL METHOD ") === false) {
108
+ && statement.concatTokens().toUpperCase().startsWith("CALL METHOD ") === false
109
+ && statement.concatTokens().toUpperCase().startsWith("CALL FUNCTION ") === false) {
109
110
  for (const { first, second } of this.buildSplits(statement.getTokens())) {
110
111
  if (second.length === 1) {
111
112
  continue; // probably punctuation
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.91.11";
71
+ return "2.91.14";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -188,7 +188,7 @@ Only one transformation is applied to a statement at a time, so multiple steps m
188
188
  if (found) {
189
189
  return found;
190
190
  }
191
- found = this.stringTemplateAlpha(high, lowFile);
191
+ found = this.stringTemplateAlpha(high, lowFile, highSyntax);
192
192
  if (found) {
193
193
  return found;
194
194
  }
@@ -200,6 +200,18 @@ Only one transformation is applied to a statement at a time, so multiple steps m
200
200
  if (found) {
201
201
  return found;
202
202
  }
203
+ found = this.downportRefSimple(high, lowFile);
204
+ if (found) {
205
+ return found;
206
+ }
207
+ found = this.downportRef(high, lowFile, highSyntax);
208
+ if (found) {
209
+ return found;
210
+ }
211
+ found = this.callFunctionParameterSimple(high, lowFile, highSyntax);
212
+ if (found) {
213
+ return found;
214
+ }
203
215
  found = this.moveWithTableTarget(low, high, lowFile, highSyntax);
204
216
  if (found) {
205
217
  return found;
@@ -272,6 +284,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
272
284
  if (found) {
273
285
  return found;
274
286
  }
287
+ found = this.getReference(high, lowFile, highSyntax);
288
+ if (found) {
289
+ return found;
290
+ }
275
291
  found = this.replaceContains(high, lowFile, highSyntax);
276
292
  if (found) {
277
293
  return found;
@@ -779,6 +795,72 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
779
795
  }
780
796
  return undefined;
781
797
  }
798
+ callFunctionParameterSimple(high, lowFile, highSyntax) {
799
+ if (!(high.get() instanceof Statements.CallFunction)) {
800
+ return undefined;
801
+ }
802
+ let found = undefined;
803
+ for (const p of high.findAllExpressions(Expressions.FunctionExportingParameter)) {
804
+ found = p.findDirectExpression(Expressions.Source);
805
+ if (found && (found.findDirectExpression(Expressions.FieldChain)
806
+ || found.findDirectExpression(Expressions.Constant)
807
+ || found.findDirectExpression(Expressions.TextElement))) {
808
+ // its actually simple, ok
809
+ found = undefined;
810
+ }
811
+ else if (found !== undefined) {
812
+ break;
813
+ }
814
+ }
815
+ if (found === undefined) {
816
+ return undefined;
817
+ }
818
+ const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
819
+ const code = `DATA(${uniqueName}) = ${found.concatTokens()}.\n`;
820
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getFirstToken().getStart(), code);
821
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, found.getFirstToken().getStart(), found.getLastToken().getEnd(), uniqueName);
822
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
823
+ return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, call function parameter", this.getMetadata().key, this.conf.severity, fix);
824
+ }
825
+ downportRefSimple(high, lowFile) {
826
+ var _a;
827
+ if (!(high.get() instanceof Statements.Move)
828
+ || high.getChildren().length !== 4
829
+ || high.getChildren()[2].getFirstToken().getStr().toUpperCase() !== "REF") {
830
+ return undefined;
831
+ }
832
+ const target = high.findDirectExpression(Expressions.Target);
833
+ if (target === undefined) {
834
+ return undefined;
835
+ }
836
+ const sourceRef = (_a = high.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Source);
837
+ if (sourceRef === undefined || sourceRef.getChildren().length !== 1) {
838
+ return;
839
+ }
840
+ const code = `GET REFERENCE OF ${sourceRef.concatTokens()} INTO ${target.concatTokens()}`;
841
+ const start = high.getFirstToken().getStart();
842
+ const end = high.getLastToken().getStart();
843
+ const fix = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, code);
844
+ return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, simple REF move", this.getMetadata().key, this.conf.severity, fix);
845
+ }
846
+ downportRef(high, lowFile, highSyntax) {
847
+ let found = undefined;
848
+ for (const s of high.findAllExpressionsRecursive(Expressions.Source)) {
849
+ if (s.getFirstToken().getStr().toUpperCase() === "REF"
850
+ && s.findDirectExpression(Expressions.TypeNameOrInfer)) {
851
+ found = s;
852
+ }
853
+ }
854
+ if (found === undefined) {
855
+ return undefined;
856
+ }
857
+ const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
858
+ const code = `DATA(${uniqueName}) = ${found.concatTokens()}.\n`;
859
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getFirstToken().getStart(), code);
860
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, found.getFirstToken().getStart(), found.getLastToken().getEnd(), uniqueName);
861
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
862
+ return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Downport, REF", this.getMetadata().key, this.conf.severity, fix);
863
+ }
782
864
  moveWithSimpleValue(high, lowFile) {
783
865
  if (!(high.get() instanceof Statements.Move)
784
866
  || high.getChildren().length !== 4) {
@@ -927,7 +1009,7 @@ ${indentation}${uniqueName}`;
927
1009
  return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Expand operator", this.getMetadata().key, this.conf.severity, fix);
928
1010
  }
929
1011
  // must be very simple string templates, like "|{ ls_line-no ALPHA = IN }|"
930
- stringTemplateAlpha(node, lowFile) {
1012
+ stringTemplateAlpha(node, lowFile, highSyntax) {
931
1013
  var _a, _b, _c;
932
1014
  if (!(node.get() instanceof Statements.Move)) {
933
1015
  return undefined;
@@ -936,8 +1018,13 @@ ${indentation}${uniqueName}`;
936
1018
  if (topSource === undefined || topSource.getChildren().length !== 1) {
937
1019
  return undefined;
938
1020
  }
939
- const child = topSource.getFirstChild();
1021
+ let top = true;
1022
+ let child = topSource.getFirstChild();
940
1023
  if (!(child.get() instanceof Expressions.StringTemplate)) {
1024
+ child = child.findFirstExpression(Expressions.StringTemplate);
1025
+ top = false;
1026
+ }
1027
+ if (child === undefined || !(child.get() instanceof Expressions.StringTemplate)) {
941
1028
  return undefined;
942
1029
  }
943
1030
  const templateTokens = child.getChildren();
@@ -962,13 +1049,28 @@ ${indentation}${uniqueName}`;
962
1049
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
963
1050
  const source = (_b = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();
964
1051
  const topTarget = (_c = node.findDirectExpression(Expressions.Target)) === null || _c === void 0 ? void 0 : _c.concatTokens();
965
- const code = `CALL FUNCTION '${functionName}'
1052
+ const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
1053
+ if (top === false) {
1054
+ const code = `DATA ${uniqueName} TYPE string.
1055
+ ${indentation}CALL FUNCTION '${functionName}'
1056
+ ${indentation} EXPORTING
1057
+ ${indentation} input = ${source}
1058
+ ${indentation} IMPORTING
1059
+ ${indentation} output = ${uniqueName}.\n`;
1060
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
1061
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, child.getFirstToken().getStart(), child.getLastToken().getEnd(), uniqueName);
1062
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
1063
+ return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Downport ALPHA", this.getMetadata().key, this.conf.severity, fix);
1064
+ }
1065
+ else {
1066
+ const code = `CALL FUNCTION '${functionName}'
966
1067
  ${indentation} EXPORTING
967
1068
  ${indentation} input = ${source}
968
1069
  ${indentation} IMPORTING
969
1070
  ${indentation} output = ${topTarget}.`;
970
- const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);
971
- return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Downport ALPHA", this.getMetadata().key, this.conf.severity, fix);
1071
+ const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);
1072
+ return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Downport ALPHA", this.getMetadata().key, this.conf.severity, fix);
1073
+ }
972
1074
  }
973
1075
  outlineLoopInput(node, lowFile, highSyntax) {
974
1076
  if (!(node.get() instanceof Statements.Loop)) {
@@ -1643,6 +1745,26 @@ ${indentation} output = ${topTarget}.`;
1643
1745
  }
1644
1746
  return undefined;
1645
1747
  }
1748
+ getReference(node, lowFile, _highSyntax) {
1749
+ var _a, _b, _c;
1750
+ if (!(node.get() instanceof Statements.GetReference)) {
1751
+ return undefined;
1752
+ }
1753
+ const inline = (_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.InlineData);
1754
+ if (inline === undefined) {
1755
+ return undefined;
1756
+ }
1757
+ const targetName = (_b = inline.findDirectExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
1758
+ const sourceName = (_c = node.findDirectExpression(Expressions.Source)) === null || _c === void 0 ? void 0 : _c.concatTokens();
1759
+ if (targetName === undefined || sourceName === undefined) {
1760
+ return undefined;
1761
+ }
1762
+ const code = `DATA ${targetName} LIKE REF TO ${sourceName}.\n`;
1763
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
1764
+ const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inline.getFirstToken().getStart(), inline.getLastToken().getEnd(), targetName);
1765
+ const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
1766
+ return issue_1.Issue.atToken(lowFile, inline.getFirstToken(), "Downport, outline DATA ref", this.getMetadata().key, this.conf.severity, fix);
1767
+ }
1646
1768
  replaceContains(node, lowFile, highSyntax) {
1647
1769
  const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
1648
1770
  // only downport if its an single method call condition
@@ -1734,8 +1856,10 @@ ${indentation} output = ${topTarget}.`;
1734
1856
  const target = node.findDirectExpression(Expressions.Target);
1735
1857
  const found = source === null || source === void 0 ? void 0 : source.findFirstExpression(Expressions.NewObject);
1736
1858
  // must be at top level of the source for quickfix to work(todo: handle more scenarios)
1737
- // todo, assumption: the target is not an inline definition
1738
- if (target && found && source.concatTokens() === found.concatTokens()) {
1859
+ if (target
1860
+ && found
1861
+ && source.concatTokens() === found.concatTokens()
1862
+ && target.findDirectExpression(Expressions.InlineData) === undefined) {
1739
1863
  const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
1740
1864
  if (abap !== undefined) {
1741
1865
  fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), abap);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.91.11",
3
+ "version": "2.91.14",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "homepage": "https://abaplint.org",
47
47
  "devDependencies": {
48
- "@microsoft/api-extractor": "^7.28.4",
48
+ "@microsoft/api-extractor": "^7.28.6",
49
49
  "@types/chai": "^4.3.1",
50
50
  "@types/mocha": "^9.1.1",
51
51
  "@types/node": "^18.0.6",