@abaplint/transpiler-cli 2.14.2 → 2.14.3

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 +497 -203
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -1405,7 +1405,7 @@ class Lexer {
1405
1405
  else if (this.m === ModeTemplate
1406
1406
  && this.buffer.length() > 1
1407
1407
  && (current === CH_PIPE || current === CH_LBRACE)
1408
- && (stream.prevChar() !== CH_BACKSLASH || (stream.prevPrevChar() === CH_BACKSLASH && stream.prevChar() === CH_BACKSLASH))) {
1408
+ && stream.countPrevious(CH_BACKSLASH) % 2 === 0) {
1409
1409
  // end of template
1410
1410
  if (current === CH_LBRACE || AFTER_LITERAL.has(ahead)) {
1411
1411
  this.add();
@@ -1559,6 +1559,14 @@ class LexerStream {
1559
1559
  }
1560
1560
  return this.raw.charCodeAt(o);
1561
1561
  }
1562
+ /** number of consecutive occurrences of the character directly before the current one */
1563
+ countPrevious(code) {
1564
+ let count = 0;
1565
+ for (let o = this.offset - 1; o >= 0 && this.raw.charCodeAt(o) === code; o--) {
1566
+ count++;
1567
+ }
1568
+ return count;
1569
+ }
1562
1570
  currentChar() {
1563
1571
  if (this.offset < 0) {
1564
1572
  return NL; // simulate newline at start of file to handle star(*) comments
@@ -21558,6 +21566,21 @@ exports.sta = sta;
21558
21566
  exports.sub = sub;
21559
21567
  const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
21560
21568
  const _statement_1 = __webpack_require__(/*! ../../2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
21569
+ function toMatch(statements, m) {
21570
+ return {
21571
+ matched: statements.slice(0, m.next),
21572
+ unmatched: statements.slice(m.next),
21573
+ error: m.error,
21574
+ errorDescription: m.errorDescription,
21575
+ errorMatched: m.errorMatched,
21576
+ };
21577
+ }
21578
+ function success(next) {
21579
+ return { next, error: false, errorDescription: "", errorMatched: 0 };
21580
+ }
21581
+ function failure(next, errorDescription, errorMatched) {
21582
+ return { next, error: true, errorDescription, errorMatched };
21583
+ }
21561
21584
  class Sequence {
21562
21585
  constructor(list) {
21563
21586
  if (list.length < 2) {
@@ -21576,36 +21599,18 @@ class Sequence {
21576
21599
  return this.list[0].first();
21577
21600
  }
21578
21601
  run(statements, parent) {
21579
- let inn = statements;
21580
- let out = [];
21602
+ return toMatch(statements, this.runAt(statements, 0, parent));
21603
+ }
21604
+ runAt(statements, index, parent) {
21605
+ let next = index;
21581
21606
  for (const i of this.list) {
21582
- const match = i.run(inn, parent);
21607
+ const match = i.runAt(statements, next, parent);
21583
21608
  if (match.error) {
21584
- return {
21585
- matched: [],
21586
- unmatched: statements,
21587
- error: true,
21588
- errorDescription: match.errorDescription,
21589
- errorMatched: out.length,
21590
- };
21591
- }
21592
- if (match.matched.length < 100) {
21593
- out.push(...match.matched);
21594
- }
21595
- else {
21596
- // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
21597
- // when the number of matched elements is very large
21598
- out = out.concat(match.matched);
21609
+ return failure(index, match.errorDescription, next - index);
21599
21610
  }
21600
- inn = match.unmatched;
21611
+ next = match.next;
21601
21612
  }
21602
- return {
21603
- matched: out,
21604
- unmatched: inn,
21605
- error: false,
21606
- errorDescription: "",
21607
- errorMatched: 0,
21608
- };
21613
+ return success(next);
21609
21614
  }
21610
21615
  }
21611
21616
  // Note that the Alternative does not nessesarily return the first in the alternative
@@ -21644,21 +21649,18 @@ class Alternative {
21644
21649
  return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
21645
21650
  }
21646
21651
  run(statements, parent) {
21652
+ return toMatch(statements, this.runAt(statements, 0, parent));
21653
+ }
21654
+ runAt(statements, index, parent) {
21647
21655
  this.setupMap();
21648
21656
  let count = 0;
21649
21657
  let countError = "";
21650
- if (statements.length === 0) {
21651
- return {
21652
- matched: [],
21653
- unmatched: statements,
21654
- error: true,
21655
- errorDescription: countError,
21656
- errorMatched: count,
21657
- };
21658
+ if (index >= statements.length) {
21659
+ return failure(index, countError, count);
21658
21660
  }
21659
- const token = statements[0].getFirstToken().getStr().toUpperCase();
21661
+ const token = statements[index].getFirstToken().getStr().toUpperCase();
21660
21662
  for (const i of this.map[token] || []) {
21661
- const match = i.run(statements, parent);
21663
+ const match = i.runAt(statements, index, parent);
21662
21664
  if (match.error === false) {
21663
21665
  return match;
21664
21666
  }
@@ -21668,7 +21670,7 @@ class Alternative {
21668
21670
  }
21669
21671
  }
21670
21672
  for (const i of this.map[""] || []) {
21671
- const match = i.run(statements, parent);
21673
+ const match = i.runAt(statements, index, parent);
21672
21674
  if (match.error === false) {
21673
21675
  return match;
21674
21676
  }
@@ -21678,22 +21680,10 @@ class Alternative {
21678
21680
  }
21679
21681
  }
21680
21682
  if (count === 0) {
21681
- return {
21682
- matched: [],
21683
- unmatched: statements,
21684
- error: true,
21685
- errorDescription: "Unexpected code structure",
21686
- errorMatched: count,
21687
- };
21683
+ return failure(index, "Unexpected code structure", count);
21688
21684
  }
21689
21685
  else {
21690
- return {
21691
- matched: [],
21692
- unmatched: statements,
21693
- error: true,
21694
- errorDescription: countError,
21695
- errorMatched: count,
21696
- };
21686
+ return failure(index, countError, count);
21697
21687
  }
21698
21688
  }
21699
21689
  }
@@ -21708,7 +21698,10 @@ class Optional {
21708
21698
  return this.obj.getUsing();
21709
21699
  }
21710
21700
  run(statements, parent) {
21711
- const ret = this.obj.run(statements, parent);
21701
+ return toMatch(statements, this.runAt(statements, 0, parent));
21702
+ }
21703
+ runAt(statements, index, parent) {
21704
+ const ret = this.obj.runAt(statements, index, parent);
21712
21705
  ret.error = false;
21713
21706
  return ret;
21714
21707
  }
@@ -21727,48 +21720,24 @@ class Star {
21727
21720
  return this.obj.getUsing();
21728
21721
  }
21729
21722
  run(statements, parent) {
21730
- let inn = statements;
21731
- let out = [];
21723
+ return toMatch(statements, this.runAt(statements, 0, parent));
21724
+ }
21725
+ runAt(statements, index, parent) {
21726
+ let next = index;
21732
21727
  while (true) {
21733
- if (inn.length === 0) {
21734
- return {
21735
- matched: out,
21736
- unmatched: inn,
21737
- error: false,
21738
- errorDescription: "",
21739
- errorMatched: 0,
21740
- };
21728
+ if (next >= statements.length) {
21729
+ return success(next);
21741
21730
  }
21742
- const match = this.obj.run(inn, parent);
21731
+ const match = this.obj.runAt(statements, next, parent);
21743
21732
  if (match.error === true) {
21744
21733
  if (match.errorMatched > 0) {
21745
- return {
21746
- matched: out,
21747
- unmatched: inn,
21748
- error: true,
21749
- errorDescription: match.errorDescription,
21750
- errorMatched: match.errorMatched,
21751
- };
21734
+ return failure(next, match.errorDescription, match.errorMatched);
21752
21735
  }
21753
21736
  else {
21754
- return {
21755
- matched: out,
21756
- unmatched: inn,
21757
- error: false,
21758
- errorDescription: "",
21759
- errorMatched: 0,
21760
- };
21737
+ return success(next);
21761
21738
  }
21762
21739
  }
21763
- if (match.matched.length < 100) {
21764
- out.push(...match.matched);
21765
- }
21766
- else {
21767
- // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
21768
- // when the number of matched elements is very large
21769
- out = out.concat(match.matched);
21770
- }
21771
- inn = match.unmatched;
21740
+ next = match.next;
21772
21741
  }
21773
21742
  }
21774
21743
  first() {
@@ -21797,10 +21766,13 @@ class SubStructure {
21797
21766
  }
21798
21767
  }
21799
21768
  run(statements, parent) {
21769
+ return toMatch(statements, this.runAt(statements, 0, parent));
21770
+ }
21771
+ runAt(statements, index, parent) {
21800
21772
  const nparent = new nodes_1.StructureNode(this.s);
21801
21773
  this.setupMatcher();
21802
- const ret = this.matcher.run(statements, nparent);
21803
- if (ret.matched.length === 0) {
21774
+ const ret = this.matcher.runAt(statements, index, nparent);
21775
+ if (ret.next === index) {
21804
21776
  ret.error = true;
21805
21777
  }
21806
21778
  else {
@@ -21830,33 +21802,18 @@ class SubStatement {
21830
21802
  return this.obj.name;
21831
21803
  }
21832
21804
  run(statements, parent) {
21833
- if (statements.length === 0) {
21834
- return {
21835
- matched: [],
21836
- unmatched: [],
21837
- error: true,
21838
- errorDescription: "Expected " + this.className().toUpperCase(),
21839
- errorMatched: 0,
21840
- };
21805
+ return toMatch(statements, this.runAt(statements, 0, parent));
21806
+ }
21807
+ runAt(statements, index, parent) {
21808
+ if (index >= statements.length) {
21809
+ return failure(statements.length, "Expected " + this.className().toUpperCase(), 0);
21841
21810
  }
21842
- else if (statements[0].get() instanceof this.obj) {
21843
- parent.addChild(statements[0]);
21844
- return {
21845
- matched: [statements[0]],
21846
- unmatched: statements.splice(1),
21847
- error: false,
21848
- errorDescription: "",
21849
- errorMatched: 0,
21850
- };
21811
+ else if (statements[index].get() instanceof this.obj) {
21812
+ parent.addChild(statements[index]);
21813
+ return success(index + 1);
21851
21814
  }
21852
21815
  else {
21853
- return {
21854
- matched: [],
21855
- unmatched: statements,
21856
- error: true,
21857
- errorDescription: "Expected " + this.className().toUpperCase(),
21858
- errorMatched: 0,
21859
- };
21816
+ return failure(index, "Expected " + this.className().toUpperCase(), 0);
21860
21817
  }
21861
21818
  }
21862
21819
  }
@@ -29602,7 +29559,7 @@ class BasicTypes {
29602
29559
  if (children.length === 0) {
29603
29560
  return new Types.UnknownType("Type error, could not resolve \"" + fullName + "\", resolveLikeName1");
29604
29561
  }
29605
- let type = undefined;
29562
+ let type;
29606
29563
  if (children[1] && (children[1].getFirstToken().getStr() === "=>" || children[1].getFirstToken().getStr() === "->")) {
29607
29564
  type = field_chain_1.FieldChain.runSyntax(chain, this.input, _reference_1.ReferenceType.TypeReference);
29608
29565
  }
@@ -29865,7 +29822,7 @@ class BasicTypes {
29865
29822
  primaryKey: primaryKey,
29866
29823
  secondary: secondaryKeys,
29867
29824
  };
29868
- let found = undefined;
29825
+ let found;
29869
29826
  if (text.startsWith("TYPE TABLE OF REF TO ")
29870
29827
  || text.startsWith("TYPE STANDARD TABLE OF REF TO ")
29871
29828
  || text.startsWith("TYPE SORTED TABLE OF REF TO ")
@@ -30003,7 +29960,7 @@ class BasicTypes {
30003
29960
  name = typeName === null || typeName === void 0 ? void 0 : typeName.concatTokens();
30004
29961
  }
30005
29962
  const type = this.resolveLikeName(e, false);
30006
- let row = undefined;
29963
+ let row;
30007
29964
  if (type === undefined) {
30008
29965
  return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
30009
29966
  }
@@ -30198,7 +30155,7 @@ class BasicTypes {
30198
30155
  rest = split[1];
30199
30156
  }
30200
30157
  const subs = rest.split("-");
30201
- let foundType = undefined;
30158
+ let foundType;
30202
30159
  if (className && chainText.includes("=>")) {
30203
30160
  const split = chainText.split("=>");
30204
30161
  const className = split[0];
@@ -30621,6 +30578,143 @@ function checkDatabaseFields(fields, dbSources, input, token) {
30621
30578
 
30622
30579
  /***/ },
30623
30580
 
30581
+ /***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js"
30582
+ /*!******************************************************************************************************!*\
30583
+ !*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js ***!
30584
+ \******************************************************************************************************/
30585
+ (__unused_webpack_module, exports, __webpack_require__) {
30586
+
30587
+ "use strict";
30588
+
30589
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
30590
+ if (k2 === undefined) k2 = k;
30591
+ var desc = Object.getOwnPropertyDescriptor(m, k);
30592
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
30593
+ desc = { enumerable: true, get: function() { return m[k]; } };
30594
+ }
30595
+ Object.defineProperty(o, k2, desc);
30596
+ }) : (function(o, m, k, k2) {
30597
+ if (k2 === undefined) k2 = k;
30598
+ o[k2] = m[k];
30599
+ }));
30600
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30601
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30602
+ }) : function(o, v) {
30603
+ o["default"] = v;
30604
+ });
30605
+ var __importStar = (this && this.__importStar) || (function () {
30606
+ var ownKeys = function(o) {
30607
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30608
+ var ar = [];
30609
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30610
+ return ar;
30611
+ };
30612
+ return ownKeys(o);
30613
+ };
30614
+ return function (mod) {
30615
+ if (mod && mod.__esModule) return mod;
30616
+ var result = {};
30617
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
30618
+ __setModuleDefault(result, mod);
30619
+ return result;
30620
+ };
30621
+ })();
30622
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
30623
+ exports.checkDatabaseWorkArea = checkDatabaseWorkArea;
30624
+ const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
30625
+ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
30626
+ const Basic = __importStar(__webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js"));
30627
+ const objects_1 = __webpack_require__(/*! ../../../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
30628
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
30629
+ // byte length of a flat type in a unicode system, as a lower and an upper bound:
30630
+ // IntegerType also stands for INT1 and INT2, and padding is left out of the lower bound
30631
+ function bounds(type) {
30632
+ if (type instanceof Basic.CharacterType || type instanceof Basic.NumericType) {
30633
+ return { min: type.getLength() * 2, max: type.getLength() * 2, align: 2 };
30634
+ }
30635
+ else if (type instanceof Basic.DateType) {
30636
+ return { min: 16, max: 16, align: 2 };
30637
+ }
30638
+ else if (type instanceof Basic.TimeType) {
30639
+ return { min: 12, max: 12, align: 2 };
30640
+ }
30641
+ else if (type instanceof Basic.IntegerType) {
30642
+ return { min: 1, max: 4, align: 4 };
30643
+ }
30644
+ else if (type instanceof Basic.Integer8Type || type instanceof Basic.FloatType
30645
+ || type instanceof Basic.DecFloat16Type || type instanceof Basic.UTCLongType) {
30646
+ return { min: 8, max: 8, align: 8 };
30647
+ }
30648
+ else if (type instanceof Basic.DecFloat34Type) {
30649
+ return { min: 16, max: 16, align: 16 };
30650
+ }
30651
+ else if (type instanceof Basic.PackedType || type instanceof Basic.HexType) {
30652
+ return { min: type.getLength(), max: type.getLength(), align: 1 };
30653
+ }
30654
+ else if (type instanceof Basic.StructureType) {
30655
+ let min = 0;
30656
+ let max = 0;
30657
+ let align = 1;
30658
+ for (const component of type.getComponents()) {
30659
+ const sub = bounds(component.type);
30660
+ if (sub === undefined) {
30661
+ return undefined;
30662
+ }
30663
+ align = Math.max(align, sub.align);
30664
+ max = Math.ceil(max / sub.align) * sub.align + sub.max;
30665
+ min = min + sub.min;
30666
+ }
30667
+ max = Math.ceil(max / align) * align;
30668
+ return { min, max, align };
30669
+ }
30670
+ // deep, generic, void or unknown
30671
+ return undefined;
30672
+ }
30673
+ // INSERT/MODIFY/UPDATE dbtab FROM wa: the work area must be at least as long as the table line,
30674
+ // client field included, else the statement is a syntax error on the system
30675
+ function checkDatabaseWorkArea(node, dbSource, sourceTypes, input) {
30676
+ var _a;
30677
+ if (!(dbSource instanceof objects_1.Table)) {
30678
+ return;
30679
+ }
30680
+ const children = node.getChildren();
30681
+ let workArea = undefined;
30682
+ for (let i = 0; i < children.length - 1; i++) {
30683
+ const child = children[i];
30684
+ if (child instanceof nodes_1.TokenNode && child.concatTokens().toUpperCase() === "FROM") {
30685
+ const next = children[i + 1];
30686
+ if (next instanceof nodes_1.ExpressionNode && next.get() instanceof Expressions.SQLSource) {
30687
+ workArea = next;
30688
+ }
30689
+ break;
30690
+ }
30691
+ }
30692
+ if (workArea === undefined) {
30693
+ return;
30694
+ }
30695
+ const source = (_a = workArea.findFirstExpression(Expressions.SimpleSource3)) !== null && _a !== void 0 ? _a : workArea.findFirstExpression(Expressions.Source);
30696
+ if (source === undefined) {
30697
+ return;
30698
+ }
30699
+ const waType = sourceTypes.get(source);
30700
+ if (!(waType instanceof Basic.StructureType)) {
30701
+ return;
30702
+ }
30703
+ const tableType = dbSource.parseType(input.scope.getRegistry());
30704
+ const waBounds = bounds(waType);
30705
+ const tableBounds = bounds(tableType);
30706
+ if (waBounds === undefined || tableBounds === undefined) {
30707
+ return;
30708
+ }
30709
+ if (waBounds.max < tableBounds.min) {
30710
+ const message = "The work area \"" + source.concatTokens() + "\" is not long enough for table " + dbSource.getName();
30711
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
30712
+ }
30713
+ }
30714
+ //# sourceMappingURL=_check_database_work_area.js.map
30715
+
30716
+ /***/ },
30717
+
30624
30718
  /***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js"
30625
30719
  /*!*************************************************************************************************!*\
30626
30720
  !*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js ***!
@@ -30942,7 +31036,7 @@ class AttributeName {
30942
31036
  return context;
30943
31037
  }
30944
31038
  const helper = new _object_oriented_1.ObjectOriented(input.scope);
30945
- let ret = undefined;
31039
+ let ret;
30946
31040
  if (context instanceof object_reference_type_1.ObjectReferenceType) {
30947
31041
  const def = input.scope.findObjectDefinition(context.getIdentifierName());
30948
31042
  if (def === undefined) {
@@ -31967,7 +32061,7 @@ const let_1 = __webpack_require__(/*! ./let */ "./node_modules/@abaplint/core/bu
31967
32061
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
31968
32062
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
31969
32063
  class ConvBody {
31970
- static runSyntax(node, input) {
32064
+ static runSyntax(node, input, targetType) {
31971
32065
  let scoped = false;
31972
32066
  const l = node.findDirectExpression(Expressions.Let);
31973
32067
  if (l) {
@@ -31979,7 +32073,7 @@ class ConvBody {
31979
32073
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
31980
32074
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
31981
32075
  }
31982
- const sourceType = source_1.Source.runSyntax(s, input);
32076
+ const sourceType = source_1.Source.runSyntax(s, input, targetType);
31983
32077
  if (scoped === true) {
31984
32078
  input.scope.pop(node.getLastToken().getEnd());
31985
32079
  }
@@ -32512,7 +32606,7 @@ class FieldChain {
32512
32606
  return found.getType();
32513
32607
  }
32514
32608
  }
32515
- let context = undefined;
32609
+ let context;
32516
32610
  const children = node.getChildren();
32517
32611
  context = this.findTop(children[0], input, refType);
32518
32612
  let prev = children[0].concatTokens();
@@ -33005,7 +33099,7 @@ class FormParam {
33005
33099
  if (node.findDirectTokenByText("STRUCTURE") && nameToken) {
33006
33100
  // STRUCTURES typing
33007
33101
  const typeName = (_a = node.findDirectExpression(expressions_1.SimpleFieldChain)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
33008
- let type = undefined;
33102
+ let type;
33009
33103
  if (typeName) {
33010
33104
  type = (_b = input.scope.findType(typeName)) === null || _b === void 0 ? void 0 : _b.getType();
33011
33105
  if (type === undefined) {
@@ -34578,7 +34672,7 @@ class MethodParameters {
34578
34672
  }
34579
34673
  checkImporting(node, input, method) {
34580
34674
  for (const item of this.parameterListT(node, input)) {
34581
- let parameterType = undefined;
34675
+ let parameterType;
34582
34676
  if (method instanceof basic_1.VoidType) {
34583
34677
  parameterType = method;
34584
34678
  }
@@ -34615,7 +34709,7 @@ class MethodParameters {
34615
34709
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
34616
34710
  return;
34617
34711
  }
34618
- let parameterType = undefined;
34712
+ let parameterType;
34619
34713
  if (method instanceof basic_1.VoidType) {
34620
34714
  parameterType = method;
34621
34715
  }
@@ -35932,9 +36026,8 @@ class Select {
35932
36026
  }
35933
36027
  static findFields(node, input) {
35934
36028
  var _a, _b;
35935
- let expr = undefined;
36029
+ const expr = node.findFirstExpression(Expressions.SQLFieldList);
35936
36030
  const ret = [];
35937
- expr = node.findFirstExpression(Expressions.SQLFieldList);
35938
36031
  if (((_a = expr === null || expr === void 0 ? void 0 : expr.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
35939
36032
  dynamic_1.Dynamic.runSyntax(expr.getFirstChild(), input);
35940
36033
  }
@@ -36028,6 +36121,7 @@ const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifie
36028
36121
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
36029
36122
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
36030
36123
  const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/assert_error.js");
36124
+ const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
36031
36125
  /*
36032
36126
  * Type interference, valid scenarios:
36033
36127
  * typed = VALUE #( ... ). right hand side must follow left hand type
@@ -36040,7 +36134,7 @@ const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_module
36040
36134
  // TODO: refactor all these method parameters to objects, this is getting messy
36041
36135
  class Source {
36042
36136
  static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false, readReference = true) {
36043
- var _a;
36137
+ var _a, _b, _c, _d;
36044
36138
  if (node === undefined) {
36045
36139
  return undefined;
36046
36140
  }
@@ -36118,7 +36212,7 @@ class Source {
36118
36212
  case "CONV":
36119
36213
  {
36120
36214
  const foundType = this.determineType(node, input, targetType);
36121
- const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input);
36215
+ const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input, foundType);
36122
36216
  const inferred = (_a = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.concatTokens();
36123
36217
  if (new _type_utils_1.TypeUtils(input.scope).isConvable(foundType, bodyType) === false) {
36124
36218
  const message = `CONV: Types not compatible, ${foundType === null || foundType === void 0 ? void 0 : foundType.constructor.name}, ${bodyType === null || bodyType === void 0 ? void 0 : bodyType.constructor.name}`;
@@ -36135,7 +36229,13 @@ class Source {
36135
36229
  this.traverseRemainingChildren(children, input);
36136
36230
  return bodyType;
36137
36231
  }
36138
- this.addIfInferred(node, input, foundType);
36232
+ const bodySource = (_b = node.findDirectExpression(Expressions.ConvBody)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.Source);
36233
+ const nestedType = (_c = bodySource === null || bodySource === void 0 ? void 0 : bodySource.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
36234
+ // CONV # passes its target type into a nested inferred constructor, so
36235
+ // showing both inferred types would produce duplicate inlay hints.
36236
+ if (!(inferred === "#" && nestedType === "#")) {
36237
+ this.addIfInferred(node, input, foundType);
36238
+ }
36139
36239
  this.traverseRemainingChildren(children, input);
36140
36240
  return foundType;
36141
36241
  }
@@ -36192,6 +36292,15 @@ class Source {
36192
36292
  case "CORRESPONDING":
36193
36293
  {
36194
36294
  const foundType = this.determineType(node, input, targetType);
36295
+ if ((foundType === null || foundType === void 0 ? void 0 : foundType.isGeneric()) === true
36296
+ && ((_d = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _d === void 0 ? void 0 : _d.concatTokens()) === "#"
36297
+ && !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
36298
+ && input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
36299
+ && !input.scope.getOpenABAP()) {
36300
+ const message = "CORRESPONDING #, the type of the target is generic";
36301
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
36302
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
36303
+ }
36195
36304
  corresponding_body_1.CorrespondingBody.runSyntax(node.findDirectExpression(Expressions.CorrespondingBody), input, foundType);
36196
36305
  this.addIfInferred(node, input, foundType);
36197
36306
  return foundType;
@@ -38837,6 +38946,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@ab
38837
38946
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
38838
38947
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
38839
38948
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
38949
+ const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
38840
38950
  class Assign {
38841
38951
  runSyntax(node, input) {
38842
38952
  var _a;
@@ -38844,7 +38954,7 @@ class Assign {
38844
38954
  const isComponent = ((_a = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getFirstChild()) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase()) === "COMPONENT";
38845
38955
  const sources = (assignSource === null || assignSource === void 0 ? void 0 : assignSource.findDirectExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) || [];
38846
38956
  const theSource = sources[sources.length - 1];
38847
- let sourceType = undefined;
38957
+ let sourceType;
38848
38958
  const firstAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[0];
38849
38959
  const secondAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[1];
38850
38960
  const thirdAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[2];
@@ -38860,6 +38970,19 @@ class Assign {
38860
38970
  }
38861
38971
  else {
38862
38972
  sourceType = source_1.Source.runSyntax(theSource, input, undefined, false, isComponent === false);
38973
+ if ((secondAssign === null || secondAssign === void 0 ? void 0 : secondAssign.concatTokens()) === "->"
38974
+ && (thirdAssign === null || thirdAssign === void 0 ? void 0 : thirdAssign.get()) instanceof Expressions.Dynamic
38975
+ && (sourceType === null || sourceType === void 0 ? void 0 : sourceType.isGeneric()) === true
38976
+ && !(sourceType instanceof basic_1.DataReference)
38977
+ && !(sourceType instanceof basic_1.ObjectReferenceType)
38978
+ && !(sourceType instanceof basic_1.GenericObjectReferenceType)
38979
+ && !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
38980
+ && input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
38981
+ && !input.scope.getOpenABAP()) {
38982
+ const message = `"${theSource.concatTokens()}" is not a reference variable`;
38983
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
38984
+ return;
38985
+ }
38863
38986
  }
38864
38987
  if ((assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren().length) === 5
38865
38988
  && isComponent) {
@@ -43586,20 +43709,23 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
43586
43709
  const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
43587
43710
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
43588
43711
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
43712
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
43589
43713
  class InsertDatabase {
43590
43714
  runSyntax(node, input) {
43715
+ const sourceTypes = new Map();
43591
43716
  for (const s of node.findAllExpressions(Expressions.Source)) {
43592
- source_1.Source.runSyntax(s, input);
43717
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
43593
43718
  }
43594
43719
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
43595
- source_1.Source.runSyntax(s, input);
43720
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
43596
43721
  }
43597
43722
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
43598
43723
  dynamic_1.Dynamic.runSyntax(d, input);
43599
43724
  }
43600
43725
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
43601
43726
  if (dbtab !== undefined) {
43602
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
43727
+ const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
43728
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
43603
43729
  }
43604
43730
  }
43605
43731
  }
@@ -44185,7 +44311,7 @@ class Loop {
44185
44311
  && topType instanceof basic_1.TableType) {
44186
44312
  // https://github.com/abap2xlsx/abap2xlsx/issues/1341
44187
44313
  const keyName = node.findExpressionAfterToken("KEY");
44188
- let key = undefined;
44314
+ let key;
44189
44315
  const name = (keyName === null || keyName === void 0 ? void 0 : keyName.get()) instanceof Expressions.SimpleName ? keyName.getFirstToken().getStr().toUpperCase() : undefined;
44190
44316
  // it might be dynamic, in that case we cannot check anything; and
44191
44317
  // primary_key is the predefined name of the primary key every table has
@@ -44542,11 +44668,13 @@ const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modu
44542
44668
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
44543
44669
  const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
44544
44670
  const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
44671
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
44545
44672
  class ModifyDatabase {
44546
44673
  runSyntax(node, input) {
44547
44674
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
44548
44675
  dynamic_1.Dynamic.runSyntax(d, input);
44549
44676
  }
44677
+ let dbSource = undefined;
44550
44678
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
44551
44679
  if (dbtab !== undefined) {
44552
44680
  if (node.getChildren().length === 5) {
@@ -44555,19 +44683,21 @@ class ModifyDatabase {
44555
44683
  input.scope.addReference(dbtab.getFirstToken(), found, _reference_1.ReferenceType.DataWriteReference, input.filename);
44556
44684
  }
44557
44685
  else {
44558
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
44686
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
44559
44687
  }
44560
44688
  }
44561
44689
  else {
44562
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
44690
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
44563
44691
  }
44564
44692
  }
44693
+ const sourceTypes = new Map();
44565
44694
  for (const s of node.findAllExpressions(Expressions.Source)) {
44566
- source_1.Source.runSyntax(s, input);
44695
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
44567
44696
  }
44568
44697
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
44569
- source_1.Source.runSyntax(s, input);
44698
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
44570
44699
  }
44700
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
44571
44701
  }
44572
44702
  }
44573
44703
  exports.ModifyDatabase = ModifyDatabase;
@@ -48467,11 +48597,13 @@ const identifier_1 = __webpack_require__(/*! ../../1_lexer/tokens/identifier */
48467
48597
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
48468
48598
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
48469
48599
  const _check_database_fields_1 = __webpack_require__(/*! ../expressions/_check_database_fields */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_fields.js");
48600
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
48470
48601
  class UpdateDatabase {
48471
48602
  runSyntax(node, input) {
48603
+ let dbSource = undefined;
48472
48604
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
48473
48605
  if (dbtab !== undefined) {
48474
- const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
48606
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
48475
48607
  const fields = node.findAllExpressions(Expressions.SQLFieldAndValue)
48476
48608
  .flatMap(fieldAndValue => fieldAndValue.findDirectExpressions(Expressions.SQLFieldName))
48477
48609
  .map(field => field.concatTokens().toUpperCase());
@@ -48494,15 +48626,17 @@ class UpdateDatabase {
48494
48626
  }
48495
48627
  }
48496
48628
  }
48629
+ const sourceTypes = new Map();
48497
48630
  for (const s of node.findAllExpressions(Expressions.Source)) {
48498
- source_1.Source.runSyntax(s, input);
48631
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
48499
48632
  }
48500
48633
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
48501
- source_1.Source.runSyntax(s, input);
48634
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
48502
48635
  }
48503
48636
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
48504
48637
  dynamic_1.Dynamic.runSyntax(d, input);
48505
48638
  }
48639
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
48506
48640
  if (input.scope.getType() === _scope_type_1.ScopeType.OpenSQL) {
48507
48641
  input.scope.pop(node.getLastToken().getEnd());
48508
48642
  }
@@ -48691,7 +48825,7 @@ class WhenType {
48691
48825
  if (nameToken === undefined) {
48692
48826
  return undefined;
48693
48827
  }
48694
- let type = undefined;
48828
+ let type;
48695
48829
  const className = nameToken.getStr().toUpperCase();
48696
48830
  const found = input.scope.existsObject(className);
48697
48831
  if (found === null || found === void 0 ? void 0 : found.id) {
@@ -53815,7 +53949,7 @@ class Attributes {
53815
53949
  return false;
53816
53950
  }
53817
53951
  parseAttribute(node, visibility, input) {
53818
- let found = undefined;
53952
+ let found;
53819
53953
  const s = node.get();
53820
53954
  if (s instanceof Statements.Data) {
53821
53955
  found = new data_1.Data().runSyntax(node, input);
@@ -55991,7 +56125,7 @@ class CDSLexer {
55991
56125
  break;
55992
56126
  case "@":
55993
56127
  // @ starts a new annotation; flush current token and start building with @
55994
- build = result.add(build, row, col, mode);
56128
+ result.add(build, row, col, mode);
55995
56129
  build = "@";
55996
56130
  break;
55997
56131
  default:
@@ -60865,7 +60999,7 @@ class Help {
60865
60999
  return content;
60866
61000
  }
60867
61001
  static dumpABAP(file, reg, textDocument, position) {
60868
- let content = "";
61002
+ let content;
60869
61003
  content = `
60870
61004
  <a href="#_tokens" rel="no-refresh">Tokens</a> |
60871
61005
  <a href="#_statements" rel="no-refresh">Statements</a> |
@@ -60898,7 +61032,7 @@ class Help {
60898
61032
  return `<h3 id="_info">Info Dump</h3><pre>` + text + "</pre>";
60899
61033
  }
60900
61034
  static cursorInformation(reg, textDocument, position, file) {
60901
- let ret = "";
61035
+ let ret;
60902
61036
  const found = _lsp_utils_1.LSPUtils.findCursor(reg, { textDocument, position });
60903
61037
  if (found !== undefined) {
60904
61038
  ret = "Statement: " + this.linkToStatement(found.snode.get()) + "<br>\n" +
@@ -64656,7 +64790,7 @@ class DataElement extends _abstract_object_1.AbstractObject {
64656
64790
  }
64657
64791
  parseType(reg) {
64658
64792
  const references = [];
64659
- let lookup = undefined;
64793
+ let lookup;
64660
64794
  this.parse();
64661
64795
  if (this.parsedXML === undefined) {
64662
64796
  lookup = { type: new Types.UnknownType("Data Element " + this.getName() + ", parser error") };
@@ -70107,6 +70241,7 @@ class Table extends _abstract_object_1.AbstractObject {
70107
70241
  PRECFIELD: field.PRECFIELD,
70108
70242
  LENG: field.LENG,
70109
70243
  INTLEN: field.INTLEN,
70244
+ INTTYPE: field.INTTYPE,
70110
70245
  DATATYPE: field.DATATYPE,
70111
70246
  DECIMALS: field.DECIMALS,
70112
70247
  KEYFLAG: field.KEYFLAG,
@@ -71625,7 +71760,7 @@ class Registry {
71625
71760
  }
71626
71761
  static abaplintVersion() {
71627
71762
  // magic, see build script "version.js"
71628
- return "2.120.71";
71763
+ return "2.120.72";
71629
71764
  }
71630
71765
  getDDICReferences() {
71631
71766
  return this.ddicReferences;
@@ -72973,7 +73108,7 @@ class AlignPseudoComments extends _abap_rule_1.ABAPRule {
72973
73108
  }
72974
73109
  const col = firstCommentToken.getStart().getCol();
72975
73110
  if (previousEnd.getCol() < expectedColumn && col !== expectedColumn) {
72976
- let fix = undefined;
73111
+ let fix;
72977
73112
  if (col < expectedColumn) {
72978
73113
  fix = edit_helper_1.EditHelper.insertAt(file, firstCommentToken.getStart(), " ".repeat(expectedColumn - col));
72979
73114
  }
@@ -73140,7 +73275,7 @@ ENDINTERFACE.`,
73140
73275
  if (f.after.getCol() === column) {
73141
73276
  continue;
73142
73277
  }
73143
- let fix = undefined;
73278
+ let fix;
73144
73279
  if (f.after.getCol() < column) {
73145
73280
  fix = edit_helper_1.EditHelper.insertAt(file, f.after, " ".repeat(column - f.after.getCol()));
73146
73281
  }
@@ -75531,7 +75666,7 @@ ENDCASE.`,
75531
75666
  if (tuples.length === 1) {
75532
75667
  return false;
75533
75668
  }
75534
- let chain = "";
75669
+ let chain;
75535
75670
  if (tuples[0].left === tuples[1].left) {
75536
75671
  chain = tuples[0].left;
75537
75672
  }
@@ -75820,7 +75955,7 @@ class CheckDDIC {
75820
75955
  this.conf = conf;
75821
75956
  }
75822
75957
  run(obj) {
75823
- let found = undefined;
75958
+ let found;
75824
75959
  if (obj instanceof Objects.DataElement
75825
75960
  || obj instanceof Objects.Domain
75826
75961
  || obj instanceof Objects.Table
@@ -76544,7 +76679,6 @@ ENDCLASS.`,
76544
76679
  this.conf = conf;
76545
76680
  }
76546
76681
  runParsed(file, obj) {
76547
- let issues = [];
76548
76682
  if (this.conf.patternKind === undefined) {
76549
76683
  this.conf.patternKind = "required";
76550
76684
  }
@@ -76565,8 +76699,7 @@ ENDCLASS.`,
76565
76699
  attributes = attributes.concat(intfDef.attributes);
76566
76700
  }
76567
76701
  }
76568
- issues = this.checkAttributes(attributes);
76569
- return issues;
76702
+ return this.checkAttributes(attributes);
76570
76703
  }
76571
76704
  checkAttributes(attr) {
76572
76705
  if (attr === undefined) {
@@ -79236,7 +79369,7 @@ Make sure to test the downported code, it might not always be completely correct
79236
79369
  if (found) {
79237
79370
  return found;
79238
79371
  }
79239
- found = this.outlineGetReferenceSimple(high, lowFile);
79372
+ found = this.outlineGetReferenceSimple(high, lowFile, highSyntax);
79240
79373
  if (found) {
79241
79374
  return found;
79242
79375
  }
@@ -79911,7 +80044,17 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
79911
80044
  const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
79912
80045
  return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
79913
80046
  }
79914
- outlineGetReferenceSimple(node, lowFile) {
80047
+ /** the type of a reference to the source: LIKE REF TO it, or REF TO data when its type is generic,
80048
+ * as LIKE REF TO a generically typed field symbol or parameter does not activate */
80049
+ refTypeOf(sourceName, node, lowFile, highSyntax) {
80050
+ var _a;
80051
+ const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
80052
+ if (((_a = spag === null || spag === void 0 ? void 0 : spag.findVariable(sourceName)) === null || _a === void 0 ? void 0 : _a.getType().isGeneric()) === true) {
80053
+ return "TYPE REF TO data";
80054
+ }
80055
+ return "LIKE REF TO " + sourceName;
80056
+ }
80057
+ outlineGetReferenceSimple(node, lowFile, highSyntax) {
79915
80058
  var _a, _b, _c;
79916
80059
  if (!(node.get() instanceof Statements.GetReference)) {
79917
80060
  return undefined;
@@ -79928,7 +80071,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
79928
80071
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
79929
80072
  const firstToken = target.getFirstToken();
79930
80073
  const lastToken = target.getLastToken();
79931
- const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getStart(), `DATA ${targetName} LIKE REF TO ${source.concatTokens()}.\n${indentation}`);
80074
+ const refType = this.refTypeOf(source.concatTokens(), node, lowFile, highSyntax);
80075
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getStart(), `DATA ${targetName} ${refType}.\n${indentation}`);
79932
80076
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), lastToken.getEnd(), targetName);
79933
80077
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
79934
80078
  return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
@@ -79945,7 +80089,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
79945
80089
  if (!(((_a = target === null || target === void 0 ? void 0 : target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.InlineData)) {
79946
80090
  return undefined;
79947
80091
  }
79948
- let type = "";
80092
+ let type;
79949
80093
  const source = node.findFirstExpression(Expressions.Source);
79950
80094
  if (source === undefined) {
79951
80095
  return undefined;
@@ -80035,8 +80179,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
80035
80179
  if (!(node.get() instanceof Statements.Raise)) {
80036
80180
  return undefined;
80037
80181
  }
80038
- let id = undefined;
80039
- let number = undefined;
80182
+ let id;
80183
+ let number;
80040
80184
  let startToken = node.findDirectTokenByText("ID");
80041
80185
  if (startToken) {
80042
80186
  const sources = node.findDirectExpressions(Expressions.Source);
@@ -80194,7 +80338,7 @@ ${indentation}${uniqueName2}->if_t100_message~t100key = ${uniqueName1}.\n`;
80194
80338
  || sourceRef.getChildren().length !== 1) {
80195
80339
  return undefined;
80196
80340
  }
80197
- let code = "";
80341
+ let code;
80198
80342
  if (sourceRef.findFirstExpression(Expressions.TableExpression)) {
80199
80343
  const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
80200
80344
  code = `ASSIGN ${sourceRef.concatTokens()} TO FIELD-SYMBOL(<${uniqueName}>).
@@ -80386,7 +80530,7 @@ LOOP AT ${groupTargetName}tab ${groupTarget}.`;
80386
80530
  || !(tableExpression instanceof nodes_1.ExpressionNode)) {
80387
80531
  return undefined;
80388
80532
  }
80389
- let condition = "";
80533
+ let condition;
80390
80534
  if (tableExpression.getChildren().length === 3) {
80391
80535
  const index = tableExpression.findDirectExpression(Expressions.Source);
80392
80536
  if (index === undefined) {
@@ -80570,7 +80714,7 @@ ${indentation}${uniqueName}`;
80570
80714
  return undefined;
80571
80715
  }
80572
80716
  const op = secondChild.getFirstToken();
80573
- let operator = "";
80717
+ let operator;
80574
80718
  switch (op.getStr()) {
80575
80719
  case "+":
80576
80720
  operator = " + ";
@@ -80612,7 +80756,7 @@ ${indentation}${uniqueName}`;
80612
80756
  || (formatting === null || formatting === void 0 ? void 0 : formatting.startsWith("ALPHA = ")) === false) {
80613
80757
  continue;
80614
80758
  }
80615
- let functionName = "";
80759
+ let functionName;
80616
80760
  switch (formatting) {
80617
80761
  case "ALPHA = IN":
80618
80762
  functionName = "CONVERSION_EXIT_ALPHA_INPUT";
@@ -80908,13 +81052,12 @@ ${indentation} output = ${uniqueName}.\n`;
80908
81052
  const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
80909
81053
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
80910
81054
  let body = "";
80911
- let name = "";
80912
81055
  const switchBody = i.findDirectExpression(Expressions.SwitchBody);
80913
81056
  if (switchBody === undefined) {
80914
81057
  continue;
80915
81058
  }
80916
81059
  for (const l of ((_c = switchBody === null || switchBody === void 0 ? void 0 : switchBody.findDirectExpression(Expressions.Let)) === null || _c === void 0 ? void 0 : _c.findDirectExpressions(Expressions.InlineFieldDefinition)) || []) {
80917
- name = l.getFirstToken().getStr();
81060
+ const name = l.getFirstToken().getStr();
80918
81061
  body += indentation + `DATA(${name}) = ${(_d = switchBody.findFirstExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens()}.\n`;
80919
81062
  }
80920
81063
  body += `DATA ${uniqueName} ${type}.\n`;
@@ -80972,7 +81115,6 @@ ${indentation} output = ${uniqueName}.\n`;
80972
81115
  const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
80973
81116
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
80974
81117
  let body = "";
80975
- let name = "";
80976
81118
  const reduceBody = i.findDirectExpression(Expressions.ReduceBody);
80977
81119
  if (reduceBody === undefined) {
80978
81120
  continue;
@@ -80983,7 +81125,7 @@ ${indentation} output = ${uniqueName}.\n`;
80983
81125
  }
80984
81126
  let firstName = "";
80985
81127
  for (const init of reduceBody.findDirectExpressions(Expressions.InlineFieldDefinition)) {
80986
- name = init.getFirstToken().getStr();
81128
+ const name = init.getFirstToken().getStr();
80987
81129
  if (firstName === "") {
80988
81130
  firstName = name;
80989
81131
  }
@@ -81215,7 +81357,7 @@ ${indentation} output = ${uniqueName}.\n`;
81215
81357
  after += c.concatTokens();
81216
81358
  }
81217
81359
  }
81218
- let condition = "";
81360
+ let condition;
81219
81361
  if ((tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.getChildren().length) === 3) {
81220
81362
  condition = "INDEX " + ((_d = tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.findDirectExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens());
81221
81363
  }
@@ -81366,7 +81508,7 @@ ${indentation} output = ${uniqueName}.\n`;
81366
81508
  continue;
81367
81509
  }
81368
81510
  const name = nameToken.getStr();
81369
- let type = "";
81511
+ let type;
81370
81512
  if (high.concatTokens().toUpperCase().startsWith("APPEND INITIAL LINE TO ")) {
81371
81513
  type = "LIKE LINE OF " + ((_b = high.findFirstExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
81372
81514
  }
@@ -81732,7 +81874,7 @@ ${indentation} output = ${uniqueName}.\n`;
81732
81874
  }
81733
81875
  return undefined;
81734
81876
  }
81735
- getReference(node, lowFile, _highSyntax) {
81877
+ getReference(node, lowFile, highSyntax) {
81736
81878
  var _a, _b, _c;
81737
81879
  if (!(node.get() instanceof Statements.GetReference)) {
81738
81880
  return undefined;
@@ -81746,7 +81888,7 @@ ${indentation} output = ${uniqueName}.\n`;
81746
81888
  if (targetName === undefined || sourceName === undefined) {
81747
81889
  return undefined;
81748
81890
  }
81749
- const code = `DATA ${targetName} LIKE REF TO ${sourceName}.\n`;
81891
+ const code = `DATA ${targetName} ${this.refTypeOf(sourceName, node, lowFile, highSyntax)}.\n`;
81750
81892
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
81751
81893
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inline.getFirstToken().getStart(), inline.getLastToken().getEnd(), targetName);
81752
81894
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
@@ -81823,18 +81965,30 @@ ${indentation} output = ${uniqueName}.\n`;
81823
81965
  const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
81824
81966
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
81825
81967
  const sy = func === "LINE_EXISTS" ? "sy-subrc" : "sy-tabix";
81826
- const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
81827
- indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
81828
- indentation + uniqueName + ` = ${sy}.\n` +
81829
- indentation;
81830
81968
  let insertAt = node.getFirstToken().getStart();
81831
81969
  if (node.get() instanceof statements_1.ElseIf) {
81832
- // assumption: no side effects in IF conditions
81970
+ // assumption: no side effects in IF conditions, except the READ itself, see below
81833
81971
  insertAt = this.findStartOfIf(node, highFile);
81834
81972
  if (insertAt === undefined) {
81835
81973
  continue;
81836
81974
  }
81837
81975
  }
81976
+ // the READ sets sy-subrc and sy-tabix, which the built-in function does not,
81977
+ // keep the values for the code that reads them after the inserted READ
81978
+ const keep = [];
81979
+ const reads = this.readSyFields(insertAt, highFile);
81980
+ for (const field of ["sy-subrc", "sy-tabix"]) {
81981
+ if (reads.has(field)) {
81982
+ keep.push({ field, name: this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax) });
81983
+ }
81984
+ }
81985
+ const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
81986
+ keep.map(k => indentation + `DATA ${k.name} LIKE ${k.field}.\n`).join("") +
81987
+ keep.map(k => indentation + `${k.name} = ${k.field}.\n`).join("") +
81988
+ indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
81989
+ indentation + uniqueName + ` = ${sy}.\n` +
81990
+ keep.map(k => indentation + `${k.field} = ${k.name}.\n`).join("") +
81991
+ indentation;
81838
81992
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, insertAt, code);
81839
81993
  const start = expression.getFirstToken().getStart();
81840
81994
  const end = expression.getLastToken().getEnd();
@@ -81845,6 +81999,46 @@ ${indentation} output = ${uniqueName}.\n`;
81845
81999
  }
81846
82000
  return undefined;
81847
82001
  }
82002
+ /** sy-subrc and sy-tabix, when read from the position on, in the procedure around it or the file outside of one;
82003
+ * inside a loop from the start of the outermost loop, as the next pass reads what this one left */
82004
+ readSyFields(position, highFile) {
82005
+ const structure = highFile.getStructure();
82006
+ const contains = (s) => !position.isBefore(s.getFirstToken().getStart())
82007
+ && !position.isAfter(s.getLastToken().getStart());
82008
+ let scope = undefined;
82009
+ for (const s of [Structures.Method, Structures.Form, Structures.FunctionModule]) {
82010
+ for (const p of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(s)) || []) {
82011
+ if (contains(p)) {
82012
+ scope = p;
82013
+ }
82014
+ }
82015
+ }
82016
+ scope = scope || structure;
82017
+ let from = position;
82018
+ for (const s of [Structures.Loop, Structures.Do, Structures.While, Structures.Select]) {
82019
+ for (const l of (scope === null || scope === void 0 ? void 0 : scope.findAllStructuresRecursive(s)) || []) {
82020
+ if (contains(l) && l.getFirstToken().getStart().isBefore(from)) {
82021
+ from = l.getFirstToken().getStart();
82022
+ }
82023
+ }
82024
+ }
82025
+ const ret = new Set();
82026
+ for (const s of (scope === null || scope === void 0 ? void 0 : scope.findAllStatementNodes()) || []) {
82027
+ if (s.getLastToken().getStart().isBefore(from)) {
82028
+ continue;
82029
+ }
82030
+ const tokens = s.getTokens();
82031
+ for (let i = 0; i < tokens.length - 2; i++) {
82032
+ if (tokens[i].getStr().toUpperCase() === "SY" && tokens[i + 1].getStr() === "-") {
82033
+ const field = "sy-" + tokens[i + 2].getStr().toLowerCase();
82034
+ if (field === "sy-subrc" || field === "sy-tabix") {
82035
+ ret.add(field);
82036
+ }
82037
+ }
82038
+ }
82039
+ }
82040
+ return ret;
82041
+ }
81848
82042
  findStartOfIf(node, highFile) {
81849
82043
  const structure = highFile.getStructure();
81850
82044
  for (const c of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(Structures.If)) || []) {
@@ -81857,6 +82051,7 @@ ${indentation} output = ${uniqueName}.\n`;
81857
82051
  return undefined;
81858
82052
  }
81859
82053
  newToCreateObject(low, high, lowFile, highSyntax) {
82054
+ var _a;
81860
82055
  if (!(low.get() instanceof _statement_1.Unknown)) {
81861
82056
  return undefined;
81862
82057
  }
@@ -81872,7 +82067,7 @@ ${indentation} output = ${uniqueName}.\n`;
81872
82067
  && found
81873
82068
  && source.concatTokens() === found.concatTokens()
81874
82069
  && target.findDirectExpression(Expressions.InlineData) === undefined) {
81875
- const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
82070
+ const abap = (_a = this.newDataReference(high, target, found, lowFile, highSyntax)) !== null && _a !== void 0 ? _a : this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
81876
82071
  if (abap !== undefined) {
81877
82072
  fix = edit_helper_1.EditHelper.replaceRange(lowFile, high.getFirstToken().getStart(), high.getLastToken().getEnd(), abap);
81878
82073
  }
@@ -81911,6 +82106,42 @@ ${indentation} output = ${uniqueName}.\n`;
81911
82106
  return undefined;
81912
82107
  }
81913
82108
  }
82109
+ /** NEW into a data reference creates data, CREATE OBJECT cannot: "target = NEW #|type( [value] )"
82110
+ * with a variable typed REF TO a data type becomes CREATE DATA plus the assignment of the value */
82111
+ newDataReference(high, target, found, lowFile, highSyntax) {
82112
+ var _a, _b, _c;
82113
+ if (target.getChildren().length !== 1 || !(((_a = target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.TargetField)) {
82114
+ return undefined;
82115
+ }
82116
+ const children = found.getChildren();
82117
+ const value = found.findDirectExpression(Expressions.Source);
82118
+ // NEW, the type, "(", optionally one value, ")"
82119
+ if (children.length !== 4 + (value ? 1 : 0)) {
82120
+ return undefined;
82121
+ }
82122
+ const name = target.concatTokens();
82123
+ const spag = highSyntax.spaghetti.lookupPosition(high.getFirstToken().getStart(), lowFile.getFilename());
82124
+ const type = (_b = spag === null || spag === void 0 ? void 0 : spag.findVariable(name)) === null || _b === void 0 ? void 0 : _b.getType();
82125
+ if (!(type instanceof basic_1.DataReference)) {
82126
+ return undefined;
82127
+ }
82128
+ const typeName = (_c = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
82129
+ const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
82130
+ let abap = `CREATE DATA ${name}` + (typeName === "#" ? "" : ` TYPE ${typeName}`) + ".";
82131
+ if (value === undefined) {
82132
+ return abap;
82133
+ }
82134
+ else if (type.getType().isGeneric() === false) {
82135
+ return abap + `\n${indentation}${name}->* = ${value.concatTokens()}.`;
82136
+ }
82137
+ // a generic reference cannot be dereferenced as a target below v756
82138
+ const fs = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
82139
+ abap = `FIELD-SYMBOLS ${fs} TYPE any.\n` +
82140
+ indentation + abap + "\n" +
82141
+ indentation + `ASSIGN ${name}->* TO ${fs}.\n` +
82142
+ indentation + `${fs} = ${value.concatTokens()}.`;
82143
+ return abap;
82144
+ }
81914
82145
  newParameters(found, name, highSyntax, lowFile) {
81915
82146
  var _a, _b, _c;
81916
82147
  const typeToken = (_a = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
@@ -82702,6 +82933,8 @@ class EmptyStructureConf extends _basic_rule_config_1.BasicRuleConfig {
82702
82933
  this.try = true;
82703
82934
  /** Checks for empty WHEN blocks */
82704
82935
  this.when = true;
82936
+ /** Checks for empty CATCH blocks, unless the CATCH has pragma ##NO_HANDLER or pseudo comment "#EC NO_HANDLER */
82937
+ this.catch = false;
82705
82938
  // todo, other category containing ELSE
82706
82939
  }
82707
82940
  }
@@ -82814,6 +83047,21 @@ result = xsdbool( sy-subrc = 0 ).`,
82814
83047
  }
82815
83048
  }
82816
83049
  }
83050
+ if (this.getConfig().catch === true) {
83051
+ for (const c of stru.findAllStructuresRecursive(Structures.Catch)) {
83052
+ // a comment in the block does not count, the extended check (SLIN) reports it too
83053
+ if (c.findDirectStructure(Structures.Body) !== undefined) {
83054
+ continue;
83055
+ }
83056
+ const catchStatement = c.getFirstStatement();
83057
+ if (catchStatement === undefined || this.isNoHandler(catchStatement, statements)) {
83058
+ continue;
83059
+ }
83060
+ const token = c.getFirstToken();
83061
+ const issue = issue_1.Issue.atToken(file, token, this.getDescription(c.get().constructor.name), this.getMetadata().key, this.conf.severity);
83062
+ issues.push(issue);
83063
+ }
83064
+ }
82817
83065
  if (this.getConfig().when === true) {
82818
83066
  const tries = stru.findAllStructuresRecursive(Structures.When);
82819
83067
  for (const t of tries) {
@@ -82827,6 +83075,15 @@ result = xsdbool( sy-subrc = 0 ).`,
82827
83075
  }
82828
83076
  return issues;
82829
83077
  }
83078
+ isNoHandler(catchStatement, statements) {
83079
+ if (catchStatement.getPragmas().some(p => p.getStr().toUpperCase() === "##NO_HANDLER")) {
83080
+ return true;
83081
+ }
83082
+ const next = statements[statements.indexOf(catchStatement) + 1];
83083
+ return (next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment
83084
+ && next.getStart().getRow() === catchStatement.getEnd().getRow()
83085
+ && next.concatTokens().toUpperCase().replace(/\s/g, "").includes("\"#ECNO_HANDLER");
83086
+ }
82830
83087
  }
82831
83088
  exports.EmptyStructure = EmptyStructure;
82832
83089
  //# sourceMappingURL=empty_structure.js.map
@@ -84263,7 +84520,7 @@ cl_abap_typedescr=>describe_by_name(
84263
84520
  const methodSource = statNode.findDirectExpression(Expressions.MethodSource);
84264
84521
  let methodSourceStr = methodSource === null || methodSource === void 0 ? void 0 : methodSource.concatTokens();
84265
84522
  const methodBody = statNode.findDirectExpression(Expressions.MethodCallBody);
84266
- let methodBodyStr = "";
84523
+ let methodBodyStr;
84267
84524
  if (methodBody) {
84268
84525
  const methodCallParam = methodBody.findDirectExpression(Expressions.MethodCallParam);
84269
84526
  if (methodCallParam && methodCallParam.getFirstToken().getStr() === "(") {
@@ -87157,7 +87414,7 @@ class KeywordCase extends _abap_rule_1.ABAPRule {
87157
87414
  const firstToken = tokens[0].token;
87158
87415
  const lastToken = tokens[tokens.length - 1].token;
87159
87416
  const firstTokenValue = firstToken.getStr();
87160
- let description = "";
87417
+ let description;
87161
87418
  if (first.keyword === true) {
87162
87419
  description = `Keyword should be ${this.conf.style} case: "${firstTokenValue}"`;
87163
87420
  }
@@ -87682,7 +87939,7 @@ ENDCLASS.`,
87682
87939
  continue;
87683
87940
  }
87684
87941
  const className = classDef.name;
87685
- let expected = "";
87942
+ let expected;
87686
87943
  if (classDef.isForTesting) {
87687
87944
  expected = this.conf.test;
87688
87945
  }
@@ -88348,7 +88605,7 @@ ENDIF.
88348
88605
  issues.push(...this.analyzeCondition(file, cond));
88349
88606
  }
88350
88607
  for (const sub of structure.findAllExpressionsMulti([Expressions.CondSub, Expressions.ComponentCondSub])) {
88351
- let cond = [];
88608
+ let cond;
88352
88609
  if (sub.get() instanceof Expressions.CondSub) {
88353
88610
  cond = sub.findDirectExpressions(Expressions.Cond);
88354
88611
  }
@@ -92386,13 +92643,9 @@ ENDIF.`,
92386
92643
  }
92387
92644
  else if (statement instanceof Statements.ClassDefinitionLoad ||
92388
92645
  statement instanceof Statements.InterfaceLoad) {
92389
- let token = undefined;
92390
- if (statement instanceof Statements.ClassDefinitionLoad) {
92391
- token = statementNode.getChildren()[3].getFirstToken();
92392
- }
92393
- else {
92394
- token = statementNode.getChildren()[2].getFirstToken();
92395
- }
92646
+ const token = statement instanceof Statements.ClassDefinitionLoad
92647
+ ? statementNode.getChildren()[3].getFirstToken()
92648
+ : statementNode.getChildren()[2].getFirstToken();
92396
92649
  let startPosition = token.getStart();
92397
92650
  startPosition = new position_1.Position(startPosition.getRow(), startPosition.getCol() - 1);
92398
92651
  return edit_helper_1.EditHelper.deleteRange(file, startPosition, token.getEnd());
@@ -93189,7 +93442,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
93189
93442
  exports.ParserMissingSpace = exports.ParserMissingSpaceConf = void 0;
93190
93443
  const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
93191
93444
  const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
93192
- const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
93193
93445
  const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
93194
93446
  const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
93195
93447
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
@@ -93222,7 +93474,7 @@ This rule makes sure the spaces are consistently required across the language.`,
93222
93474
  }
93223
93475
  runParsed(file) {
93224
93476
  const issues = [];
93225
- let start = new position_1.Position(0, 0);
93477
+ let start;
93226
93478
  for (const statement of file.getStatements()) {
93227
93479
  const missing = this.missingSpace(statement);
93228
93480
  if (missing) {
@@ -94783,14 +95035,8 @@ From 752 and up`,
94783
95035
  }
94784
95036
  getFix(file, statement, withExporting) {
94785
95037
  const children = statement.getChildren();
94786
- let contentFix = undefined;
94787
- if (withExporting) {
94788
- const fixText = "( " + children[5].concatTokens() + " ).";
94789
- contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
94790
- }
94791
- else {
94792
- contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), "( ).");
94793
- }
95038
+ const fixText = withExporting ? "( " + children[5].concatTokens() + " )." : "( ).";
95039
+ const contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
94794
95040
  const replaceType = edit_helper_1.EditHelper.replaceToken(file, children[2].getFirstToken(), "NEW");
94795
95041
  return edit_helper_1.EditHelper.merge(contentFix, replaceType);
94796
95042
  }
@@ -103217,6 +103463,7 @@ class XMLConsistency {
103217
103463
  * Naming for CLAS and INTF objects
103218
103464
  * QUAN fields in TABL objects have reference table and field values
103219
103465
  * Transparent TABL objects have delivery class and size category set
103466
+ * TABL fields with a built-in type carry the INTTYPE abapGit serializes for it, for the confirmed pairs
103220
103467
  * Lock parameter names in ENQU objects are max 16 characters
103221
103468
  * Texts and translations do not exceed maximum allowed length.`,
103222
103469
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
@@ -103483,6 +103730,12 @@ class XMLConsistency {
103483
103730
  const message = `QUAN field ${field.FIELDNAME} must have REFTABLE and REFFIELD set`;
103484
103731
  issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
103485
103732
  }
103733
+ const expected = field.DATATYPE ? XMLConsistency.intTypes[field.DATATYPE] : undefined;
103734
+ if (expected !== undefined && field.INTTYPE !== undefined && field.INTTYPE !== expected) {
103735
+ const message = `Field ${field.FIELDNAME}: INTTYPE "${field.INTTYPE}" does not match DATATYPE ${field.DATATYPE}, ` +
103736
+ `abapGit serializes "${expected}"`;
103737
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
103738
+ }
103486
103739
  }
103487
103740
  if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
103488
103741
  // Confirmed reserved database field names, see issue #4331, DAY and HOUR reported by activation.
@@ -103506,6 +103759,15 @@ class XMLConsistency {
103506
103759
  }
103507
103760
  }
103508
103761
  exports.XMLConsistency = XMLConsistency;
103762
+ // INTTYPE that abapGit serializes for a built-in DATATYPE, confirmed by exported tables;
103763
+ // a different value activates, but shows as a diff on every pull
103764
+ XMLConsistency.intTypes = {
103765
+ "CHAR": "C", "CLNT": "C", "CUKY": "C", "LANG": "C",
103766
+ "DATS": "D", "TIMS": "T",
103767
+ "INT4": "X", "RAW": "X",
103768
+ "DEC": "P", "CURR": "P",
103769
+ "STRG": "g", "SSTR": "g", "RSTR": "y",
103770
+ };
103509
103771
  //# sourceMappingURL=xml_consistency.js.map
103510
103772
 
103511
103773
  /***/ },
@@ -104128,7 +104390,7 @@ class FormLengthStats {
104128
104390
  return res;
104129
104391
  }
104130
104392
  static findName(stat) {
104131
- let name = "";
104393
+ let name;
104132
104394
  const nameExpr = stat.findFirstExpression(expressions_1.FormName);
104133
104395
  if (nameExpr) {
104134
104396
  name = nameExpr.getFirstToken().getStr();
@@ -104539,7 +104801,7 @@ class MethodLengthStats {
104539
104801
  return res;
104540
104802
  }
104541
104803
  static findName(stat) {
104542
- let name = "";
104804
+ let name;
104543
104805
  const nameExpr = stat.findFirstExpression(expressions_1.MethodName);
104544
104806
  if (nameExpr) {
104545
104807
  name = nameExpr.getFirstToken().getStr();
@@ -127396,13 +127658,20 @@ class Traversal {
127396
127658
  if (ref === undefined) {
127397
127659
  return undefined;
127398
127660
  }
127399
- // local
127661
+ // local, also when the interface is declared in another include of the same object,
127662
+ // eg. a local interface in the locals_imp of a class, used in its test classes
127400
127663
  if (ref.getFilename() === this.getFilename()) {
127401
127664
  const scope = this.findCurrentScopeByToken(ref.getToken());
127402
127665
  if (scope?.getIdentifier().stype === abaplint.ScopeType.Interface) {
127403
127666
  return scope?.getIdentifier().sname;
127404
127667
  }
127405
127668
  }
127669
+ else if (this.getCurrentObject().getABAPFileByName(ref.getFilename()) !== undefined) {
127670
+ const scope = this.spaghetti.lookupPosition(ref.getStart(), ref.getFilename());
127671
+ if (scope?.getIdentifier().stype === abaplint.ScopeType.Interface) {
127672
+ return scope?.getIdentifier().sname;
127673
+ }
127674
+ }
127406
127675
  // global
127407
127676
  for (const obj of this.reg.getObjectsByType("INTF")) {
127408
127677
  if (obj.getFiles().some(f => f.getFilename() === ref.getFilename())) {
@@ -127767,8 +128036,33 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
127767
128036
  return `abap.Classes['${name}'] = ${Traversal.escapeNamespace(def.getName().toLowerCase())};`;
127768
128037
  }
127769
128038
  setValues(identifier, name) {
128039
+ // an enumerated value of a class or interface, declared without STRUCTURE: number the
128040
+ // values in the order they are declared, like the STRUCTURE components in setValues below
128041
+ if (identifier.getValue() === "novalueClassAttributeEnum"
128042
+ && !(identifier.getType() instanceof abaplint.BasicTypes.StructureType)) {
128043
+ const index = this.findEnumValueIndex(identifier);
128044
+ return index === undefined ? "" : Traversal.prefixVariable(name) + ".set(" + index + ");\n";
128045
+ }
127770
128046
  return Traversal.setValues(identifier, name);
127771
128047
  }
128048
+ /** position of an enumerated value in its TYPES BEGIN OF ENUM, counting from 0 */
128049
+ findEnumValueIndex(identifier) {
128050
+ // the enum can be declared in another object, eg. a global interface the class implements
128051
+ const filename = identifier.getFilename();
128052
+ const raw = this.reg.getFileByName(filename);
128053
+ const obj = raw === undefined ? undefined : this.reg.findObjectForFile(raw);
128054
+ const file = obj instanceof abaplint.ABAPObject ? obj.getABAPFileByName(filename) : undefined;
128055
+ for (const enumeration of file?.getStructure()?.findAllStructures(abaplint.Structures.TypeEnum) || []) {
128056
+ const values = enumeration.getChildren().filter(c => c instanceof abaplint.Nodes.StatementNode
128057
+ && (c.get() instanceof abaplint.Statements.Type || c.get() instanceof abaplint.Statements.TypeEnum));
128058
+ const index = values.findIndex(v => v
128059
+ .findFirstExpression(abaplint.Expressions.NamespaceSimpleName)?.getFirstToken().getStart().equals(identifier.getStart()));
128060
+ if (index >= 0) {
128061
+ return index;
128062
+ }
128063
+ }
128064
+ return undefined;
128065
+ }
127772
128066
  static setValues(identifier, name) {
127773
128067
  const val = identifier.getValue();
127774
128068
  let ret = "";