@abaplint/cli 2.120.71 → 2.120.73

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/cli.js +563 -204
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -353,7 +353,7 @@ class Lexer {
353
353
  else if (this.m === ModeTemplate
354
354
  && this.buffer.length() > 1
355
355
  && (current === CH_PIPE || current === CH_LBRACE)
356
- && (stream.prevChar() !== CH_BACKSLASH || (stream.prevPrevChar() === CH_BACKSLASH && stream.prevChar() === CH_BACKSLASH))) {
356
+ && stream.countPrevious(CH_BACKSLASH) % 2 === 0) {
357
357
  // end of template
358
358
  if (current === CH_LBRACE || AFTER_LITERAL.has(ahead)) {
359
359
  this.add();
@@ -507,6 +507,14 @@ class LexerStream {
507
507
  }
508
508
  return this.raw.charCodeAt(o);
509
509
  }
510
+ /** number of consecutive occurrences of the character directly before the current one */
511
+ countPrevious(code) {
512
+ let count = 0;
513
+ for (let o = this.offset - 1; o >= 0 && this.raw.charCodeAt(o) === code; o--) {
514
+ count++;
515
+ }
516
+ return count;
517
+ }
510
518
  currentChar() {
511
519
  if (this.offset < 0) {
512
520
  return NL; // simulate newline at start of file to handle star(*) comments
@@ -20506,6 +20514,21 @@ exports.sta = sta;
20506
20514
  exports.sub = sub;
20507
20515
  const nodes_1 = __webpack_require__(/*! ../../nodes */ "../core/build/src/abap/nodes/index.js");
20508
20516
  const _statement_1 = __webpack_require__(/*! ../../2_statements/statements/_statement */ "../core/build/src/abap/2_statements/statements/_statement.js");
20517
+ function toMatch(statements, m) {
20518
+ return {
20519
+ matched: statements.slice(0, m.next),
20520
+ unmatched: statements.slice(m.next),
20521
+ error: m.error,
20522
+ errorDescription: m.errorDescription,
20523
+ errorMatched: m.errorMatched,
20524
+ };
20525
+ }
20526
+ function success(next) {
20527
+ return { next, error: false, errorDescription: "", errorMatched: 0 };
20528
+ }
20529
+ function failure(next, errorDescription, errorMatched) {
20530
+ return { next, error: true, errorDescription, errorMatched };
20531
+ }
20509
20532
  class Sequence {
20510
20533
  constructor(list) {
20511
20534
  if (list.length < 2) {
@@ -20524,36 +20547,18 @@ class Sequence {
20524
20547
  return this.list[0].first();
20525
20548
  }
20526
20549
  run(statements, parent) {
20527
- let inn = statements;
20528
- let out = [];
20550
+ return toMatch(statements, this.runAt(statements, 0, parent));
20551
+ }
20552
+ runAt(statements, index, parent) {
20553
+ let next = index;
20529
20554
  for (const i of this.list) {
20530
- const match = i.run(inn, parent);
20555
+ const match = i.runAt(statements, next, parent);
20531
20556
  if (match.error) {
20532
- return {
20533
- matched: [],
20534
- unmatched: statements,
20535
- error: true,
20536
- errorDescription: match.errorDescription,
20537
- errorMatched: out.length,
20538
- };
20557
+ return failure(index, match.errorDescription, next - index);
20539
20558
  }
20540
- if (match.matched.length < 100) {
20541
- out.push(...match.matched);
20542
- }
20543
- else {
20544
- // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
20545
- // when the number of matched elements is very large
20546
- out = out.concat(match.matched);
20547
- }
20548
- inn = match.unmatched;
20559
+ next = match.next;
20549
20560
  }
20550
- return {
20551
- matched: out,
20552
- unmatched: inn,
20553
- error: false,
20554
- errorDescription: "",
20555
- errorMatched: 0,
20556
- };
20561
+ return success(next);
20557
20562
  }
20558
20563
  }
20559
20564
  // Note that the Alternative does not nessesarily return the first in the alternative
@@ -20592,21 +20597,18 @@ class Alternative {
20592
20597
  return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
20593
20598
  }
20594
20599
  run(statements, parent) {
20600
+ return toMatch(statements, this.runAt(statements, 0, parent));
20601
+ }
20602
+ runAt(statements, index, parent) {
20595
20603
  this.setupMap();
20596
20604
  let count = 0;
20597
20605
  let countError = "";
20598
- if (statements.length === 0) {
20599
- return {
20600
- matched: [],
20601
- unmatched: statements,
20602
- error: true,
20603
- errorDescription: countError,
20604
- errorMatched: count,
20605
- };
20606
+ if (index >= statements.length) {
20607
+ return failure(index, countError, count);
20606
20608
  }
20607
- const token = statements[0].getFirstToken().getStr().toUpperCase();
20609
+ const token = statements[index].getFirstToken().getStr().toUpperCase();
20608
20610
  for (const i of this.map[token] || []) {
20609
- const match = i.run(statements, parent);
20611
+ const match = i.runAt(statements, index, parent);
20610
20612
  if (match.error === false) {
20611
20613
  return match;
20612
20614
  }
@@ -20616,7 +20618,7 @@ class Alternative {
20616
20618
  }
20617
20619
  }
20618
20620
  for (const i of this.map[""] || []) {
20619
- const match = i.run(statements, parent);
20621
+ const match = i.runAt(statements, index, parent);
20620
20622
  if (match.error === false) {
20621
20623
  return match;
20622
20624
  }
@@ -20626,22 +20628,10 @@ class Alternative {
20626
20628
  }
20627
20629
  }
20628
20630
  if (count === 0) {
20629
- return {
20630
- matched: [],
20631
- unmatched: statements,
20632
- error: true,
20633
- errorDescription: "Unexpected code structure",
20634
- errorMatched: count,
20635
- };
20631
+ return failure(index, "Unexpected code structure", count);
20636
20632
  }
20637
20633
  else {
20638
- return {
20639
- matched: [],
20640
- unmatched: statements,
20641
- error: true,
20642
- errorDescription: countError,
20643
- errorMatched: count,
20644
- };
20634
+ return failure(index, countError, count);
20645
20635
  }
20646
20636
  }
20647
20637
  }
@@ -20656,7 +20646,10 @@ class Optional {
20656
20646
  return this.obj.getUsing();
20657
20647
  }
20658
20648
  run(statements, parent) {
20659
- const ret = this.obj.run(statements, parent);
20649
+ return toMatch(statements, this.runAt(statements, 0, parent));
20650
+ }
20651
+ runAt(statements, index, parent) {
20652
+ const ret = this.obj.runAt(statements, index, parent);
20660
20653
  ret.error = false;
20661
20654
  return ret;
20662
20655
  }
@@ -20675,48 +20668,24 @@ class Star {
20675
20668
  return this.obj.getUsing();
20676
20669
  }
20677
20670
  run(statements, parent) {
20678
- let inn = statements;
20679
- let out = [];
20671
+ return toMatch(statements, this.runAt(statements, 0, parent));
20672
+ }
20673
+ runAt(statements, index, parent) {
20674
+ let next = index;
20680
20675
  while (true) {
20681
- if (inn.length === 0) {
20682
- return {
20683
- matched: out,
20684
- unmatched: inn,
20685
- error: false,
20686
- errorDescription: "",
20687
- errorMatched: 0,
20688
- };
20676
+ if (next >= statements.length) {
20677
+ return success(next);
20689
20678
  }
20690
- const match = this.obj.run(inn, parent);
20679
+ const match = this.obj.runAt(statements, next, parent);
20691
20680
  if (match.error === true) {
20692
20681
  if (match.errorMatched > 0) {
20693
- return {
20694
- matched: out,
20695
- unmatched: inn,
20696
- error: true,
20697
- errorDescription: match.errorDescription,
20698
- errorMatched: match.errorMatched,
20699
- };
20682
+ return failure(next, match.errorDescription, match.errorMatched);
20700
20683
  }
20701
20684
  else {
20702
- return {
20703
- matched: out,
20704
- unmatched: inn,
20705
- error: false,
20706
- errorDescription: "",
20707
- errorMatched: 0,
20708
- };
20685
+ return success(next);
20709
20686
  }
20710
20687
  }
20711
- if (match.matched.length < 100) {
20712
- out.push(...match.matched);
20713
- }
20714
- else {
20715
- // avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
20716
- // when the number of matched elements is very large
20717
- out = out.concat(match.matched);
20718
- }
20719
- inn = match.unmatched;
20688
+ next = match.next;
20720
20689
  }
20721
20690
  }
20722
20691
  first() {
@@ -20745,10 +20714,13 @@ class SubStructure {
20745
20714
  }
20746
20715
  }
20747
20716
  run(statements, parent) {
20717
+ return toMatch(statements, this.runAt(statements, 0, parent));
20718
+ }
20719
+ runAt(statements, index, parent) {
20748
20720
  const nparent = new nodes_1.StructureNode(this.s);
20749
20721
  this.setupMatcher();
20750
- const ret = this.matcher.run(statements, nparent);
20751
- if (ret.matched.length === 0) {
20722
+ const ret = this.matcher.runAt(statements, index, nparent);
20723
+ if (ret.next === index) {
20752
20724
  ret.error = true;
20753
20725
  }
20754
20726
  else {
@@ -20778,33 +20750,18 @@ class SubStatement {
20778
20750
  return this.obj.name;
20779
20751
  }
20780
20752
  run(statements, parent) {
20781
- if (statements.length === 0) {
20782
- return {
20783
- matched: [],
20784
- unmatched: [],
20785
- error: true,
20786
- errorDescription: "Expected " + this.className().toUpperCase(),
20787
- errorMatched: 0,
20788
- };
20753
+ return toMatch(statements, this.runAt(statements, 0, parent));
20754
+ }
20755
+ runAt(statements, index, parent) {
20756
+ if (index >= statements.length) {
20757
+ return failure(statements.length, "Expected " + this.className().toUpperCase(), 0);
20789
20758
  }
20790
- else if (statements[0].get() instanceof this.obj) {
20791
- parent.addChild(statements[0]);
20792
- return {
20793
- matched: [statements[0]],
20794
- unmatched: statements.splice(1),
20795
- error: false,
20796
- errorDescription: "",
20797
- errorMatched: 0,
20798
- };
20759
+ else if (statements[index].get() instanceof this.obj) {
20760
+ parent.addChild(statements[index]);
20761
+ return success(index + 1);
20799
20762
  }
20800
20763
  else {
20801
- return {
20802
- matched: [],
20803
- unmatched: statements,
20804
- error: true,
20805
- errorDescription: "Expected " + this.className().toUpperCase(),
20806
- errorMatched: 0,
20807
- };
20764
+ return failure(index, "Expected " + this.className().toUpperCase(), 0);
20808
20765
  }
20809
20766
  }
20810
20767
  }
@@ -28550,7 +28507,7 @@ class BasicTypes {
28550
28507
  if (children.length === 0) {
28551
28508
  return new Types.UnknownType("Type error, could not resolve \"" + fullName + "\", resolveLikeName1");
28552
28509
  }
28553
- let type = undefined;
28510
+ let type;
28554
28511
  if (children[1] && (children[1].getFirstToken().getStr() === "=>" || children[1].getFirstToken().getStr() === "->")) {
28555
28512
  type = field_chain_1.FieldChain.runSyntax(chain, this.input, _reference_1.ReferenceType.TypeReference);
28556
28513
  }
@@ -28813,7 +28770,7 @@ class BasicTypes {
28813
28770
  primaryKey: primaryKey,
28814
28771
  secondary: secondaryKeys,
28815
28772
  };
28816
- let found = undefined;
28773
+ let found;
28817
28774
  if (text.startsWith("TYPE TABLE OF REF TO ")
28818
28775
  || text.startsWith("TYPE STANDARD TABLE OF REF TO ")
28819
28776
  || text.startsWith("TYPE SORTED TABLE OF REF TO ")
@@ -28951,7 +28908,7 @@ class BasicTypes {
28951
28908
  name = typeName === null || typeName === void 0 ? void 0 : typeName.concatTokens();
28952
28909
  }
28953
28910
  const type = this.resolveLikeName(e, false);
28954
- let row = undefined;
28911
+ let row;
28955
28912
  if (type === undefined) {
28956
28913
  return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
28957
28914
  }
@@ -29146,7 +29103,7 @@ class BasicTypes {
29146
29103
  rest = split[1];
29147
29104
  }
29148
29105
  const subs = rest.split("-");
29149
- let foundType = undefined;
29106
+ let foundType;
29150
29107
  if (className && chainText.includes("=>")) {
29151
29108
  const split = chainText.split("=>");
29152
29109
  const className = split[0];
@@ -29569,6 +29526,143 @@ function checkDatabaseFields(fields, dbSources, input, token) {
29569
29526
 
29570
29527
  /***/ },
29571
29528
 
29529
+ /***/ "../core/build/src/abap/5_syntax/expressions/_check_database_work_area.js"
29530
+ /*!********************************************************************************!*\
29531
+ !*** ../core/build/src/abap/5_syntax/expressions/_check_database_work_area.js ***!
29532
+ \********************************************************************************/
29533
+ (__unused_webpack_module, exports, __webpack_require__) {
29534
+
29535
+ "use strict";
29536
+
29537
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
29538
+ if (k2 === undefined) k2 = k;
29539
+ var desc = Object.getOwnPropertyDescriptor(m, k);
29540
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
29541
+ desc = { enumerable: true, get: function() { return m[k]; } };
29542
+ }
29543
+ Object.defineProperty(o, k2, desc);
29544
+ }) : (function(o, m, k, k2) {
29545
+ if (k2 === undefined) k2 = k;
29546
+ o[k2] = m[k];
29547
+ }));
29548
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29549
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29550
+ }) : function(o, v) {
29551
+ o["default"] = v;
29552
+ });
29553
+ var __importStar = (this && this.__importStar) || (function () {
29554
+ var ownKeys = function(o) {
29555
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29556
+ var ar = [];
29557
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29558
+ return ar;
29559
+ };
29560
+ return ownKeys(o);
29561
+ };
29562
+ return function (mod) {
29563
+ if (mod && mod.__esModule) return mod;
29564
+ var result = {};
29565
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
29566
+ __setModuleDefault(result, mod);
29567
+ return result;
29568
+ };
29569
+ })();
29570
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
29571
+ exports.checkDatabaseWorkArea = checkDatabaseWorkArea;
29572
+ const nodes_1 = __webpack_require__(/*! ../../nodes */ "../core/build/src/abap/nodes/index.js");
29573
+ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
29574
+ const Basic = __importStar(__webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js"));
29575
+ const objects_1 = __webpack_require__(/*! ../../../objects */ "../core/build/src/objects/index.js");
29576
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
29577
+ // byte length of a flat type in a unicode system, as a lower and an upper bound:
29578
+ // IntegerType also stands for INT1 and INT2, and padding is left out of the lower bound
29579
+ function bounds(type) {
29580
+ if (type instanceof Basic.CharacterType || type instanceof Basic.NumericType) {
29581
+ return { min: type.getLength() * 2, max: type.getLength() * 2, align: 2 };
29582
+ }
29583
+ else if (type instanceof Basic.DateType) {
29584
+ return { min: 16, max: 16, align: 2 };
29585
+ }
29586
+ else if (type instanceof Basic.TimeType) {
29587
+ return { min: 12, max: 12, align: 2 };
29588
+ }
29589
+ else if (type instanceof Basic.IntegerType) {
29590
+ return { min: 1, max: 4, align: 4 };
29591
+ }
29592
+ else if (type instanceof Basic.Integer8Type || type instanceof Basic.FloatType
29593
+ || type instanceof Basic.DecFloat16Type || type instanceof Basic.UTCLongType) {
29594
+ return { min: 8, max: 8, align: 8 };
29595
+ }
29596
+ else if (type instanceof Basic.DecFloat34Type) {
29597
+ return { min: 16, max: 16, align: 16 };
29598
+ }
29599
+ else if (type instanceof Basic.PackedType || type instanceof Basic.HexType) {
29600
+ return { min: type.getLength(), max: type.getLength(), align: 1 };
29601
+ }
29602
+ else if (type instanceof Basic.StructureType) {
29603
+ let min = 0;
29604
+ let max = 0;
29605
+ let align = 1;
29606
+ for (const component of type.getComponents()) {
29607
+ const sub = bounds(component.type);
29608
+ if (sub === undefined) {
29609
+ return undefined;
29610
+ }
29611
+ align = Math.max(align, sub.align);
29612
+ max = Math.ceil(max / sub.align) * sub.align + sub.max;
29613
+ min = min + sub.min;
29614
+ }
29615
+ max = Math.ceil(max / align) * align;
29616
+ return { min, max, align };
29617
+ }
29618
+ // deep, generic, void or unknown
29619
+ return undefined;
29620
+ }
29621
+ // INSERT/MODIFY/UPDATE dbtab FROM wa: the work area must be at least as long as the table line,
29622
+ // client field included, else the statement is a syntax error on the system
29623
+ function checkDatabaseWorkArea(node, dbSource, sourceTypes, input) {
29624
+ var _a;
29625
+ if (!(dbSource instanceof objects_1.Table)) {
29626
+ return;
29627
+ }
29628
+ const children = node.getChildren();
29629
+ let workArea = undefined;
29630
+ for (let i = 0; i < children.length - 1; i++) {
29631
+ const child = children[i];
29632
+ if (child instanceof nodes_1.TokenNode && child.concatTokens().toUpperCase() === "FROM") {
29633
+ const next = children[i + 1];
29634
+ if (next instanceof nodes_1.ExpressionNode && next.get() instanceof Expressions.SQLSource) {
29635
+ workArea = next;
29636
+ }
29637
+ break;
29638
+ }
29639
+ }
29640
+ if (workArea === undefined) {
29641
+ return;
29642
+ }
29643
+ const source = (_a = workArea.findFirstExpression(Expressions.SimpleSource3)) !== null && _a !== void 0 ? _a : workArea.findFirstExpression(Expressions.Source);
29644
+ if (source === undefined) {
29645
+ return;
29646
+ }
29647
+ const waType = sourceTypes.get(source);
29648
+ if (!(waType instanceof Basic.StructureType)) {
29649
+ return;
29650
+ }
29651
+ const tableType = dbSource.parseType(input.scope.getRegistry());
29652
+ const waBounds = bounds(waType);
29653
+ const tableBounds = bounds(tableType);
29654
+ if (waBounds === undefined || tableBounds === undefined) {
29655
+ return;
29656
+ }
29657
+ if (waBounds.max < tableBounds.min) {
29658
+ const message = "The work area \"" + source.concatTokens() + "\" is not long enough for table " + dbSource.getName();
29659
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
29660
+ }
29661
+ }
29662
+ //# sourceMappingURL=_check_database_work_area.js.map
29663
+
29664
+ /***/ },
29665
+
29572
29666
  /***/ "../core/build/src/abap/5_syntax/expressions/_check_offset_length.js"
29573
29667
  /*!***************************************************************************!*\
29574
29668
  !*** ../core/build/src/abap/5_syntax/expressions/_check_offset_length.js ***!
@@ -29890,7 +29984,7 @@ class AttributeName {
29890
29984
  return context;
29891
29985
  }
29892
29986
  const helper = new _object_oriented_1.ObjectOriented(input.scope);
29893
- let ret = undefined;
29987
+ let ret;
29894
29988
  if (context instanceof object_reference_type_1.ObjectReferenceType) {
29895
29989
  const def = input.scope.findObjectDefinition(context.getIdentifierName());
29896
29990
  if (def === undefined) {
@@ -30915,7 +31009,7 @@ const let_1 = __webpack_require__(/*! ./let */ "../core/build/src/abap/5_syntax/
30915
31009
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
30916
31010
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js");
30917
31011
  class ConvBody {
30918
- static runSyntax(node, input) {
31012
+ static runSyntax(node, input, targetType) {
30919
31013
  let scoped = false;
30920
31014
  const l = node.findDirectExpression(Expressions.Let);
30921
31015
  if (l) {
@@ -30927,7 +31021,7 @@ class ConvBody {
30927
31021
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
30928
31022
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
30929
31023
  }
30930
- const sourceType = source_1.Source.runSyntax(s, input);
31024
+ const sourceType = source_1.Source.runSyntax(s, input, targetType);
30931
31025
  if (scoped === true) {
30932
31026
  input.scope.pop(node.getLastToken().getEnd());
30933
31027
  }
@@ -31460,7 +31554,7 @@ class FieldChain {
31460
31554
  return found.getType();
31461
31555
  }
31462
31556
  }
31463
- let context = undefined;
31557
+ let context;
31464
31558
  const children = node.getChildren();
31465
31559
  context = this.findTop(children[0], input, refType);
31466
31560
  let prev = children[0].concatTokens();
@@ -31953,7 +32047,7 @@ class FormParam {
31953
32047
  if (node.findDirectTokenByText("STRUCTURE") && nameToken) {
31954
32048
  // STRUCTURES typing
31955
32049
  const typeName = (_a = node.findDirectExpression(expressions_1.SimpleFieldChain)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
31956
- let type = undefined;
32050
+ let type;
31957
32051
  if (typeName) {
31958
32052
  type = (_b = input.scope.findType(typeName)) === null || _b === void 0 ? void 0 : _b.getType();
31959
32053
  if (type === undefined) {
@@ -33526,7 +33620,7 @@ class MethodParameters {
33526
33620
  }
33527
33621
  checkImporting(node, input, method) {
33528
33622
  for (const item of this.parameterListT(node, input)) {
33529
- let parameterType = undefined;
33623
+ let parameterType;
33530
33624
  if (method instanceof basic_1.VoidType) {
33531
33625
  parameterType = method;
33532
33626
  }
@@ -33563,7 +33657,7 @@ class MethodParameters {
33563
33657
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
33564
33658
  return;
33565
33659
  }
33566
- let parameterType = undefined;
33660
+ let parameterType;
33567
33661
  if (method instanceof basic_1.VoidType) {
33568
33662
  parameterType = method;
33569
33663
  }
@@ -34880,9 +34974,8 @@ class Select {
34880
34974
  }
34881
34975
  static findFields(node, input) {
34882
34976
  var _a, _b;
34883
- let expr = undefined;
34977
+ const expr = node.findFirstExpression(Expressions.SQLFieldList);
34884
34978
  const ret = [];
34885
- expr = node.findFirstExpression(Expressions.SQLFieldList);
34886
34979
  if (((_a = expr === null || expr === void 0 ? void 0 : expr.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
34887
34980
  dynamic_1.Dynamic.runSyntax(expr.getFirstChild(), input);
34888
34981
  }
@@ -34976,6 +35069,7 @@ const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifie
34976
35069
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "../core/build/src/abap/5_syntax/_type_utils.js");
34977
35070
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
34978
35071
  const assert_error_1 = __webpack_require__(/*! ../assert_error */ "../core/build/src/abap/5_syntax/assert_error.js");
35072
+ const version_1 = __webpack_require__(/*! ../../../version */ "../core/build/src/version.js");
34979
35073
  /*
34980
35074
  * Type interference, valid scenarios:
34981
35075
  * typed = VALUE #( ... ). right hand side must follow left hand type
@@ -34988,7 +35082,7 @@ const assert_error_1 = __webpack_require__(/*! ../assert_error */ "../core/build
34988
35082
  // TODO: refactor all these method parameters to objects, this is getting messy
34989
35083
  class Source {
34990
35084
  static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false, readReference = true) {
34991
- var _a;
35085
+ var _a, _b, _c, _d;
34992
35086
  if (node === undefined) {
34993
35087
  return undefined;
34994
35088
  }
@@ -35066,7 +35160,7 @@ class Source {
35066
35160
  case "CONV":
35067
35161
  {
35068
35162
  const foundType = this.determineType(node, input, targetType);
35069
- const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input);
35163
+ const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input, foundType);
35070
35164
  const inferred = (_a = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.concatTokens();
35071
35165
  if (new _type_utils_1.TypeUtils(input.scope).isConvable(foundType, bodyType) === false) {
35072
35166
  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}`;
@@ -35083,7 +35177,13 @@ class Source {
35083
35177
  this.traverseRemainingChildren(children, input);
35084
35178
  return bodyType;
35085
35179
  }
35086
- this.addIfInferred(node, input, foundType);
35180
+ const bodySource = (_b = node.findDirectExpression(Expressions.ConvBody)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.Source);
35181
+ const nestedType = (_c = bodySource === null || bodySource === void 0 ? void 0 : bodySource.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
35182
+ // CONV # passes its target type into a nested inferred constructor, so
35183
+ // showing both inferred types would produce duplicate inlay hints.
35184
+ if (!(inferred === "#" && nestedType === "#")) {
35185
+ this.addIfInferred(node, input, foundType);
35186
+ }
35087
35187
  this.traverseRemainingChildren(children, input);
35088
35188
  return foundType;
35089
35189
  }
@@ -35140,6 +35240,15 @@ class Source {
35140
35240
  case "CORRESPONDING":
35141
35241
  {
35142
35242
  const foundType = this.determineType(node, input, targetType);
35243
+ if ((foundType === null || foundType === void 0 ? void 0 : foundType.isGeneric()) === true
35244
+ && ((_d = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _d === void 0 ? void 0 : _d.concatTokens()) === "#"
35245
+ && !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
35246
+ && input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
35247
+ && !input.scope.getOpenABAP()) {
35248
+ const message = "CORRESPONDING #, the type of the target is generic";
35249
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
35250
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
35251
+ }
35143
35252
  corresponding_body_1.CorrespondingBody.runSyntax(node.findDirectExpression(Expressions.CorrespondingBody), input, foundType);
35144
35253
  this.addIfInferred(node, input, foundType);
35145
35254
  return foundType;
@@ -37785,6 +37894,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/
37785
37894
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "../core/build/src/abap/5_syntax/expressions/dynamic.js");
37786
37895
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "../core/build/src/abap/5_syntax/_type_utils.js");
37787
37896
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
37897
+ const version_1 = __webpack_require__(/*! ../../../version */ "../core/build/src/version.js");
37788
37898
  class Assign {
37789
37899
  runSyntax(node, input) {
37790
37900
  var _a;
@@ -37792,7 +37902,7 @@ class Assign {
37792
37902
  const isComponent = ((_a = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getFirstChild()) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase()) === "COMPONENT";
37793
37903
  const sources = (assignSource === null || assignSource === void 0 ? void 0 : assignSource.findDirectExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) || [];
37794
37904
  const theSource = sources[sources.length - 1];
37795
- let sourceType = undefined;
37905
+ let sourceType;
37796
37906
  const firstAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[0];
37797
37907
  const secondAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[1];
37798
37908
  const thirdAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[2];
@@ -37808,6 +37918,19 @@ class Assign {
37808
37918
  }
37809
37919
  else {
37810
37920
  sourceType = source_1.Source.runSyntax(theSource, input, undefined, false, isComponent === false);
37921
+ if ((secondAssign === null || secondAssign === void 0 ? void 0 : secondAssign.concatTokens()) === "->"
37922
+ && (thirdAssign === null || thirdAssign === void 0 ? void 0 : thirdAssign.get()) instanceof Expressions.Dynamic
37923
+ && (sourceType === null || sourceType === void 0 ? void 0 : sourceType.isGeneric()) === true
37924
+ && !(sourceType instanceof basic_1.DataReference)
37925
+ && !(sourceType instanceof basic_1.ObjectReferenceType)
37926
+ && !(sourceType instanceof basic_1.GenericObjectReferenceType)
37927
+ && !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
37928
+ && input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
37929
+ && !input.scope.getOpenABAP()) {
37930
+ const message = `"${theSource.concatTokens()}" is not a reference variable`;
37931
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
37932
+ return;
37933
+ }
37811
37934
  }
37812
37935
  if ((assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren().length) === 5
37813
37936
  && isComponent) {
@@ -42534,20 +42657,23 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
42534
42657
  const source_1 = __webpack_require__(/*! ../expressions/source */ "../core/build/src/abap/5_syntax/expressions/source.js");
42535
42658
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "../core/build/src/abap/5_syntax/expressions/dynamic.js");
42536
42659
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "../core/build/src/abap/5_syntax/expressions/database_table.js");
42660
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "../core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
42537
42661
  class InsertDatabase {
42538
42662
  runSyntax(node, input) {
42663
+ const sourceTypes = new Map();
42539
42664
  for (const s of node.findAllExpressions(Expressions.Source)) {
42540
- source_1.Source.runSyntax(s, input);
42665
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
42541
42666
  }
42542
42667
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
42543
- source_1.Source.runSyntax(s, input);
42668
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
42544
42669
  }
42545
42670
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
42546
42671
  dynamic_1.Dynamic.runSyntax(d, input);
42547
42672
  }
42548
42673
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
42549
42674
  if (dbtab !== undefined) {
42550
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
42675
+ const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
42676
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
42551
42677
  }
42552
42678
  }
42553
42679
  }
@@ -43133,7 +43259,7 @@ class Loop {
43133
43259
  && topType instanceof basic_1.TableType) {
43134
43260
  // https://github.com/abap2xlsx/abap2xlsx/issues/1341
43135
43261
  const keyName = node.findExpressionAfterToken("KEY");
43136
- let key = undefined;
43262
+ let key;
43137
43263
  const name = (keyName === null || keyName === void 0 ? void 0 : keyName.get()) instanceof Expressions.SimpleName ? keyName.getFirstToken().getStr().toUpperCase() : undefined;
43138
43264
  // it might be dynamic, in that case we cannot check anything; and
43139
43265
  // primary_key is the predefined name of the primary key every table has
@@ -43490,11 +43616,13 @@ const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "../core/bui
43490
43616
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "../core/build/src/abap/5_syntax/expressions/database_table.js");
43491
43617
  const source_1 = __webpack_require__(/*! ../expressions/source */ "../core/build/src/abap/5_syntax/expressions/source.js");
43492
43618
  const _reference_1 = __webpack_require__(/*! ../_reference */ "../core/build/src/abap/5_syntax/_reference.js");
43619
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "../core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
43493
43620
  class ModifyDatabase {
43494
43621
  runSyntax(node, input) {
43495
43622
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
43496
43623
  dynamic_1.Dynamic.runSyntax(d, input);
43497
43624
  }
43625
+ let dbSource = undefined;
43498
43626
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
43499
43627
  if (dbtab !== undefined) {
43500
43628
  if (node.getChildren().length === 5) {
@@ -43503,19 +43631,21 @@ class ModifyDatabase {
43503
43631
  input.scope.addReference(dbtab.getFirstToken(), found, _reference_1.ReferenceType.DataWriteReference, input.filename);
43504
43632
  }
43505
43633
  else {
43506
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
43634
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
43507
43635
  }
43508
43636
  }
43509
43637
  else {
43510
- database_table_1.DatabaseTable.runSyntax(dbtab, input);
43638
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
43511
43639
  }
43512
43640
  }
43641
+ const sourceTypes = new Map();
43513
43642
  for (const s of node.findAllExpressions(Expressions.Source)) {
43514
- source_1.Source.runSyntax(s, input);
43643
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
43515
43644
  }
43516
43645
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
43517
- source_1.Source.runSyntax(s, input);
43646
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
43518
43647
  }
43648
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
43519
43649
  }
43520
43650
  }
43521
43651
  exports.ModifyDatabase = ModifyDatabase;
@@ -47415,11 +47545,13 @@ const identifier_1 = __webpack_require__(/*! ../../1_lexer/tokens/identifier */
47415
47545
  const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "../core/build/src/abap/5_syntax/expressions/database_table.js");
47416
47546
  const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "../core/build/src/abap/5_syntax/expressions/dynamic.js");
47417
47547
  const _check_database_fields_1 = __webpack_require__(/*! ../expressions/_check_database_fields */ "../core/build/src/abap/5_syntax/expressions/_check_database_fields.js");
47548
+ const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "../core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
47418
47549
  class UpdateDatabase {
47419
47550
  runSyntax(node, input) {
47551
+ let dbSource = undefined;
47420
47552
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
47421
47553
  if (dbtab !== undefined) {
47422
- const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
47554
+ dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
47423
47555
  const fields = node.findAllExpressions(Expressions.SQLFieldAndValue)
47424
47556
  .flatMap(fieldAndValue => fieldAndValue.findDirectExpressions(Expressions.SQLFieldName))
47425
47557
  .map(field => field.concatTokens().toUpperCase());
@@ -47442,15 +47574,17 @@ class UpdateDatabase {
47442
47574
  }
47443
47575
  }
47444
47576
  }
47577
+ const sourceTypes = new Map();
47445
47578
  for (const s of node.findAllExpressions(Expressions.Source)) {
47446
- source_1.Source.runSyntax(s, input);
47579
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
47447
47580
  }
47448
47581
  for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
47449
- source_1.Source.runSyntax(s, input);
47582
+ sourceTypes.set(s, source_1.Source.runSyntax(s, input));
47450
47583
  }
47451
47584
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
47452
47585
  dynamic_1.Dynamic.runSyntax(d, input);
47453
47586
  }
47587
+ (0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
47454
47588
  if (input.scope.getType() === _scope_type_1.ScopeType.OpenSQL) {
47455
47589
  input.scope.pop(node.getLastToken().getEnd());
47456
47590
  }
@@ -47639,7 +47773,7 @@ class WhenType {
47639
47773
  if (nameToken === undefined) {
47640
47774
  return undefined;
47641
47775
  }
47642
- let type = undefined;
47776
+ let type;
47643
47777
  const className = nameToken.getStr().toUpperCase();
47644
47778
  const found = input.scope.existsObject(className);
47645
47779
  if (found === null || found === void 0 ? void 0 : found.id) {
@@ -52763,7 +52897,7 @@ class Attributes {
52763
52897
  return false;
52764
52898
  }
52765
52899
  parseAttribute(node, visibility, input) {
52766
- let found = undefined;
52900
+ let found;
52767
52901
  const s = node.get();
52768
52902
  if (s instanceof Statements.Data) {
52769
52903
  found = new data_1.Data().runSyntax(node, input);
@@ -54939,7 +55073,7 @@ class CDSLexer {
54939
55073
  break;
54940
55074
  case "@":
54941
55075
  // @ starts a new annotation; flush current token and start building with @
54942
- build = result.add(build, row, col, mode);
55076
+ result.add(build, row, col, mode);
54943
55077
  build = "@";
54944
55078
  break;
54945
55079
  default:
@@ -59813,7 +59947,7 @@ class Help {
59813
59947
  return content;
59814
59948
  }
59815
59949
  static dumpABAP(file, reg, textDocument, position) {
59816
- let content = "";
59950
+ let content;
59817
59951
  content = `
59818
59952
  <a href="#_tokens" rel="no-refresh">Tokens</a> |
59819
59953
  <a href="#_statements" rel="no-refresh">Statements</a> |
@@ -59846,7 +59980,7 @@ class Help {
59846
59980
  return `<h3 id="_info">Info Dump</h3><pre>` + text + "</pre>";
59847
59981
  }
59848
59982
  static cursorInformation(reg, textDocument, position, file) {
59849
- let ret = "";
59983
+ let ret;
59850
59984
  const found = _lsp_utils_1.LSPUtils.findCursor(reg, { textDocument, position });
59851
59985
  if (found !== undefined) {
59852
59986
  ret = "Statement: " + this.linkToStatement(found.snode.get()) + "<br>\n" +
@@ -63604,7 +63738,7 @@ class DataElement extends _abstract_object_1.AbstractObject {
63604
63738
  }
63605
63739
  parseType(reg) {
63606
63740
  const references = [];
63607
- let lookup = undefined;
63741
+ let lookup;
63608
63742
  this.parse();
63609
63743
  if (this.parsedXML === undefined) {
63610
63744
  lookup = { type: new Types.UnknownType("Data Element " + this.getName() + ", parser error") };
@@ -69055,6 +69189,7 @@ class Table extends _abstract_object_1.AbstractObject {
69055
69189
  PRECFIELD: field.PRECFIELD,
69056
69190
  LENG: field.LENG,
69057
69191
  INTLEN: field.INTLEN,
69192
+ INTTYPE: field.INTTYPE,
69058
69193
  DATATYPE: field.DATATYPE,
69059
69194
  DECIMALS: field.DECIMALS,
69060
69195
  KEYFLAG: field.KEYFLAG,
@@ -70573,7 +70708,7 @@ class Registry {
70573
70708
  }
70574
70709
  static abaplintVersion() {
70575
70710
  // magic, see build script "version.js"
70576
- return "2.120.71";
70711
+ return "2.120.73";
70577
70712
  }
70578
70713
  getDDICReferences() {
70579
70714
  return this.ddicReferences;
@@ -71921,7 +72056,7 @@ class AlignPseudoComments extends _abap_rule_1.ABAPRule {
71921
72056
  }
71922
72057
  const col = firstCommentToken.getStart().getCol();
71923
72058
  if (previousEnd.getCol() < expectedColumn && col !== expectedColumn) {
71924
- let fix = undefined;
72059
+ let fix;
71925
72060
  if (col < expectedColumn) {
71926
72061
  fix = edit_helper_1.EditHelper.insertAt(file, firstCommentToken.getStart(), " ".repeat(expectedColumn - col));
71927
72062
  }
@@ -72088,7 +72223,7 @@ ENDINTERFACE.`,
72088
72223
  if (f.after.getCol() === column) {
72089
72224
  continue;
72090
72225
  }
72091
- let fix = undefined;
72226
+ let fix;
72092
72227
  if (f.after.getCol() < column) {
72093
72228
  fix = edit_helper_1.EditHelper.insertAt(file, f.after, " ".repeat(column - f.after.getCol()));
72094
72229
  }
@@ -74479,7 +74614,7 @@ ENDCASE.`,
74479
74614
  if (tuples.length === 1) {
74480
74615
  return false;
74481
74616
  }
74482
- let chain = "";
74617
+ let chain;
74483
74618
  if (tuples[0].left === tuples[1].left) {
74484
74619
  chain = tuples[0].left;
74485
74620
  }
@@ -74768,7 +74903,7 @@ class CheckDDIC {
74768
74903
  this.conf = conf;
74769
74904
  }
74770
74905
  run(obj) {
74771
- let found = undefined;
74906
+ let found;
74772
74907
  if (obj instanceof Objects.DataElement
74773
74908
  || obj instanceof Objects.Domain
74774
74909
  || obj instanceof Objects.Table
@@ -75492,7 +75627,6 @@ ENDCLASS.`,
75492
75627
  this.conf = conf;
75493
75628
  }
75494
75629
  runParsed(file, obj) {
75495
- let issues = [];
75496
75630
  if (this.conf.patternKind === undefined) {
75497
75631
  this.conf.patternKind = "required";
75498
75632
  }
@@ -75513,8 +75647,7 @@ ENDCLASS.`,
75513
75647
  attributes = attributes.concat(intfDef.attributes);
75514
75648
  }
75515
75649
  }
75516
- issues = this.checkAttributes(attributes);
75517
- return issues;
75650
+ return this.checkAttributes(attributes);
75518
75651
  }
75519
75652
  checkAttributes(attr) {
75520
75653
  if (attr === undefined) {
@@ -78184,7 +78317,7 @@ Make sure to test the downported code, it might not always be completely correct
78184
78317
  if (found) {
78185
78318
  return found;
78186
78319
  }
78187
- found = this.outlineGetReferenceSimple(high, lowFile);
78320
+ found = this.outlineGetReferenceSimple(high, lowFile, highSyntax);
78188
78321
  if (found) {
78189
78322
  return found;
78190
78323
  }
@@ -78859,7 +78992,17 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
78859
78992
  const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
78860
78993
  return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
78861
78994
  }
78862
- outlineGetReferenceSimple(node, lowFile) {
78995
+ /** the type of a reference to the source: LIKE REF TO it, or REF TO data when its type is generic,
78996
+ * as LIKE REF TO a generically typed field symbol or parameter does not activate */
78997
+ refTypeOf(sourceName, node, lowFile, highSyntax) {
78998
+ var _a;
78999
+ const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
79000
+ if (((_a = spag === null || spag === void 0 ? void 0 : spag.findVariable(sourceName)) === null || _a === void 0 ? void 0 : _a.getType().isGeneric()) === true) {
79001
+ return "TYPE REF TO data";
79002
+ }
79003
+ return "LIKE REF TO " + sourceName;
79004
+ }
79005
+ outlineGetReferenceSimple(node, lowFile, highSyntax) {
78863
79006
  var _a, _b, _c;
78864
79007
  if (!(node.get() instanceof Statements.GetReference)) {
78865
79008
  return undefined;
@@ -78876,7 +79019,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
78876
79019
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
78877
79020
  const firstToken = target.getFirstToken();
78878
79021
  const lastToken = target.getLastToken();
78879
- const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getStart(), `DATA ${targetName} LIKE REF TO ${source.concatTokens()}.\n${indentation}`);
79022
+ const refType = this.refTypeOf(source.concatTokens(), node, lowFile, highSyntax);
79023
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getStart(), `DATA ${targetName} ${refType}.\n${indentation}`);
78880
79024
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), lastToken.getEnd(), targetName);
78881
79025
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
78882
79026
  return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
@@ -78893,7 +79037,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
78893
79037
  if (!(((_a = target === null || target === void 0 ? void 0 : target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.InlineData)) {
78894
79038
  return undefined;
78895
79039
  }
78896
- let type = "";
79040
+ let type;
78897
79041
  const source = node.findFirstExpression(Expressions.Source);
78898
79042
  if (source === undefined) {
78899
79043
  return undefined;
@@ -78983,8 +79127,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
78983
79127
  if (!(node.get() instanceof Statements.Raise)) {
78984
79128
  return undefined;
78985
79129
  }
78986
- let id = undefined;
78987
- let number = undefined;
79130
+ let id;
79131
+ let number;
78988
79132
  let startToken = node.findDirectTokenByText("ID");
78989
79133
  if (startToken) {
78990
79134
  const sources = node.findDirectExpressions(Expressions.Source);
@@ -79142,7 +79286,7 @@ ${indentation}${uniqueName2}->if_t100_message~t100key = ${uniqueName1}.\n`;
79142
79286
  || sourceRef.getChildren().length !== 1) {
79143
79287
  return undefined;
79144
79288
  }
79145
- let code = "";
79289
+ let code;
79146
79290
  if (sourceRef.findFirstExpression(Expressions.TableExpression)) {
79147
79291
  const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
79148
79292
  code = `ASSIGN ${sourceRef.concatTokens()} TO FIELD-SYMBOL(<${uniqueName}>).
@@ -79334,7 +79478,7 @@ LOOP AT ${groupTargetName}tab ${groupTarget}.`;
79334
79478
  || !(tableExpression instanceof nodes_1.ExpressionNode)) {
79335
79479
  return undefined;
79336
79480
  }
79337
- let condition = "";
79481
+ let condition;
79338
79482
  if (tableExpression.getChildren().length === 3) {
79339
79483
  const index = tableExpression.findDirectExpression(Expressions.Source);
79340
79484
  if (index === undefined) {
@@ -79518,7 +79662,7 @@ ${indentation}${uniqueName}`;
79518
79662
  return undefined;
79519
79663
  }
79520
79664
  const op = secondChild.getFirstToken();
79521
- let operator = "";
79665
+ let operator;
79522
79666
  switch (op.getStr()) {
79523
79667
  case "+":
79524
79668
  operator = " + ";
@@ -79560,7 +79704,7 @@ ${indentation}${uniqueName}`;
79560
79704
  || (formatting === null || formatting === void 0 ? void 0 : formatting.startsWith("ALPHA = ")) === false) {
79561
79705
  continue;
79562
79706
  }
79563
- let functionName = "";
79707
+ let functionName;
79564
79708
  switch (formatting) {
79565
79709
  case "ALPHA = IN":
79566
79710
  functionName = "CONVERSION_EXIT_ALPHA_INPUT";
@@ -79856,13 +80000,12 @@ ${indentation} output = ${uniqueName}.\n`;
79856
80000
  const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
79857
80001
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
79858
80002
  let body = "";
79859
- let name = "";
79860
80003
  const switchBody = i.findDirectExpression(Expressions.SwitchBody);
79861
80004
  if (switchBody === undefined) {
79862
80005
  continue;
79863
80006
  }
79864
80007
  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)) || []) {
79865
- name = l.getFirstToken().getStr();
80008
+ const name = l.getFirstToken().getStr();
79866
80009
  body += indentation + `DATA(${name}) = ${(_d = switchBody.findFirstExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens()}.\n`;
79867
80010
  }
79868
80011
  body += `DATA ${uniqueName} ${type}.\n`;
@@ -79920,7 +80063,6 @@ ${indentation} output = ${uniqueName}.\n`;
79920
80063
  const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
79921
80064
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
79922
80065
  let body = "";
79923
- let name = "";
79924
80066
  const reduceBody = i.findDirectExpression(Expressions.ReduceBody);
79925
80067
  if (reduceBody === undefined) {
79926
80068
  continue;
@@ -79931,7 +80073,7 @@ ${indentation} output = ${uniqueName}.\n`;
79931
80073
  }
79932
80074
  let firstName = "";
79933
80075
  for (const init of reduceBody.findDirectExpressions(Expressions.InlineFieldDefinition)) {
79934
- name = init.getFirstToken().getStr();
80076
+ const name = init.getFirstToken().getStr();
79935
80077
  if (firstName === "") {
79936
80078
  firstName = name;
79937
80079
  }
@@ -80163,7 +80305,7 @@ ${indentation} output = ${uniqueName}.\n`;
80163
80305
  after += c.concatTokens();
80164
80306
  }
80165
80307
  }
80166
- let condition = "";
80308
+ let condition;
80167
80309
  if ((tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.getChildren().length) === 3) {
80168
80310
  condition = "INDEX " + ((_d = tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.findDirectExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens());
80169
80311
  }
@@ -80314,7 +80456,7 @@ ${indentation} output = ${uniqueName}.\n`;
80314
80456
  continue;
80315
80457
  }
80316
80458
  const name = nameToken.getStr();
80317
- let type = "";
80459
+ let type;
80318
80460
  if (high.concatTokens().toUpperCase().startsWith("APPEND INITIAL LINE TO ")) {
80319
80461
  type = "LIKE LINE OF " + ((_b = high.findFirstExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
80320
80462
  }
@@ -80680,7 +80822,7 @@ ${indentation} output = ${uniqueName}.\n`;
80680
80822
  }
80681
80823
  return undefined;
80682
80824
  }
80683
- getReference(node, lowFile, _highSyntax) {
80825
+ getReference(node, lowFile, highSyntax) {
80684
80826
  var _a, _b, _c;
80685
80827
  if (!(node.get() instanceof Statements.GetReference)) {
80686
80828
  return undefined;
@@ -80694,7 +80836,7 @@ ${indentation} output = ${uniqueName}.\n`;
80694
80836
  if (targetName === undefined || sourceName === undefined) {
80695
80837
  return undefined;
80696
80838
  }
80697
- const code = `DATA ${targetName} LIKE REF TO ${sourceName}.\n`;
80839
+ const code = `DATA ${targetName} ${this.refTypeOf(sourceName, node, lowFile, highSyntax)}.\n`;
80698
80840
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
80699
80841
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inline.getFirstToken().getStart(), inline.getLastToken().getEnd(), targetName);
80700
80842
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
@@ -80771,18 +80913,30 @@ ${indentation} output = ${uniqueName}.\n`;
80771
80913
  const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
80772
80914
  const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
80773
80915
  const sy = func === "LINE_EXISTS" ? "sy-subrc" : "sy-tabix";
80774
- const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
80775
- indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
80776
- indentation + uniqueName + ` = ${sy}.\n` +
80777
- indentation;
80778
80916
  let insertAt = node.getFirstToken().getStart();
80779
80917
  if (node.get() instanceof statements_1.ElseIf) {
80780
- // assumption: no side effects in IF conditions
80918
+ // assumption: no side effects in IF conditions, except the READ itself, see below
80781
80919
  insertAt = this.findStartOfIf(node, highFile);
80782
80920
  if (insertAt === undefined) {
80783
80921
  continue;
80784
80922
  }
80785
80923
  }
80924
+ // the READ sets sy-subrc and sy-tabix, which the built-in function does not,
80925
+ // keep the values for the code that reads them after the inserted READ
80926
+ const keep = [];
80927
+ const reads = this.readSyFields(insertAt, highFile);
80928
+ for (const field of ["sy-subrc", "sy-tabix"]) {
80929
+ if (reads.has(field)) {
80930
+ keep.push({ field, name: this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax) });
80931
+ }
80932
+ }
80933
+ const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
80934
+ keep.map(k => indentation + `DATA ${k.name} LIKE ${k.field}.\n`).join("") +
80935
+ keep.map(k => indentation + `${k.name} = ${k.field}.\n`).join("") +
80936
+ indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
80937
+ indentation + uniqueName + ` = ${sy}.\n` +
80938
+ keep.map(k => indentation + `${k.field} = ${k.name}.\n`).join("") +
80939
+ indentation;
80786
80940
  const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, insertAt, code);
80787
80941
  const start = expression.getFirstToken().getStart();
80788
80942
  const end = expression.getLastToken().getEnd();
@@ -80793,6 +80947,46 @@ ${indentation} output = ${uniqueName}.\n`;
80793
80947
  }
80794
80948
  return undefined;
80795
80949
  }
80950
+ /** sy-subrc and sy-tabix, when read from the position on, in the procedure around it or the file outside of one;
80951
+ * inside a loop from the start of the outermost loop, as the next pass reads what this one left */
80952
+ readSyFields(position, highFile) {
80953
+ const structure = highFile.getStructure();
80954
+ const contains = (s) => !position.isBefore(s.getFirstToken().getStart())
80955
+ && !position.isAfter(s.getLastToken().getStart());
80956
+ let scope = undefined;
80957
+ for (const s of [Structures.Method, Structures.Form, Structures.FunctionModule]) {
80958
+ for (const p of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(s)) || []) {
80959
+ if (contains(p)) {
80960
+ scope = p;
80961
+ }
80962
+ }
80963
+ }
80964
+ scope = scope || structure;
80965
+ let from = position;
80966
+ for (const s of [Structures.Loop, Structures.Do, Structures.While, Structures.Select]) {
80967
+ for (const l of (scope === null || scope === void 0 ? void 0 : scope.findAllStructuresRecursive(s)) || []) {
80968
+ if (contains(l) && l.getFirstToken().getStart().isBefore(from)) {
80969
+ from = l.getFirstToken().getStart();
80970
+ }
80971
+ }
80972
+ }
80973
+ const ret = new Set();
80974
+ for (const s of (scope === null || scope === void 0 ? void 0 : scope.findAllStatementNodes()) || []) {
80975
+ if (s.getLastToken().getStart().isBefore(from)) {
80976
+ continue;
80977
+ }
80978
+ const tokens = s.getTokens();
80979
+ for (let i = 0; i < tokens.length - 2; i++) {
80980
+ if (tokens[i].getStr().toUpperCase() === "SY" && tokens[i + 1].getStr() === "-") {
80981
+ const field = "sy-" + tokens[i + 2].getStr().toLowerCase();
80982
+ if (field === "sy-subrc" || field === "sy-tabix") {
80983
+ ret.add(field);
80984
+ }
80985
+ }
80986
+ }
80987
+ }
80988
+ return ret;
80989
+ }
80796
80990
  findStartOfIf(node, highFile) {
80797
80991
  const structure = highFile.getStructure();
80798
80992
  for (const c of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(Structures.If)) || []) {
@@ -80805,6 +80999,7 @@ ${indentation} output = ${uniqueName}.\n`;
80805
80999
  return undefined;
80806
81000
  }
80807
81001
  newToCreateObject(low, high, lowFile, highSyntax) {
81002
+ var _a;
80808
81003
  if (!(low.get() instanceof _statement_1.Unknown)) {
80809
81004
  return undefined;
80810
81005
  }
@@ -80820,7 +81015,7 @@ ${indentation} output = ${uniqueName}.\n`;
80820
81015
  && found
80821
81016
  && source.concatTokens() === found.concatTokens()
80822
81017
  && target.findDirectExpression(Expressions.InlineData) === undefined) {
80823
- const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
81018
+ const abap = (_a = this.newDataReference(high, target, found, lowFile, highSyntax)) !== null && _a !== void 0 ? _a : this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
80824
81019
  if (abap !== undefined) {
80825
81020
  fix = edit_helper_1.EditHelper.replaceRange(lowFile, high.getFirstToken().getStart(), high.getLastToken().getEnd(), abap);
80826
81021
  }
@@ -80859,6 +81054,42 @@ ${indentation} output = ${uniqueName}.\n`;
80859
81054
  return undefined;
80860
81055
  }
80861
81056
  }
81057
+ /** NEW into a data reference creates data, CREATE OBJECT cannot: "target = NEW #|type( [value] )"
81058
+ * with a variable typed REF TO a data type becomes CREATE DATA plus the assignment of the value */
81059
+ newDataReference(high, target, found, lowFile, highSyntax) {
81060
+ var _a, _b, _c;
81061
+ if (target.getChildren().length !== 1 || !(((_a = target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.TargetField)) {
81062
+ return undefined;
81063
+ }
81064
+ const children = found.getChildren();
81065
+ const value = found.findDirectExpression(Expressions.Source);
81066
+ // NEW, the type, "(", optionally one value, ")"
81067
+ if (children.length !== 4 + (value ? 1 : 0)) {
81068
+ return undefined;
81069
+ }
81070
+ const name = target.concatTokens();
81071
+ const spag = highSyntax.spaghetti.lookupPosition(high.getFirstToken().getStart(), lowFile.getFilename());
81072
+ const type = (_b = spag === null || spag === void 0 ? void 0 : spag.findVariable(name)) === null || _b === void 0 ? void 0 : _b.getType();
81073
+ if (!(type instanceof basic_1.DataReference)) {
81074
+ return undefined;
81075
+ }
81076
+ const typeName = (_c = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
81077
+ const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
81078
+ let abap = `CREATE DATA ${name}` + (typeName === "#" ? "" : ` TYPE ${typeName}`) + ".";
81079
+ if (value === undefined) {
81080
+ return abap;
81081
+ }
81082
+ else if (type.getType().isGeneric() === false) {
81083
+ return abap + `\n${indentation}${name}->* = ${value.concatTokens()}.`;
81084
+ }
81085
+ // a generic reference cannot be dereferenced as a target below v756
81086
+ const fs = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
81087
+ abap = `FIELD-SYMBOLS ${fs} TYPE any.\n` +
81088
+ indentation + abap + "\n" +
81089
+ indentation + `ASSIGN ${name}->* TO ${fs}.\n` +
81090
+ indentation + `${fs} = ${value.concatTokens()}.`;
81091
+ return abap;
81092
+ }
80862
81093
  newParameters(found, name, highSyntax, lowFile) {
80863
81094
  var _a, _b, _c;
80864
81095
  const typeToken = (_a = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
@@ -81650,6 +81881,8 @@ class EmptyStructureConf extends _basic_rule_config_1.BasicRuleConfig {
81650
81881
  this.try = true;
81651
81882
  /** Checks for empty WHEN blocks */
81652
81883
  this.when = true;
81884
+ /** Checks for empty CATCH blocks, unless the CATCH has pragma ##NO_HANDLER or pseudo comment "#EC NO_HANDLER */
81885
+ this.catch = false;
81653
81886
  // todo, other category containing ELSE
81654
81887
  }
81655
81888
  }
@@ -81762,6 +81995,21 @@ result = xsdbool( sy-subrc = 0 ).`,
81762
81995
  }
81763
81996
  }
81764
81997
  }
81998
+ if (this.getConfig().catch === true) {
81999
+ for (const c of stru.findAllStructuresRecursive(Structures.Catch)) {
82000
+ // a comment in the block does not count, the extended check (SLIN) reports it too
82001
+ if (c.findDirectStructure(Structures.Body) !== undefined) {
82002
+ continue;
82003
+ }
82004
+ const catchStatement = c.getFirstStatement();
82005
+ if (catchStatement === undefined || this.isNoHandler(catchStatement, statements)) {
82006
+ continue;
82007
+ }
82008
+ const token = c.getFirstToken();
82009
+ const issue = issue_1.Issue.atToken(file, token, this.getDescription(c.get().constructor.name), this.getMetadata().key, this.conf.severity);
82010
+ issues.push(issue);
82011
+ }
82012
+ }
81765
82013
  if (this.getConfig().when === true) {
81766
82014
  const tries = stru.findAllStructuresRecursive(Structures.When);
81767
82015
  for (const t of tries) {
@@ -81775,6 +82023,15 @@ result = xsdbool( sy-subrc = 0 ).`,
81775
82023
  }
81776
82024
  return issues;
81777
82025
  }
82026
+ isNoHandler(catchStatement, statements) {
82027
+ if (catchStatement.getPragmas().some(p => p.getStr().toUpperCase() === "##NO_HANDLER")) {
82028
+ return true;
82029
+ }
82030
+ const next = statements[statements.indexOf(catchStatement) + 1];
82031
+ return (next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment
82032
+ && next.getStart().getRow() === catchStatement.getEnd().getRow()
82033
+ && next.concatTokens().toUpperCase().replace(/\s/g, "").includes("\"#ECNO_HANDLER");
82034
+ }
81778
82035
  }
81779
82036
  exports.EmptyStructure = EmptyStructure;
81780
82037
  //# sourceMappingURL=empty_structure.js.map
@@ -83211,7 +83468,7 @@ cl_abap_typedescr=>describe_by_name(
83211
83468
  const methodSource = statNode.findDirectExpression(Expressions.MethodSource);
83212
83469
  let methodSourceStr = methodSource === null || methodSource === void 0 ? void 0 : methodSource.concatTokens();
83213
83470
  const methodBody = statNode.findDirectExpression(Expressions.MethodCallBody);
83214
- let methodBodyStr = "";
83471
+ let methodBodyStr;
83215
83472
  if (methodBody) {
83216
83473
  const methodCallParam = methodBody.findDirectExpression(Expressions.MethodCallParam);
83217
83474
  if (methodCallParam && methodCallParam.getFirstToken().getStr() === "(") {
@@ -83236,6 +83493,102 @@ exports.FunctionalWriting = FunctionalWriting;
83236
83493
 
83237
83494
  /***/ },
83238
83495
 
83496
+ /***/ "../core/build/src/rules/generic_regex.js"
83497
+ /*!************************************************!*\
83498
+ !*** ../core/build/src/rules/generic_regex.js ***!
83499
+ \************************************************/
83500
+ (__unused_webpack_module, exports, __webpack_require__) {
83501
+
83502
+ "use strict";
83503
+
83504
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
83505
+ exports.GenericRegex = exports.GenericRegexConf = void 0;
83506
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
83507
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
83508
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
83509
+ class GenericRegexConf extends _basic_rule_config_1.BasicRuleConfig {
83510
+ constructor() {
83511
+ super(...arguments);
83512
+ /** List of forbidden regular expressions, case insensitive, checked against each line of every file.
83513
+ * Patterns use JavaScript regex syntax without enclosing slashes or flags.
83514
+ * @uniqueItems true
83515
+ */
83516
+ this.regexes = [];
83517
+ }
83518
+ }
83519
+ exports.GenericRegexConf = GenericRegexConf;
83520
+ class GenericRegex {
83521
+ constructor() {
83522
+ this.conf = new GenericRegexConf();
83523
+ this.regexes = [];
83524
+ }
83525
+ getMetadata() {
83526
+ return {
83527
+ key: "generic_regex",
83528
+ title: "Generic regex",
83529
+ shortDescription: "Report an issue for each match of a configured regular expression.",
83530
+ extendedInformation: `Checks each line of every object file, including comments, strings, and XML.
83531
+ Patterns use JavaScript regular expression syntax without enclosing slashes or flags.
83532
+ Matching is case insensitive and does not span multiple lines. Each non-overlapping match is reported.
83533
+ Use the standard exclude configuration to skip files.
83534
+
83535
+ Example configuration: \`{"generic_regex": {"regexes": ["TODO", "BREAK-POINT"]}}\``,
83536
+ tags: [_irule_1.RuleTag.SingleFile],
83537
+ };
83538
+ }
83539
+ getConfig() {
83540
+ return this.conf;
83541
+ }
83542
+ setConfig(conf) {
83543
+ var _a;
83544
+ this.conf = Object.assign(new GenericRegexConf(), conf);
83545
+ this.conf.regexes = (_a = this.conf.regexes) !== null && _a !== void 0 ? _a : [];
83546
+ }
83547
+ initialize(_reg) {
83548
+ this.regexes = this.conf.regexes.map(pattern => {
83549
+ try {
83550
+ return new RegExp(pattern, "gi");
83551
+ }
83552
+ catch (_a) {
83553
+ throw new Error(`generic_regex: Invalid regular expression "${pattern}"`);
83554
+ }
83555
+ });
83556
+ return this;
83557
+ }
83558
+ run(obj) {
83559
+ const issues = [];
83560
+ if (this.regexes.length === 0) {
83561
+ return issues;
83562
+ }
83563
+ for (const file of obj.getFiles()) {
83564
+ const rows = file.getRawRows();
83565
+ for (let row = 0; row < rows.length; row++) {
83566
+ const text = rows[row].replace(/\r$/, "");
83567
+ for (const regex of this.regexes) {
83568
+ regex.lastIndex = 0;
83569
+ for (;;) {
83570
+ const match = regex.exec(text);
83571
+ if (match === null) {
83572
+ break;
83573
+ }
83574
+ const startCol = match.index + 1;
83575
+ const message = `Text matches forbidden regular expression "${regex.source}"`;
83576
+ issues.push(issue_1.Issue.atRowRange(file, row + 1, startCol, startCol + match[0].length, message, this.getMetadata().key, this.conf.severity));
83577
+ if (match[0].length === 0) {
83578
+ regex.lastIndex++;
83579
+ }
83580
+ }
83581
+ }
83582
+ }
83583
+ }
83584
+ return issues;
83585
+ }
83586
+ }
83587
+ exports.GenericRegex = GenericRegex;
83588
+ //# sourceMappingURL=generic_regex.js.map
83589
+
83590
+ /***/ },
83591
+
83239
83592
  /***/ "../core/build/src/rules/global_class.js"
83240
83593
  /*!***********************************************!*\
83241
83594
  !*** ../core/build/src/rules/global_class.js ***!
@@ -85150,6 +85503,7 @@ __exportStar(__webpack_require__(/*! ./fully_type_constants */ "../core/build/sr
85150
85503
  __exportStar(__webpack_require__(/*! ./fully_type_itabs */ "../core/build/src/rules/fully_type_itabs.js"), exports);
85151
85504
  __exportStar(__webpack_require__(/*! ./function_module_recommendations */ "../core/build/src/rules/function_module_recommendations.js"), exports);
85152
85505
  __exportStar(__webpack_require__(/*! ./functional_writing */ "../core/build/src/rules/functional_writing.js"), exports);
85506
+ __exportStar(__webpack_require__(/*! ./generic_regex */ "../core/build/src/rules/generic_regex.js"), exports);
85153
85507
  __exportStar(__webpack_require__(/*! ./global_class */ "../core/build/src/rules/global_class.js"), exports);
85154
85508
  __exportStar(__webpack_require__(/*! ./identical_conditions */ "../core/build/src/rules/identical_conditions.js"), exports);
85155
85509
  __exportStar(__webpack_require__(/*! ./identical_contents */ "../core/build/src/rules/identical_contents.js"), exports);
@@ -86105,7 +86459,7 @@ class KeywordCase extends _abap_rule_1.ABAPRule {
86105
86459
  const firstToken = tokens[0].token;
86106
86460
  const lastToken = tokens[tokens.length - 1].token;
86107
86461
  const firstTokenValue = firstToken.getStr();
86108
- let description = "";
86462
+ let description;
86109
86463
  if (first.keyword === true) {
86110
86464
  description = `Keyword should be ${this.conf.style} case: "${firstTokenValue}"`;
86111
86465
  }
@@ -86630,7 +86984,7 @@ ENDCLASS.`,
86630
86984
  continue;
86631
86985
  }
86632
86986
  const className = classDef.name;
86633
- let expected = "";
86987
+ let expected;
86634
86988
  if (classDef.isForTesting) {
86635
86989
  expected = this.conf.test;
86636
86990
  }
@@ -87296,7 +87650,7 @@ ENDIF.
87296
87650
  issues.push(...this.analyzeCondition(file, cond));
87297
87651
  }
87298
87652
  for (const sub of structure.findAllExpressionsMulti([Expressions.CondSub, Expressions.ComponentCondSub])) {
87299
- let cond = [];
87653
+ let cond;
87300
87654
  if (sub.get() instanceof Expressions.CondSub) {
87301
87655
  cond = sub.findDirectExpressions(Expressions.Cond);
87302
87656
  }
@@ -91334,13 +91688,9 @@ ENDIF.`,
91334
91688
  }
91335
91689
  else if (statement instanceof Statements.ClassDefinitionLoad ||
91336
91690
  statement instanceof Statements.InterfaceLoad) {
91337
- let token = undefined;
91338
- if (statement instanceof Statements.ClassDefinitionLoad) {
91339
- token = statementNode.getChildren()[3].getFirstToken();
91340
- }
91341
- else {
91342
- token = statementNode.getChildren()[2].getFirstToken();
91343
- }
91691
+ const token = statement instanceof Statements.ClassDefinitionLoad
91692
+ ? statementNode.getChildren()[3].getFirstToken()
91693
+ : statementNode.getChildren()[2].getFirstToken();
91344
91694
  let startPosition = token.getStart();
91345
91695
  startPosition = new position_1.Position(startPosition.getRow(), startPosition.getCol() - 1);
91346
91696
  return edit_helper_1.EditHelper.deleteRange(file, startPosition, token.getEnd());
@@ -92137,7 +92487,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
92137
92487
  exports.ParserMissingSpace = exports.ParserMissingSpaceConf = void 0;
92138
92488
  const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
92139
92489
  const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
92140
- const position_1 = __webpack_require__(/*! ../position */ "../core/build/src/position.js");
92141
92490
  const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
92142
92491
  const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "../core/build/src/abap/nodes/index.js");
92143
92492
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
@@ -92170,7 +92519,7 @@ This rule makes sure the spaces are consistently required across the language.`,
92170
92519
  }
92171
92520
  runParsed(file) {
92172
92521
  const issues = [];
92173
- let start = new position_1.Position(0, 0);
92522
+ let start;
92174
92523
  for (const statement of file.getStatements()) {
92175
92524
  const missing = this.missingSpace(statement);
92176
92525
  if (missing) {
@@ -93731,14 +94080,8 @@ From 752 and up`,
93731
94080
  }
93732
94081
  getFix(file, statement, withExporting) {
93733
94082
  const children = statement.getChildren();
93734
- let contentFix = undefined;
93735
- if (withExporting) {
93736
- const fixText = "( " + children[5].concatTokens() + " ).";
93737
- contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
93738
- }
93739
- else {
93740
- contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), "( ).");
93741
- }
94083
+ const fixText = withExporting ? "( " + children[5].concatTokens() + " )." : "( ).";
94084
+ const contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
93742
94085
  const replaceType = edit_helper_1.EditHelper.replaceToken(file, children[2].getFirstToken(), "NEW");
93743
94086
  return edit_helper_1.EditHelper.merge(contentFix, replaceType);
93744
94087
  }
@@ -102165,6 +102508,7 @@ class XMLConsistency {
102165
102508
  * Naming for CLAS and INTF objects
102166
102509
  * QUAN fields in TABL objects have reference table and field values
102167
102510
  * Transparent TABL objects have delivery class and size category set
102511
+ * TABL fields with a built-in type carry the INTTYPE abapGit serializes for it, for the confirmed pairs
102168
102512
  * Lock parameter names in ENQU objects are max 16 characters
102169
102513
  * Texts and translations do not exceed maximum allowed length.`,
102170
102514
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
@@ -102431,6 +102775,12 @@ class XMLConsistency {
102431
102775
  const message = `QUAN field ${field.FIELDNAME} must have REFTABLE and REFFIELD set`;
102432
102776
  issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
102433
102777
  }
102778
+ const expected = field.DATATYPE ? XMLConsistency.intTypes[field.DATATYPE] : undefined;
102779
+ if (expected !== undefined && field.INTTYPE !== undefined && field.INTTYPE !== expected) {
102780
+ const message = `Field ${field.FIELDNAME}: INTTYPE "${field.INTTYPE}" does not match DATATYPE ${field.DATATYPE}, ` +
102781
+ `abapGit serializes "${expected}"`;
102782
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
102783
+ }
102434
102784
  }
102435
102785
  if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
102436
102786
  // Confirmed reserved database field names, see issue #4331, DAY and HOUR reported by activation.
@@ -102454,6 +102804,15 @@ class XMLConsistency {
102454
102804
  }
102455
102805
  }
102456
102806
  exports.XMLConsistency = XMLConsistency;
102807
+ // INTTYPE that abapGit serializes for a built-in DATATYPE, confirmed by exported tables;
102808
+ // a different value activates, but shows as a diff on every pull
102809
+ XMLConsistency.intTypes = {
102810
+ "CHAR": "C", "CLNT": "C", "CUKY": "C", "LANG": "C",
102811
+ "DATS": "D", "TIMS": "T",
102812
+ "INT4": "X", "RAW": "X",
102813
+ "DEC": "P", "CURR": "P",
102814
+ "STRG": "g", "SSTR": "g", "RSTR": "y",
102815
+ };
102457
102816
  //# sourceMappingURL=xml_consistency.js.map
102458
102817
 
102459
102818
  /***/ },
@@ -103076,7 +103435,7 @@ class FormLengthStats {
103076
103435
  return res;
103077
103436
  }
103078
103437
  static findName(stat) {
103079
- let name = "";
103438
+ let name;
103080
103439
  const nameExpr = stat.findFirstExpression(expressions_1.FormName);
103081
103440
  if (nameExpr) {
103082
103441
  name = nameExpr.getFirstToken().getStr();
@@ -103487,7 +103846,7 @@ class MethodLengthStats {
103487
103846
  return res;
103488
103847
  }
103489
103848
  static findName(stat) {
103490
- let name = "";
103849
+ let name;
103491
103850
  const nameExpr = stat.findFirstExpression(expressions_1.MethodName);
103492
103851
  if (nameExpr) {
103493
103852
  name = nameExpr.getFirstToken().getStr();
@@ -105089,7 +105448,7 @@ function loadConfig(filename) {
105089
105448
  // c) specified and found
105090
105449
  // d) specified and not found => use default
105091
105450
  // e) supplied but a directory => use default
105092
- let f = "";
105451
+ let f;
105093
105452
  if (filename === undefined) {
105094
105453
  f = process.cwd() + path.sep + "abaplint.json";
105095
105454
  if (fs.existsSync(f) === false) {
@@ -105232,7 +105591,7 @@ async function run(arg) {
105232
105591
  else {
105233
105592
  process.stderr.write("abaplint " + core_1.Registry.abaplintVersion() + "\n");
105234
105593
  let loaded = [];
105235
- let deps = [];
105594
+ let deps;
105236
105595
  const { config, base } = loadConfig(arg.configFilename);
105237
105596
  outputSyntaxConfig(config);
105238
105597
  try {