@abaplint/transpiler-cli 2.8.25 → 2.8.27

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 +366 -56
  2. package/package.json +4 -4
package/build/bundle.js CHANGED
@@ -1921,7 +1921,7 @@ class Star {
1921
1921
  return this.sta.getUsing();
1922
1922
  }
1923
1923
  run(r) {
1924
- const result = r;
1924
+ let result = r;
1925
1925
  try {
1926
1926
  let res = r;
1927
1927
  let input = [];
@@ -1931,7 +1931,13 @@ class Star {
1931
1931
  if (res.length === 0) {
1932
1932
  break;
1933
1933
  }
1934
- result.push(...res);
1934
+ if (res.length > 1000) {
1935
+ // avoid stack overflow
1936
+ result = result.concat(res);
1937
+ }
1938
+ else {
1939
+ result.push(...res);
1940
+ }
1935
1941
  }
1936
1942
  }
1937
1943
  catch (err) {
@@ -2064,7 +2070,7 @@ class Sequence {
2064
2070
  return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
2065
2071
  }
2066
2072
  run(r) {
2067
- const result = [];
2073
+ let result = [];
2068
2074
  for (const input of r) {
2069
2075
  let temp = [input];
2070
2076
  let match = true;
@@ -2076,7 +2082,13 @@ class Sequence {
2076
2082
  }
2077
2083
  }
2078
2084
  if (match === true) {
2079
- result.push(...temp);
2085
+ if (temp.length > 1000) {
2086
+ // avoid stack overflow
2087
+ result = result.concat(temp);
2088
+ }
2089
+ else {
2090
+ result.push(...temp);
2091
+ }
2080
2092
  }
2081
2093
  }
2082
2094
  return result;
@@ -2577,17 +2589,23 @@ class Macros {
2577
2589
  constructor(globalMacros) {
2578
2590
  this.macros = {};
2579
2591
  for (const m of globalMacros) {
2580
- this.macros[m.toUpperCase()] = [];
2592
+ this.macros[m.toUpperCase()] = {
2593
+ statements: [],
2594
+ filename: undefined,
2595
+ };
2581
2596
  }
2582
2597
  }
2583
- addMacro(name, contents) {
2598
+ addMacro(name, contents, filename) {
2584
2599
  if (this.isMacro(name)) {
2585
2600
  return;
2586
2601
  }
2587
- this.macros[name.toUpperCase()] = contents;
2602
+ this.macros[name.toUpperCase()] = {
2603
+ statements: contents,
2604
+ filename: filename,
2605
+ };
2588
2606
  }
2589
2607
  getContents(name) {
2590
- return this.macros[name.toUpperCase()];
2608
+ return this.macros[name.toUpperCase()].statements;
2591
2609
  }
2592
2610
  listMacroNames() {
2593
2611
  return Object.keys(this.macros);
@@ -2598,6 +2616,9 @@ class Macros {
2598
2616
  }
2599
2617
  return false;
2600
2618
  }
2619
+ getMacroFilename(name) {
2620
+ return this.macros[name.toUpperCase()].filename;
2621
+ }
2601
2622
  }
2602
2623
  class ExpandMacros {
2603
2624
  // "reg" must be supplied if there are cross object macros via INCLUDE
@@ -2607,35 +2628,42 @@ class ExpandMacros {
2607
2628
  this.globalMacros = globalMacros;
2608
2629
  this.reg = reg;
2609
2630
  }
2610
- find(statements) {
2611
- var _a, _b;
2612
- let name = undefined;
2631
+ find(statements, file, clear = true) {
2632
+ var _a, _b, _c;
2633
+ let nameToken = undefined;
2634
+ let start = undefined;
2613
2635
  let contents = [];
2636
+ const macroReferences = (_a = this.reg) === null || _a === void 0 ? void 0 : _a.getMacroReferences();
2637
+ if (clear) {
2638
+ macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.clear(file.getFilename());
2639
+ }
2614
2640
  for (let i = 0; i < statements.length; i++) {
2615
2641
  const statement = statements[i];
2616
2642
  const type = statement.get();
2617
2643
  if (type instanceof Statements.Define) {
2618
2644
  // todo, will this break if first token is a pragma?
2619
- name = statement.getTokens()[1].getStr();
2645
+ nameToken = statement.getTokens()[1];
2646
+ start = statement.getFirstToken().getStart();
2620
2647
  contents = [];
2621
2648
  }
2622
2649
  else if (type instanceof Statements.Include) {
2623
- const includeName = (_a = statement.findDirectExpression(Expressions.IncludeName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
2650
+ const includeName = (_b = statement.findDirectExpression(Expressions.IncludeName)) === null || _b === void 0 ? void 0 : _b.concatTokens();
2624
2651
  // todo, this does not take function module includes into account
2625
- const prog = (_b = this.reg) === null || _b === void 0 ? void 0 : _b.getObject("PROG", includeName);
2652
+ const prog = (_c = this.reg) === null || _c === void 0 ? void 0 : _c.getObject("PROG", includeName);
2626
2653
  if (prog) {
2627
2654
  prog.parse(this.version, this.globalMacros, this.reg);
2628
- const main = prog.getMainABAPFile();
2629
- if (main) {
2655
+ const includeMainFile = prog.getMainABAPFile();
2656
+ if (includeMainFile) {
2630
2657
  // slow, this copies everything,
2631
- this.find([...main.getStatements()]);
2658
+ this.find([...includeMainFile.getStatements()], includeMainFile, false);
2632
2659
  }
2633
2660
  }
2634
2661
  }
2635
- else if (name) {
2662
+ else if (nameToken) {
2636
2663
  if (type instanceof Statements.EndOfDefinition) {
2637
- this.macros.addMacro(name, contents);
2638
- name = undefined;
2664
+ this.macros.addMacro(nameToken.getStr(), contents, file.getFilename());
2665
+ macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.addDefinition({ filename: file.getFilename(), token: nameToken }, start, statement.getLastToken().getEnd());
2666
+ nameToken = undefined;
2639
2667
  }
2640
2668
  else if (!(type instanceof _statement_1.Comment)) {
2641
2669
  statements[i] = new statement_node_1.StatementNode(new _statement_1.MacroContent()).setChildren(this.tokensToNodes(statement.getTokens()));
@@ -2644,17 +2672,26 @@ class ExpandMacros {
2644
2672
  }
2645
2673
  }
2646
2674
  }
2647
- handleMacros(statements) {
2675
+ handleMacros(statements, file) {
2676
+ var _a;
2648
2677
  const result = [];
2649
2678
  let containsUnknown = false;
2679
+ const macroReferences = (_a = this.reg) === null || _a === void 0 ? void 0 : _a.getMacroReferences();
2650
2680
  for (const statement of statements) {
2651
2681
  const type = statement.get();
2652
2682
  if (type instanceof _statement_1.Unknown || type instanceof _statement_1.MacroCall) {
2653
2683
  const macroName = this.findName(statement.getTokens());
2654
2684
  if (macroName && this.macros.isMacro(macroName)) {
2685
+ const filename = this.macros.getMacroFilename(macroName);
2686
+ if (filename) {
2687
+ macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.addReference({
2688
+ filename: filename,
2689
+ token: statement.getFirstToken(),
2690
+ });
2691
+ }
2655
2692
  result.push(new statement_node_1.StatementNode(new _statement_1.MacroCall(), statement.getColon()).setChildren(this.tokensToNodes(statement.getTokens())));
2656
2693
  const expanded = this.expandContents(macroName, statement);
2657
- const handled = this.handleMacros(expanded);
2694
+ const handled = this.handleMacros(expanded, file);
2658
2695
  for (const e of handled.statements) {
2659
2696
  result.push(e);
2660
2697
  }
@@ -3548,9 +3585,9 @@ const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/co
3548
3585
  const _1 = __webpack_require__(/*! . */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
3549
3586
  class CondBody extends combi_1.Expression {
3550
3587
  getRunnable() {
3551
- const when = (0, combi_1.seq)("WHEN", (0, combi_1.alt)(_1.Cond, _1.Source), "THEN", (0, combi_1.alt)(_1.Source, _1.Throw));
3552
- const elsee = (0, combi_1.seq)("ELSE", (0, combi_1.alt)(_1.Source, _1.Throw));
3553
- return (0, combi_1.seq)((0, combi_1.opt)(_1.Let), (0, combi_1.plus)(when), (0, combi_1.opt)(elsee));
3588
+ const when = (0, combi_1.seq)("WHEN", (0, combi_1.altPrio)(_1.Cond, _1.Source), "THEN", (0, combi_1.altPrio)(_1.Throw, _1.Source));
3589
+ const elsee = (0, combi_1.seq)("ELSE", (0, combi_1.altPrio)(_1.Throw, _1.Source));
3590
+ return (0, combi_1.seq)((0, combi_1.optPrio)(_1.Let), (0, combi_1.plusPrio)(when), (0, combi_1.optPrio)(elsee));
3554
3591
  }
3555
3592
  }
3556
3593
  exports.CondBody = CondBody;
@@ -8510,10 +8547,10 @@ class StatementParser {
8510
8547
  for (const w of wa) {
8511
8548
  this.process(w);
8512
8549
  this.categorize(w);
8513
- macros.find(w.statements);
8550
+ macros.find(w.statements, w.file);
8514
8551
  }
8515
8552
  for (const w of wa) {
8516
- const res = macros.handleMacros(w.statements);
8553
+ const res = macros.handleMacros(w.statements, w.file);
8517
8554
  w.statements = res.statements;
8518
8555
  if (res.containsUnknown === true) {
8519
8556
  this.lazyUnknown(w);
@@ -16900,7 +16937,7 @@ class Sequence {
16900
16937
  }
16901
16938
  run(statements, parent) {
16902
16939
  let inn = statements;
16903
- const out = [];
16940
+ let out = [];
16904
16941
  for (const i of this.list) {
16905
16942
  const match = i.run(inn, parent);
16906
16943
  if (match.error) {
@@ -16912,7 +16949,14 @@ class Sequence {
16912
16949
  errorMatched: out.length,
16913
16950
  };
16914
16951
  }
16915
- out.push(...match.matched);
16952
+ if (match.matched.length < 100) {
16953
+ out.push(...match.matched);
16954
+ }
16955
+ else {
16956
+ // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
16957
+ // when the number of matched elements is very large
16958
+ out = out.concat(match.matched);
16959
+ }
16916
16960
  inn = match.unmatched;
16917
16961
  }
16918
16962
  return {
@@ -17044,7 +17088,7 @@ class Star {
17044
17088
  }
17045
17089
  run(statements, parent) {
17046
17090
  let inn = statements;
17047
- const out = [];
17091
+ let out = [];
17048
17092
  while (true) {
17049
17093
  if (inn.length === 0) {
17050
17094
  return {
@@ -17076,7 +17120,14 @@ class Star {
17076
17120
  };
17077
17121
  }
17078
17122
  }
17079
- out.push(...match.matched);
17123
+ if (match.matched.length < 100) {
17124
+ out.push(...match.matched);
17125
+ }
17126
+ else {
17127
+ // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
17128
+ // when the number of matched elements is very large
17129
+ out = out.concat(match.matched);
17130
+ }
17080
17131
  inn = match.unmatched;
17081
17132
  }
17082
17133
  }
@@ -40566,6 +40617,7 @@ const _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ "./n
40566
40617
  const _builtin_1 = __webpack_require__(/*! ../abap/5_syntax/_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
40567
40618
  const _scope_type_1 = __webpack_require__(/*! ../abap/5_syntax/_scope_type */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_scope_type.js");
40568
40619
  const types_1 = __webpack_require__(/*! ../abap/types */ "./node_modules/@abaplint/core/build/src/abap/types/index.js");
40620
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
40569
40621
  class LSPLookup {
40570
40622
  static lookup(cursor, reg, obj) {
40571
40623
  var _a, _b;
@@ -40682,6 +40734,18 @@ class LSPLookup {
40682
40734
  scope: bottomScope,
40683
40735
  };
40684
40736
  }
40737
+ if (cursor.snode.get() instanceof _statement_1.MacroCall) {
40738
+ const macroDefinition = reg.getMacroReferences().findDefinitionByUsage(cursor.identifier.getFilename(), cursor.snode.getFirstToken());
40739
+ if (macroDefinition) {
40740
+ return {
40741
+ hover: "Macro Call",
40742
+ definition: {
40743
+ uri: macroDefinition === null || macroDefinition === void 0 ? void 0 : macroDefinition.filename,
40744
+ range: _lsp_utils_1.LSPUtils.tokenToRange(macroDefinition.token),
40745
+ },
40746
+ };
40747
+ }
40748
+ }
40685
40749
  if (hoverValue !== "") {
40686
40750
  return { hover: hoverValue, scope: bottomScope };
40687
40751
  }
@@ -41058,6 +41122,9 @@ class CodeActions {
41058
41122
  const diagnostics = [];
41059
41123
  const fixes = [];
41060
41124
  for (const i of issues) {
41125
+ if (i.getKey() !== key) {
41126
+ continue;
41127
+ }
41061
41128
  const fix = i.getDefaultFix();
41062
41129
  if (fix === undefined) {
41063
41130
  continue;
@@ -41746,11 +41813,13 @@ exports.Highlight = Highlight;
41746
41813
 
41747
41814
  Object.defineProperty(exports, "__esModule", ({ value: true }));
41748
41815
  exports.Hover = void 0;
41816
+ const Tokens = __webpack_require__(/*! ../abap/1_lexer/tokens */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js");
41817
+ const Statements = __webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
41749
41818
  const LServer = __webpack_require__(/*! vscode-languageserver-types */ "./node_modules/vscode-languageserver-types/lib/umd/main.js");
41750
41819
  const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
41751
41820
  const _lsp_utils_1 = __webpack_require__(/*! ./_lsp_utils */ "./node_modules/@abaplint/core/build/src/lsp/_lsp_utils.js");
41752
- const Tokens = __webpack_require__(/*! ../abap/1_lexer/tokens */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js");
41753
41821
  const _lookup_1 = __webpack_require__(/*! ./_lookup */ "./node_modules/@abaplint/core/build/src/lsp/_lookup.js");
41822
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
41754
41823
  class Hover {
41755
41824
  constructor(reg) {
41756
41825
  this.reg = reg;
@@ -41774,6 +41843,12 @@ class Hover {
41774
41843
  || found.token instanceof Tokens.StringTemplateMiddle) {
41775
41844
  return { kind: LServer.MarkupKind.Markdown, value: "String Template" };
41776
41845
  }
41846
+ else if (found.snode.get() instanceof _statement_1.MacroCall) {
41847
+ return { kind: LServer.MarkupKind.Markdown, value: "Macro Call" };
41848
+ }
41849
+ else if (found.snode.get() instanceof Statements.Define && found.stack.length === 2) {
41850
+ return { kind: LServer.MarkupKind.Markdown, value: "Macro Name" };
41851
+ }
41777
41852
  else if (found.token instanceof Tokens.Comment) {
41778
41853
  let type = "Comment";
41779
41854
  if (found.token.getStr().startsWith(`"!`)) {
@@ -42142,6 +42217,7 @@ class References {
42142
42217
  const locs = this.search(lookup.definitionId, lookup.scope);
42143
42218
  return locs.map(_lsp_utils_1.LSPUtils.identiferToLocation);
42144
42219
  }
42220
+ ////////////////////////////////////////////
42145
42221
  // todo, cleanup this mehtod, some of the method parameters are not used anymore?
42146
42222
  search(identifier, node, exitAfterFound = false, removeDuplicates = true) {
42147
42223
  let ret = [];
@@ -42169,7 +42245,6 @@ class References {
42169
42245
  return ret;
42170
42246
  }
42171
42247
  }
42172
- ////////////////////////////////////////////
42173
42248
  removeDuplicates(arr) {
42174
42249
  const values = {};
42175
42250
  return arr.filter(item => {
@@ -42595,6 +42670,87 @@ exports.Symbols = Symbols;
42595
42670
 
42596
42671
  /***/ }),
42597
42672
 
42673
+ /***/ "./node_modules/@abaplint/core/build/src/macro_references.js":
42674
+ /*!*******************************************************************!*\
42675
+ !*** ./node_modules/@abaplint/core/build/src/macro_references.js ***!
42676
+ \*******************************************************************/
42677
+ /***/ ((__unused_webpack_module, exports) => {
42678
+
42679
+ "use strict";
42680
+
42681
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
42682
+ exports.MacroReferences = void 0;
42683
+ class MacroReferences {
42684
+ constructor() {
42685
+ this.definitions = {};
42686
+ this.references = {};
42687
+ }
42688
+ addDefinition(ref, start, end) {
42689
+ if (this.definitions[ref.filename] === undefined) {
42690
+ this.definitions[ref.filename] = [];
42691
+ }
42692
+ else if (this.definitions[ref.filename].find((d) => d.token.getStart().equals(ref.token.getStart()))) {
42693
+ return;
42694
+ }
42695
+ this.definitions[ref.filename].push({ token: ref.token, start, end });
42696
+ }
42697
+ getDefinitionRange(filename, token) {
42698
+ for (const d of this.definitions[filename] || []) {
42699
+ if (d.token.getStart().equals(token.getStart())) {
42700
+ return { start: d.start, end: d.end };
42701
+ }
42702
+ }
42703
+ return undefined;
42704
+ }
42705
+ addReference(ref) {
42706
+ if (this.references[ref.filename] === undefined) {
42707
+ this.references[ref.filename] = [];
42708
+ }
42709
+ this.references[ref.filename].push(ref);
42710
+ }
42711
+ listDefinitionsByFile(filename) {
42712
+ const ret = [];
42713
+ for (const d of this.definitions[filename] || []) {
42714
+ ret.push(d.token);
42715
+ }
42716
+ return ret;
42717
+ }
42718
+ listUsagesbyMacro(filename, token) {
42719
+ const ret = [];
42720
+ const tokenStr = token.getStr().toUpperCase();
42721
+ for (const ref of this.references[filename] || []) {
42722
+ if (ref.token.getStr().toUpperCase() === tokenStr) {
42723
+ ret.push(ref);
42724
+ }
42725
+ }
42726
+ return ret;
42727
+ }
42728
+ clear(filename) {
42729
+ delete this.definitions[filename];
42730
+ delete this.references[filename];
42731
+ }
42732
+ findDefinitionByUsage(filename, token) {
42733
+ const tokenStr = token.getStr().toUpperCase();
42734
+ for (const ref of this.references[filename] || []) {
42735
+ if (ref.token.getStart().equals(token.getStart())) {
42736
+ for (const d of this.definitions[ref.filename] || []) {
42737
+ if (d.token.getStr().toUpperCase() === tokenStr) {
42738
+ return {
42739
+ filename: ref.filename,
42740
+ token: d.token,
42741
+ };
42742
+ }
42743
+ }
42744
+ }
42745
+ }
42746
+ return undefined;
42747
+ }
42748
+ }
42749
+ exports.MacroReferences = MacroReferences;
42750
+ //# sourceMappingURL=macro_references.js.map
42751
+
42752
+ /***/ }),
42753
+
42598
42754
  /***/ "./node_modules/@abaplint/core/build/src/msag_references.js":
42599
42755
  /*!******************************************************************!*\
42600
42756
  !*** ./node_modules/@abaplint/core/build/src/msag_references.js ***!
@@ -49707,6 +49863,10 @@ const Types = __webpack_require__(/*! ../abap/types/basic */ "./node_modules/@ab
49707
49863
  const _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ "./node_modules/@abaplint/core/build/src/objects/_abstract_object.js");
49708
49864
  const xml_utils_1 = __webpack_require__(/*! ../xml_utils */ "./node_modules/@abaplint/core/build/src/xml_utils.js");
49709
49865
  const ddic_1 = __webpack_require__(/*! ../ddic */ "./node_modules/@abaplint/core/build/src/ddic.js");
49866
+ var ViewClass;
49867
+ (function (ViewClass) {
49868
+ ViewClass["ExternalView"] = "X";
49869
+ })(ViewClass || (ViewClass = {}));
49710
49870
  class View extends _abstract_object_1.AbstractObject {
49711
49871
  getType() {
49712
49872
  return "VIEW";
@@ -49750,6 +49910,16 @@ class View extends _abstract_object_1.AbstractObject {
49750
49910
  // ignore, this is a special case of old style .INCLUDE
49751
49911
  continue;
49752
49912
  }
49913
+ else if (this.parsedData.header.VIEWCLASS === ViewClass.ExternalView) {
49914
+ components.push({
49915
+ name: field.VIEWFIELD,
49916
+ type: new Types.VoidType("ExternalView")
49917
+ });
49918
+ continue;
49919
+ }
49920
+ else if (field.TABNAME === this.getName()) {
49921
+ throw new Error("Unexpected self reference in view " + this.getName() + ", " + field.FIELDNAME + " " + field.FIELDNAME);
49922
+ }
49753
49923
  const lookup = ddic.lookupTableOrView(field.TABNAME);
49754
49924
  let found = lookup.type;
49755
49925
  if (lookup.object) {
@@ -49785,13 +49955,23 @@ class View extends _abstract_object_1.AbstractObject {
49785
49955
  }
49786
49956
  ///////////////
49787
49957
  parseXML() {
49788
- var _a, _b;
49789
- this.parsedData = { fields: [], join: [] };
49958
+ var _a, _b, _c;
49959
+ this.parsedData = {
49960
+ header: {
49961
+ VIEWCLASS: "",
49962
+ },
49963
+ fields: [],
49964
+ join: [],
49965
+ };
49790
49966
  const parsed = super.parseRaw2();
49791
49967
  if (parsed === undefined || parsed.abapGit === undefined) {
49792
49968
  return;
49793
49969
  }
49794
- const fields = (_a = parsed.abapGit["asx:abap"]["asx:values"]) === null || _a === void 0 ? void 0 : _a.DD27P_TABLE;
49970
+ const header = (_a = parsed.abapGit["asx:abap"]["asx:values"]) === null || _a === void 0 ? void 0 : _a.DD25V;
49971
+ this.parsedData.header = {
49972
+ VIEWCLASS: (header === null || header === void 0 ? void 0 : header.VIEWCLASS) || "",
49973
+ };
49974
+ const fields = (_b = parsed.abapGit["asx:abap"]["asx:values"]) === null || _b === void 0 ? void 0 : _b.DD27P_TABLE;
49795
49975
  for (const field of (0, xml_utils_1.xmlToArray)(fields === null || fields === void 0 ? void 0 : fields.DD27P)) {
49796
49976
  this.parsedData.fields.push({
49797
49977
  VIEWFIELD: field.VIEWFIELD,
@@ -49799,7 +49979,7 @@ class View extends _abstract_object_1.AbstractObject {
49799
49979
  FIELDNAME: field.FIELDNAME,
49800
49980
  });
49801
49981
  }
49802
- const join = (_b = parsed.abapGit["asx:abap"]["asx:values"]) === null || _b === void 0 ? void 0 : _b.DD28J_TABLE;
49982
+ const join = (_c = parsed.abapGit["asx:abap"]["asx:values"]) === null || _c === void 0 ? void 0 : _c.DD28J_TABLE;
49803
49983
  for (const j of (0, xml_utils_1.xmlToArray)(join === null || join === void 0 ? void 0 : join.DD28J)) {
49804
49984
  this.parsedData.join.push({
49805
49985
  LTAB: j.LTAB,
@@ -50476,6 +50656,7 @@ const excludeHelper_1 = __webpack_require__(/*! ./utils/excludeHelper */ "./node
50476
50656
  const ddic_references_1 = __webpack_require__(/*! ./ddic_references */ "./node_modules/@abaplint/core/build/src/ddic_references.js");
50477
50657
  const rules_runner_1 = __webpack_require__(/*! ./rules_runner */ "./node_modules/@abaplint/core/build/src/rules_runner.js");
50478
50658
  const msag_references_1 = __webpack_require__(/*! ./msag_references */ "./node_modules/@abaplint/core/build/src/msag_references.js");
50659
+ const macro_references_1 = __webpack_require__(/*! ./macro_references */ "./node_modules/@abaplint/core/build/src/macro_references.js");
50479
50660
  // todo, this should really be an instance in case there are multiple Registry'ies
50480
50661
  class ParsingPerformance {
50481
50662
  static clear() {
@@ -50530,10 +50711,11 @@ class Registry {
50530
50711
  this.conf = conf ? conf : config_1.Config.getDefault();
50531
50712
  this.ddicReferences = new ddic_references_1.DDICReferences();
50532
50713
  this.msagReferences = new msag_references_1.MSAGReferences();
50714
+ this.macroReferences = new macro_references_1.MacroReferences();
50533
50715
  }
50534
50716
  static abaplintVersion() {
50535
50717
  // magic, see build script "version.sh"
50536
- return "2.108.8";
50718
+ return "2.109.3";
50537
50719
  }
50538
50720
  getDDICReferences() {
50539
50721
  return this.ddicReferences;
@@ -50541,6 +50723,9 @@ class Registry {
50541
50723
  getMSAGReferences() {
50542
50724
  return this.msagReferences;
50543
50725
  }
50726
+ getMacroReferences() {
50727
+ return this.macroReferences;
50728
+ }
50544
50729
  *getObjects() {
50545
50730
  for (const name in this.objects) {
50546
50731
  for (const type in this.objects[name]) {
@@ -53398,7 +53583,7 @@ If sy-dbcnt is checked after database statements, it is considered okay.
53398
53583
  If IS ASSIGNED is checked after assigning, it is considered okay.
53399
53584
 
53400
53585
  FIND statement with MATCH COUNT is considered okay if subrc is not checked`,
53401
- tags: [_irule_1.RuleTag.SingleFile],
53586
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
53402
53587
  pseudoComment: "EC CI_SUBRC",
53403
53588
  pragma: "##SUBRC_OK",
53404
53589
  };
@@ -61272,6 +61457,7 @@ __exportStar(__webpack_require__(/*! ./cds_legacy_view */ "./node_modules/@abapl
61272
61457
  __exportStar(__webpack_require__(/*! ./cds_parser_error */ "./node_modules/@abaplint/core/build/src/rules/cds_parser_error.js"), exports);
61273
61458
  __exportStar(__webpack_require__(/*! ./chain_mainly_declarations */ "./node_modules/@abaplint/core/build/src/rules/chain_mainly_declarations.js"), exports);
61274
61459
  __exportStar(__webpack_require__(/*! ./change_if_to_case */ "./node_modules/@abaplint/core/build/src/rules/change_if_to_case.js"), exports);
61460
+ __exportStar(__webpack_require__(/*! ./unused_macros */ "./node_modules/@abaplint/core/build/src/rules/unused_macros.js"), exports);
61275
61461
  __exportStar(__webpack_require__(/*! ./check_abstract */ "./node_modules/@abaplint/core/build/src/rules/check_abstract.js"), exports);
61276
61462
  __exportStar(__webpack_require__(/*! ./check_comments */ "./node_modules/@abaplint/core/build/src/rules/check_comments.js"), exports);
61277
61463
  __exportStar(__webpack_require__(/*! ./check_ddic */ "./node_modules/@abaplint/core/build/src/rules/check_ddic.js"), exports);
@@ -68225,7 +68411,9 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
68225
68411
  exports.SelectSingleFullKey = exports.SelectSingleFullKeyConf = void 0;
68226
68412
  const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
68227
68413
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
68414
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
68228
68415
  const __1 = __webpack_require__(/*! .. */ "./node_modules/@abaplint/core/build/src/index.js");
68416
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
68229
68417
  class SelectSingleFullKeyConf extends _basic_rule_config_1.BasicRuleConfig {
68230
68418
  constructor() {
68231
68419
  super(...arguments);
@@ -68246,7 +68434,7 @@ class SelectSingleFullKey {
68246
68434
 
68247
68435
  If the statement contains a JOIN it is not checked`,
68248
68436
  pseudoComment: "EC CI_NOORDER",
68249
- tags: [],
68437
+ tags: [_irule_1.RuleTag.Quickfix],
68250
68438
  };
68251
68439
  }
68252
68440
  initialize(reg) {
@@ -68267,6 +68455,12 @@ If the statement contains a JOIN it is not checked`,
68267
68455
  setConfig(conf) {
68268
68456
  this.conf = conf;
68269
68457
  }
68458
+ buildFix(file, statement) {
68459
+ return {
68460
+ description: `Add "#EC CI_NOORDER`,
68461
+ edit: edit_helper_1.EditHelper.insertAt(file, statement.getLastToken().getStart(), ` "#EC CI_NOORDER`),
68462
+ };
68463
+ }
68270
68464
  run(obj) {
68271
68465
  var _a, _b;
68272
68466
  if (!(obj instanceof __1.ABAPObject)) {
@@ -68328,7 +68522,8 @@ If the statement contains a JOIN it is not checked`,
68328
68522
  }
68329
68523
  }
68330
68524
  if (set.size > 0) {
68331
- issues.push(issue_1.Issue.atStatement(file, s, message, this.getMetadata().key, this.getConfig().severity));
68525
+ const fix = this.buildFix(file, s);
68526
+ issues.push(issue_1.Issue.atStatement(file, s, message, this.getMetadata().key, this.getConfig().severity, undefined, [fix]));
68332
68527
  }
68333
68528
  }
68334
68529
  }
@@ -70793,7 +70988,13 @@ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./
70793
70988
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
70794
70989
  const Statements = __webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
70795
70990
  const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
70991
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
70796
70992
  class UnnecessaryReturnConf extends _basic_rule_config_1.BasicRuleConfig {
70993
+ constructor() {
70994
+ super(...arguments);
70995
+ /** Allow empty METHODs + FORMs + FUNCTION-MODULEs */
70996
+ this.allowEmpty = false;
70997
+ }
70797
70998
  }
70798
70999
  exports.UnnecessaryReturnConf = UnnecessaryReturnConf;
70799
71000
  class UnnecessaryReturn extends _abap_rule_1.ABAPRule {
@@ -70837,15 +71038,29 @@ ENDFORM.`,
70837
71038
  }
70838
71039
  const message = "Unnecessary RETURN";
70839
71040
  const statements = file.getStatements();
71041
+ let statementCounter = 0;
70840
71042
  for (let i = 0; i < statements.length; i++) {
70841
71043
  const node = statements[i];
70842
- if (!(node.get() instanceof Statements.EndMethod
70843
- || node.get() instanceof Statements.EndForm
70844
- || node.get() instanceof Statements.EndFunction)) {
71044
+ const nodeType = node.get();
71045
+ if ((nodeType instanceof Statements.MethodImplementation
71046
+ || nodeType instanceof Statements.Form
71047
+ || nodeType instanceof Statements.FunctionModule)) {
71048
+ statementCounter = 0;
71049
+ continue;
71050
+ }
71051
+ if (!(nodeType instanceof _statement_1.Comment)) {
71052
+ statementCounter++;
71053
+ }
71054
+ if (!(nodeType instanceof Statements.EndMethod
71055
+ || nodeType instanceof Statements.EndForm
71056
+ || nodeType instanceof Statements.EndFunction)) {
70845
71057
  continue;
70846
71058
  }
70847
71059
  const prev = statements[i - 1];
70848
71060
  if (prev && prev.get() instanceof Statements.Return) {
71061
+ if (this.conf.allowEmpty === true && statementCounter === 2) {
71062
+ continue;
71063
+ }
70849
71064
  const fix = edit_helper_1.EditHelper.deleteStatement(file, prev);
70850
71065
  issues.push(issue_1.Issue.atStatement(file, prev, message, this.getMetadata().key, this.getConfig().severity, fix));
70851
71066
  }
@@ -71121,6 +71336,90 @@ exports.UnusedDDIC = UnusedDDIC;
71121
71336
 
71122
71337
  /***/ }),
71123
71338
 
71339
+ /***/ "./node_modules/@abaplint/core/build/src/rules/unused_macros.js":
71340
+ /*!**********************************************************************!*\
71341
+ !*** ./node_modules/@abaplint/core/build/src/rules/unused_macros.js ***!
71342
+ \**********************************************************************/
71343
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
71344
+
71345
+ "use strict";
71346
+
71347
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
71348
+ exports.UnusedMacros = exports.UnusedMacrosConf = void 0;
71349
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
71350
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
71351
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
71352
+ const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
71353
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
71354
+ class UnusedMacrosConf extends _basic_rule_config_1.BasicRuleConfig {
71355
+ constructor() {
71356
+ super(...arguments);
71357
+ /** skip specific names, case insensitive
71358
+ * @uniqueItems true
71359
+ */
71360
+ this.skipNames = [];
71361
+ }
71362
+ }
71363
+ exports.UnusedMacrosConf = UnusedMacrosConf;
71364
+ class UnusedMacros {
71365
+ constructor() {
71366
+ this.conf = new UnusedMacrosConf();
71367
+ }
71368
+ getMetadata() {
71369
+ return {
71370
+ key: "unused_macros",
71371
+ title: "Unused macros",
71372
+ shortDescription: `Checks for unused macro definitions definitions`,
71373
+ tags: [_irule_1.RuleTag.Quickfix],
71374
+ badExample: `DEFINE foobar1.
71375
+ WRITE 'hello'.
71376
+ END-OF-DEFINITION.`,
71377
+ goodExample: `DEFINE foobar2.
71378
+ WRITE 'hello'.
71379
+ END-OF-DEFINITION.
71380
+
71381
+ foobar2.`,
71382
+ };
71383
+ }
71384
+ getConfig() {
71385
+ return this.conf;
71386
+ }
71387
+ setConfig(conf) {
71388
+ this.conf = conf;
71389
+ if (this.conf.skipNames === undefined) {
71390
+ this.conf.skipNames = [];
71391
+ }
71392
+ }
71393
+ initialize(reg) {
71394
+ this.reg = reg;
71395
+ return this;
71396
+ }
71397
+ run(obj) {
71398
+ var _a;
71399
+ const result = [];
71400
+ if (!(obj instanceof _abap_object_1.ABAPObject)) {
71401
+ return [];
71402
+ }
71403
+ const references = this.reg.getMacroReferences();
71404
+ for (const file of obj.getABAPFiles()) {
71405
+ for (const macroToken of references.listDefinitionsByFile(file.getFilename())) {
71406
+ const usages = references.listUsagesbyMacro(file.getFilename(), macroToken);
71407
+ if (usages.length === 0 && ((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.includes(macroToken.getStr().toUpperCase())) === false) {
71408
+ const message = "Unused macro definition: " + macroToken.getStr();
71409
+ const pos = references.getDefinitionRange(file.getFilename(), macroToken);
71410
+ const fix = edit_helper_1.EditHelper.deleteRange(file, pos.start, pos.end);
71411
+ result.push(issue_1.Issue.atToken(file, macroToken, message, this.getMetadata().key, this.conf.severity, fix));
71412
+ }
71413
+ }
71414
+ }
71415
+ return result;
71416
+ }
71417
+ }
71418
+ exports.UnusedMacros = UnusedMacros;
71419
+ //# sourceMappingURL=unused_macros.js.map
71420
+
71421
+ /***/ }),
71422
+
71124
71423
  /***/ "./node_modules/@abaplint/core/build/src/rules/unused_methods.js":
71125
71424
  /*!***********************************************************************!*\
71126
71425
  !*** ./node_modules/@abaplint/core/build/src/rules/unused_methods.js ***!
@@ -77551,12 +77850,12 @@ class Transpiler {
77551
77850
  progress?.set(reg.getObjectCount(false), "Building");
77552
77851
  for (const obj of reg.getObjects()) {
77553
77852
  await progress?.tick("Building, " + obj.getName());
77554
- if (obj instanceof abaplint.ABAPObject && !(obj instanceof abaplint.Objects.TypePool)) {
77555
- output.objects.push(...new handle_abap_1.HandleABAP(this.options).runObject(obj, reg));
77556
- }
77557
- else if (obj instanceof abaplint.Objects.TypePool) {
77853
+ if (obj instanceof abaplint.Objects.TypePool) {
77558
77854
  output.objects.push(...new handle_type_pool_1.HandleTypePool().runObject(obj, reg));
77559
77855
  }
77856
+ else if (obj instanceof abaplint.ABAPObject) {
77857
+ output.objects.push(...new handle_abap_1.HandleABAP(this.options).runObject(obj, reg));
77858
+ }
77560
77859
  else if (obj instanceof abaplint.Objects.Oauth2Profile) {
77561
77860
  output.objects.push(...new handle_oa2p_1.HandleOA2P().runObject(obj, reg));
77562
77861
  }
@@ -85833,28 +86132,29 @@ async function run() {
85833
86132
  for (const st of this.getSortedTests(reg)) {
85834
86133
  ret += `// --------------------------------------------\n`;
85835
86134
  ret += ` clas = unit.addObject("${st.obj.getName()}");\n`;
86135
+ const lc = st.localClass.toLowerCase();
85836
86136
  ret += ` {
85837
- const {${st.localClass}} = await import("./${this.escapeNamespace(st.obj.getName().toLowerCase())}.${st.obj.getType().toLowerCase()}.testclasses.mjs");
85838
- locl = clas.addTestClass("${st.localClass}");
85839
- if (${st.localClass}.class_setup) await ${st.localClass}.class_setup();\n`;
86137
+ const {${lc}} = await import("./${this.escapeNamespace(st.obj.getName().toLowerCase())}.${st.obj.getType().toLowerCase()}.testclasses.mjs");
86138
+ locl = clas.addTestClass("${lc}");
86139
+ if (${lc}.class_setup) await ${lc}.class_setup();\n`;
85840
86140
  for (const m of st.methods) {
85841
- const skipThis = (skip || []).some(a => a.object === st.obj.getName() && a.class === st.localClass && a.method === m);
86141
+ const skipThis = (skip || []).some(a => a.object === st.obj.getName() && a.class === lc && a.method === m);
85842
86142
  if (skipThis) {
85843
- ret += ` console.log('${st.obj.getName()}: running ${st.localClass}->${m}, skipped');\n`;
86143
+ ret += ` console.log('${st.obj.getName()}: running ${lc}->${m}, skipped');\n`;
85844
86144
  ret += ` meth = locl.addMethod("${m}");\n`;
85845
86145
  ret += ` meth.skip();\n`;
85846
86146
  continue;
85847
86147
  }
85848
- ret += ` {\n const test = await (new ${st.localClass}()).constructor_();\n`;
86148
+ ret += ` {\n const test = await (new ${lc}()).constructor_();\n`;
85849
86149
  ret += ` if (test.setup) await test.setup();\n`;
85850
- ret += ` console.log("${st.obj.getName()}: running ${st.localClass}->${m}");\n`;
86150
+ ret += ` console.log("${st.obj.getName()}: running ${lc}->${m}");\n`;
85851
86151
  ret += ` meth = locl.addMethod("${m}");\n`;
85852
86152
  ret += ` await test.${m}();\n`;
85853
86153
  ret += ` meth.pass();\n`;
85854
86154
  ret += ` if (test.teardown) await test.teardown();\n`;
85855
86155
  ret += ` }\n`;
85856
86156
  }
85857
- ret += ` if (${st.localClass}.class_teardown) await ${st.localClass}.class_teardown();\n`;
86157
+ ret += ` if (${lc}.class_teardown) await ${lc}.class_teardown();\n`;
85858
86158
  ret += ` }\n`;
85859
86159
  }
85860
86160
  /*
@@ -86676,6 +86976,8 @@ exports.validate = function (xmlData, options) {
86676
86976
  return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' doesn't have proper closing.", getLineNumberForPosition(xmlData, i));
86677
86977
  } else if (attrStr.trim().length > 0) {
86678
86978
  return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos));
86979
+ } else if (tags.length === 0) {
86980
+ return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos));
86679
86981
  } else {
86680
86982
  const otg = tags.pop();
86681
86983
  if (tagName !== otg.tagName) {
@@ -87963,10 +88265,18 @@ const parseXml = function(xmlData) {
87963
88265
  let tagContent = "";
87964
88266
  //self-closing tag
87965
88267
  if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
88268
+ if(tagName[tagName.length - 1] === "/"){ //remove trailing '/'
88269
+ tagName = tagName.substr(0, tagName.length - 1);
88270
+ jPath = jPath.substr(0, jPath.length - 1);
88271
+ tagExp = tagName;
88272
+ }else{
88273
+ tagExp = tagExp.substr(0, tagExp.length - 1);
88274
+ }
87966
88275
  i = result.closeIndex;
87967
88276
  }
87968
88277
  //unpaired tag
87969
88278
  else if(this.options.unpairedTags.indexOf(tagName) !== -1){
88279
+
87970
88280
  i = result.closeIndex;
87971
88281
  }
87972
88282
  //normal tag
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.8.25",
3
+ "version": "2.8.27",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -26,12 +26,12 @@
26
26
  "author": "abaplint",
27
27
  "license": "MIT",
28
28
  "devDependencies": {
29
- "@abaplint/transpiler": "^2.8.25",
29
+ "@abaplint/transpiler": "^2.8.27",
30
30
  "@types/glob": "^8.1.0",
31
31
  "glob": "=7.2.0",
32
32
  "@types/progress": "^2.0.7",
33
- "@types/node": "^20.12.12",
34
- "@abaplint/core": "^2.108.8",
33
+ "@types/node": "^20.14.2",
34
+ "@abaplint/core": "^2.109.3",
35
35
  "progress": "^2.0.3",
36
36
  "webpack": "^5.91.0",
37
37
  "webpack-cli": "^5.1.4",