@abaplint/cli 2.102.14 → 2.102.16

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 +234 -82
  2. package/package.json +4 -4
package/build/cli.js CHANGED
@@ -5067,7 +5067,6 @@ __exportStar(__webpack_require__(/*! ./component_compare */ "./node_modules/@aba
5067
5067
  __exportStar(__webpack_require__(/*! ./component_cond_sub */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/component_cond_sub.js"), exports);
5068
5068
  __exportStar(__webpack_require__(/*! ./component_cond */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/component_cond.js"), exports);
5069
5069
  __exportStar(__webpack_require__(/*! ./component_name */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/component_name.js"), exports);
5070
- __exportStar(__webpack_require__(/*! ./sql_fields */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_fields.js"), exports);
5071
5070
  __exportStar(__webpack_require__(/*! ./concatenated_constant */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/concatenated_constant.js"), exports);
5072
5071
  __exportStar(__webpack_require__(/*! ./cond_body */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/cond_body.js"), exports);
5073
5072
  __exportStar(__webpack_require__(/*! ./cond_sub */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/cond_sub.js"), exports);
@@ -5192,8 +5191,8 @@ __exportStar(__webpack_require__(/*! ./source_field */ "./node_modules/@abaplint
5192
5191
  __exportStar(__webpack_require__(/*! ./source */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/source.js"), exports);
5193
5192
  __exportStar(__webpack_require__(/*! ./sql_aggregation */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_aggregation.js"), exports);
5194
5193
  __exportStar(__webpack_require__(/*! ./sql_alias_field */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_alias_field.js"), exports);
5195
- __exportStar(__webpack_require__(/*! ./sql_arithmetics */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_arithmetics.js"), exports);
5196
5194
  __exportStar(__webpack_require__(/*! ./sql_arithmetic_operator */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_arithmetic_operator.js"), exports);
5195
+ __exportStar(__webpack_require__(/*! ./sql_arithmetics */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_arithmetics.js"), exports);
5197
5196
  __exportStar(__webpack_require__(/*! ./sql_as_name */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_as_name.js"), exports);
5198
5197
  __exportStar(__webpack_require__(/*! ./sql_case */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_case.js"), exports);
5199
5198
  __exportStar(__webpack_require__(/*! ./sql_cds_parameters */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_cds_parameters.js"), exports);
@@ -5206,6 +5205,7 @@ __exportStar(__webpack_require__(/*! ./sql_field_list_loop */ "./node_modules/@a
5206
5205
  __exportStar(__webpack_require__(/*! ./sql_field_list */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_field_list.js"), exports);
5207
5206
  __exportStar(__webpack_require__(/*! ./sql_field_name */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_field_name.js"), exports);
5208
5207
  __exportStar(__webpack_require__(/*! ./sql_field */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_field.js"), exports);
5208
+ __exportStar(__webpack_require__(/*! ./sql_fields */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_fields.js"), exports);
5209
5209
  __exportStar(__webpack_require__(/*! ./sql_for_all_entries */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_for_all_entries.js"), exports);
5210
5210
  __exportStar(__webpack_require__(/*! ./sql_from_source */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_from_source.js"), exports);
5211
5211
  __exportStar(__webpack_require__(/*! ./sql_from */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_from.js"), exports);
@@ -5238,6 +5238,7 @@ __exportStar(__webpack_require__(/*! ./text_element_key */ "./node_modules/@abap
5238
5238
  __exportStar(__webpack_require__(/*! ./text_element_string */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/text_element_string.js"), exports);
5239
5239
  __exportStar(__webpack_require__(/*! ./text_element */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/text_element.js"), exports);
5240
5240
  __exportStar(__webpack_require__(/*! ./throw */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/throw.js"), exports);
5241
+ __exportStar(__webpack_require__(/*! ./transporting_fields */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/transporting_fields.js"), exports);
5241
5242
  __exportStar(__webpack_require__(/*! ./type_name_or_infer */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/type_name_or_infer.js"), exports);
5242
5243
  __exportStar(__webpack_require__(/*! ./type_name */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/type_name.js"), exports);
5243
5244
  __exportStar(__webpack_require__(/*! ./type_param */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/type_param.js"), exports);
@@ -8333,6 +8334,30 @@ exports.Throw = Throw;
8333
8334
 
8334
8335
  /***/ }),
8335
8336
 
8337
+ /***/ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/transporting_fields.js":
8338
+ /*!****************************************************************************************************!*\
8339
+ !*** ./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/transporting_fields.js ***!
8340
+ \****************************************************************************************************/
8341
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8342
+
8343
+ "use strict";
8344
+
8345
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
8346
+ exports.TransportingFields = void 0;
8347
+ const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
8348
+ const dynamic_1 = __webpack_require__(/*! ./dynamic */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/dynamic.js");
8349
+ const field_sub_1 = __webpack_require__(/*! ./field_sub */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/field_sub.js");
8350
+ class TransportingFields extends combi_1.Expression {
8351
+ getRunnable() {
8352
+ const fields = (0, combi_1.plus)((0, combi_1.alt)((0, combi_1.seq)("INTO", (0, combi_1.failStar)()), field_sub_1.FieldSub));
8353
+ return (0, combi_1.altPrio)(dynamic_1.Dynamic, fields);
8354
+ }
8355
+ }
8356
+ exports.TransportingFields = TransportingFields;
8357
+ //# sourceMappingURL=transporting_fields.js.map
8358
+
8359
+ /***/ }),
8360
+
8336
8361
  /***/ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/type.js":
8337
8362
  /*!*************************************************************************************!*\
8338
8363
  !*** ./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/type.js ***!
@@ -14695,6 +14720,7 @@ exports.ReadTable = void 0;
14695
14720
  const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/core/build/src/abap/2_statements/combi.js");
14696
14721
  const expressions_1 = __webpack_require__(/*! ../expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
14697
14722
  const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
14723
+ const transporting_fields_1 = __webpack_require__(/*! ../expressions/transporting_fields */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/transporting_fields.js");
14698
14724
  class ReadTable {
14699
14725
  getMatcher() {
14700
14726
  const comparing = (0, combi_1.seq)("COMPARING", (0, combi_1.alt)((0, combi_1.plus)(expressions_1.FieldSub), expressions_1.Dynamic));
@@ -14703,8 +14729,7 @@ class ReadTable {
14703
14729
  const key = (0, combi_1.seq)((0, combi_1.altPrio)("WITH KEY", "WITH TABLE KEY"), (0, combi_1.alt)(expressions_1.ComponentCompareSimple, components, (0, combi_1.seq)((0, combi_1.optPrio)("="), expressions_1.Source)));
14704
14730
  const using = (0, combi_1.seq)("USING KEY", (0, combi_1.alt)(expressions_1.Field, expressions_1.Dynamic));
14705
14731
  const from = (0, combi_1.seq)("FROM", expressions_1.Source);
14706
- const fields = (0, combi_1.plus)((0, combi_1.alt)((0, combi_1.seq)("INTO", (0, combi_1.failStar)()), expressions_1.FieldSub));
14707
- const perm = (0, combi_1.per)((0, combi_1.alt)(index, key, from), expressions_1.ReadTableTarget, using, comparing, "CASTING", "TRANSPORTING ALL FIELDS", (0, combi_1.seq)("TRANSPORTING", (0, combi_1.altPrio)(expressions_1.Dynamic, fields)), "BINARY SEARCH");
14732
+ const perm = (0, combi_1.per)((0, combi_1.alt)(index, key, from), expressions_1.ReadTableTarget, using, comparing, "CASTING", "TRANSPORTING ALL FIELDS", (0, combi_1.seq)("TRANSPORTING", transporting_fields_1.TransportingFields), "BINARY SEARCH");
14708
14733
  return (0, combi_1.seq)("READ TABLE", (0, combi_1.alt)(expressions_1.SimpleSource2, (0, combi_1.ver)(version_1.Version.v740sp02, expressions_1.Source)), (0, combi_1.opt)(perm));
14709
14734
  }
14710
14735
  }
@@ -21424,6 +21449,7 @@ var ScopeType;
21424
21449
  ScopeType["FunctionModule"] = "function";
21425
21450
  ScopeType["Method"] = "method";
21426
21451
  ScopeType["MethodInstance"] = "method_instance";
21452
+ ScopeType["MethodDefinition"] = "method_definition";
21427
21453
  ScopeType["For"] = "for";
21428
21454
  ScopeType["Let"] = "let";
21429
21455
  ScopeType["OpenSQL"] = "open_sql";
@@ -24404,22 +24430,28 @@ const Expressions = __webpack_require__(/*! ../../2_statements/expressions */ ".
24404
24430
  const source_1 = __webpack_require__(/*! ./source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
24405
24431
  class MessageSource {
24406
24432
  runSyntax(node, scope, filename) {
24407
- var _a, _b, _c, _d;
24433
+ var _a, _b, _c, _d, _e;
24408
24434
  for (const f of node.findDirectExpressions(Expressions.Source)) {
24409
24435
  new source_1.Source().runSyntax(f, scope, filename);
24410
24436
  }
24411
24437
  if (node.getFirstToken().getStr().toUpperCase() === "ID") {
24412
24438
  const id = (_a = node.findExpressionAfterToken("ID")) === null || _a === void 0 ? void 0 : _a.concatTokens();
24413
- const number = (_b = node.findDirectExpression(Expressions.MessageNumber)) === null || _b === void 0 ? void 0 : _b.concatTokens();
24439
+ let number = (_b = node.findDirectExpression(Expressions.MessageNumber)) === null || _b === void 0 ? void 0 : _b.concatTokens();
24440
+ if (number === undefined) {
24441
+ const num = (_c = node.findExpressionAfterToken("NUMBER")) === null || _c === void 0 ? void 0 : _c.concatTokens();
24442
+ if (num === null || num === void 0 ? void 0 : num.startsWith("'")) {
24443
+ number = num.substring(1, num.length - 1).toUpperCase();
24444
+ }
24445
+ }
24414
24446
  if ((id === null || id === void 0 ? void 0 : id.startsWith("'")) && number) {
24415
24447
  const messageClass = id.substring(1, id.length - 1).toUpperCase();
24416
24448
  scope.getMSAGReferences().addUsing(filename, node.getFirstToken(), messageClass, number);
24417
24449
  }
24418
24450
  }
24419
24451
  else {
24420
- const typeAndNumber = (_c = node.findDirectExpression(Expressions.MessageTypeAndNumber)) === null || _c === void 0 ? void 0 : _c.concatTokens();
24452
+ const typeAndNumber = (_d = node.findDirectExpression(Expressions.MessageTypeAndNumber)) === null || _d === void 0 ? void 0 : _d.concatTokens();
24421
24453
  const messageNumber = typeAndNumber === null || typeAndNumber === void 0 ? void 0 : typeAndNumber.substring(1);
24422
- const messageClass = (_d = node.findDirectExpression(Expressions.MessageClass)) === null || _d === void 0 ? void 0 : _d.concatTokens().toUpperCase();
24454
+ const messageClass = (_e = node.findDirectExpression(Expressions.MessageClass)) === null || _e === void 0 ? void 0 : _e.concatTokens().toUpperCase();
24423
24455
  if (messageNumber && messageClass) {
24424
24456
  scope.getMSAGReferences().addUsing(filename, node.getFirstToken(), messageClass, messageNumber);
24425
24457
  }
@@ -29101,14 +29133,18 @@ class IncludeType {
29101
29133
  let ityp = new basic_types_1.BasicTypes(filename, scope).parseType(iname);
29102
29134
  const as = (_a = node.findExpressionAfterToken("AS")) === null || _a === void 0 ? void 0 : _a.concatTokens();
29103
29135
  if (as && ityp instanceof basic_1.StructureType) {
29104
- ityp = new basic_1.StructureType(ityp.getComponents().concat([{ name: as, type: ityp }]));
29136
+ ityp = new basic_1.StructureType(ityp.getComponents().concat([{
29137
+ name: as,
29138
+ type: ityp,
29139
+ asInclude: true,
29140
+ }]));
29105
29141
  }
29106
29142
  const suffix = (_b = node.findExpressionAfterToken("SUFFIX")) === null || _b === void 0 ? void 0 : _b.concatTokens();
29107
29143
  if (suffix && ityp instanceof basic_1.StructureType) {
29108
29144
  const components = [];
29109
29145
  for (const c of ityp.getComponents()) {
29110
29146
  if (c.name === as) {
29111
- components.push(c);
29147
+ components.push(Object.assign(Object.assign({}, c), { suffix: suffix, asInclude: c.asInclude }));
29112
29148
  continue;
29113
29149
  }
29114
29150
  components.push({
@@ -29583,11 +29619,12 @@ class MethodImplementation {
29583
29619
  if (methodDefinition === undefined) {
29584
29620
  throw new Error("Method definition \"" + methodName + "\" not found");
29585
29621
  }
29622
+ const start = node.getFirstToken().getStart();
29586
29623
  if (methodDefinition.isStatic() === false) {
29587
- scope.push(_scope_type_1.ScopeType.MethodInstance, methodName, node.getFirstToken().getStart(), filename);
29624
+ scope.push(_scope_type_1.ScopeType.MethodInstance, methodName, start, filename);
29588
29625
  scope.addList(classDefinition.getAttributes().getInstance());
29589
29626
  }
29590
- scope.push(_scope_type_1.ScopeType.Method, methodName, node.getFirstToken().getStart(), filename);
29627
+ scope.push(_scope_type_1.ScopeType.Method, methodName, start, filename);
29591
29628
  scope.addReference(methodToken, methodDefinition, _reference_1.ReferenceType.MethodImplementationReference, filename);
29592
29629
  scope.addList(methodDefinition.getParameters().getAll());
29593
29630
  for (const i of helper.findInterfaces(classDefinition)) {
@@ -30050,7 +30087,7 @@ const method_parameters_1 = __webpack_require__(/*! ../expressions/method_parame
30050
30087
  class Raise {
30051
30088
  runSyntax(node, scope, filename) {
30052
30089
  // todo
30053
- var _a, _b, _c, _d, _e;
30090
+ var _a, _b, _c, _d, _e, _f;
30054
30091
  const helper = new _object_oriented_1.ObjectOriented(scope);
30055
30092
  let method;
30056
30093
  const classTok = (_a = node.findDirectExpression(Expressions.ClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
@@ -30109,7 +30146,13 @@ class Raise {
30109
30146
  new message_source_1.MessageSource().runSyntax(s, scope, filename);
30110
30147
  }
30111
30148
  const id = (_d = node.findExpressionAfterToken("ID")) === null || _d === void 0 ? void 0 : _d.concatTokens();
30112
- const number = (_e = node.findDirectExpression(Expressions.MessageNumber)) === null || _e === void 0 ? void 0 : _e.concatTokens();
30149
+ let number = (_e = node.findDirectExpression(Expressions.MessageNumber)) === null || _e === void 0 ? void 0 : _e.concatTokens();
30150
+ if (number === undefined) {
30151
+ const num = (_f = node.findExpressionAfterToken("NUMBER")) === null || _f === void 0 ? void 0 : _f.concatTokens();
30152
+ if (num === null || num === void 0 ? void 0 : num.startsWith("'")) {
30153
+ number = num.substring(1, num.length - 1).toUpperCase();
30154
+ }
30155
+ }
30113
30156
  if ((id === null || id === void 0 ? void 0 : id.startsWith("'")) && number) {
30114
30157
  const messageClass = id.substring(1, id.length - 1).toUpperCase();
30115
30158
  scope.getMSAGReferences().addUsing(filename, node.getFirstToken(), messageClass, number);
@@ -30327,29 +30370,19 @@ class ReadTable {
30327
30370
  rowType = new basic_1.DataReference(rowType);
30328
30371
  }
30329
30372
  const inline = target.findFirstExpression(Expressions.InlineData);
30373
+ const fst = target.findDirectExpression(Expressions.FSTarget);
30374
+ const t = target.findFirstExpression(Expressions.Target);
30330
30375
  if (inline) {
30331
30376
  new inline_data_1.InlineData().runSyntax(inline, scope, filename, rowType);
30332
- return;
30333
30377
  }
30334
- const fst = target.findDirectExpression(Expressions.FSTarget);
30335
- if (fst) {
30378
+ else if (fst) {
30336
30379
  new fstarget_1.FSTarget().runSyntax(fst, scope, filename, rowType);
30337
- return;
30338
30380
  }
30339
- /*
30340
- const inlinefs = target.findFirstExpression(Expressions.InlineFS);
30341
- if (inlinefs) {
30342
- new InlineFS().runSyntax(inlinefs, scope, filename, sourceType);
30343
- return;
30344
- }
30345
- */
30346
- const t = target.findFirstExpression(Expressions.Target);
30347
- if (t) {
30381
+ else if (t) {
30348
30382
  const targetType = new target_1.Target().runSyntax(t, scope, filename);
30349
30383
  if (new _type_utils_1.TypeUtils(scope).isAssignable(rowType, targetType) === false) {
30350
30384
  throw new Error("Incompatible types");
30351
30385
  }
30352
- return;
30353
30386
  }
30354
30387
  }
30355
30388
  if (target === undefined && concat.includes(" TRANSPORTING NO FIELDS ") === false) {
@@ -30358,6 +30391,25 @@ class ReadTable {
30358
30391
  throw new Error("READ TABLE, define INTO or TRANSPORTING NO FIELDS");
30359
30392
  }
30360
30393
  }
30394
+ const transporting = node.findDirectExpression(Expressions.TransportingFields);
30395
+ if (transporting
30396
+ && !(rowType instanceof basic_1.VoidType)
30397
+ && !(rowType instanceof basic_1.UnknownType)
30398
+ && !(rowType instanceof basic_1.AnyType)) {
30399
+ if (!(rowType instanceof basic_1.StructureType)) {
30400
+ throw new Error("READ TABLE, source not structured");
30401
+ }
30402
+ for (const t of (transporting === null || transporting === void 0 ? void 0 : transporting.findDirectExpressions(Expressions.FieldSub)) || []) {
30403
+ const field = t.concatTokens();
30404
+ if (field.includes("-")) {
30405
+ // todo
30406
+ continue;
30407
+ }
30408
+ if (rowType.getComponentByName(field) === undefined) {
30409
+ throw new Error("READ TABLE, field " + field + " not found in source");
30410
+ }
30411
+ }
30412
+ }
30361
30413
  }
30362
30414
  }
30363
30415
  exports.ReadTable = ReadTable;
@@ -36787,6 +36839,7 @@ const method_param_1 = __webpack_require__(/*! ../5_syntax/expressions/method_pa
36787
36839
  const _object_oriented_1 = __webpack_require__(/*! ../5_syntax/_object_oriented */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_object_oriented.js");
36788
36840
  const _reference_1 = __webpack_require__(/*! ../5_syntax/_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
36789
36841
  const identifier_1 = __webpack_require__(/*! ../1_lexer/tokens/identifier */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/identifier.js");
36842
+ const _scope_type_1 = __webpack_require__(/*! ../5_syntax/_scope_type */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_scope_type.js");
36790
36843
  // todo:
36791
36844
  // this.exceptions = [];
36792
36845
  // also consider RAISING vs EXCEPTIONS
@@ -36804,7 +36857,11 @@ class MethodParameters {
36804
36857
  this.preferred = undefined;
36805
36858
  this.exceptions = [];
36806
36859
  this.filename = filename;
36807
- this.parse(node, scope, filename);
36860
+ // need the scope for LIKE typing inside method parameters
36861
+ const parentName = scope.getName();
36862
+ scope.push(_scope_type_1.ScopeType.MethodDefinition, "method definition", node.getStart(), filename);
36863
+ this.parse(node, scope, filename, parentName);
36864
+ scope.pop(node.getEnd());
36808
36865
  }
36809
36866
  getFilename() {
36810
36867
  return this.filename;
@@ -36879,7 +36936,7 @@ class MethodParameters {
36879
36936
  return this.defaults[parameter.toUpperCase()];
36880
36937
  }
36881
36938
  ///////////////////
36882
- parse(node, scope, filename) {
36939
+ parse(node, scope, filename, parentName) {
36883
36940
  var _a, _b;
36884
36941
  const handler = node.findFirstExpression(Expressions.EventHandler);
36885
36942
  if (handler) {
@@ -36939,9 +36996,9 @@ class MethodParameters {
36939
36996
  if (returning) {
36940
36997
  this.returning = new method_def_returning_1.MethodDefReturning().runSyntax(returning, scope, this.filename, ["returning" /* IdentifierMeta.MethodReturning */]);
36941
36998
  }
36942
- this.workaroundRAP(node, scope, filename);
36999
+ this.workaroundRAP(node, scope, filename, parentName);
36943
37000
  }
36944
- workaroundRAP(node, scope, filename) {
37001
+ workaroundRAP(node, _scope, filename, parentName) {
36945
37002
  const resultName = node.findExpressionAfterToken("RESULT");
36946
37003
  const isRap = node.findExpressionAfterToken("IMPORTING");
36947
37004
  if (isRap) {
@@ -36966,7 +37023,7 @@ class MethodParameters {
36966
37023
  this.importing.push(new _typed_identifier_1.TypedIdentifier(token, filename, new basic_1.VoidType("RapMethodParameter"), ["exporting" /* IdentifierMeta.MethodExporting */]));
36967
37024
  }
36968
37025
  // its some kind of magic
36969
- if (scope.getName().toUpperCase() === "CL_ABAP_BEHAVIOR_SAVER") {
37026
+ if (parentName.toUpperCase() === "CL_ABAP_BEHAVIOR_SAVER") {
36970
37027
  const tempChanging = this.changing.map(c => new _typed_identifier_1.TypedIdentifier(c.getToken(), filename, new basic_1.VoidType("RapMethodParameter"), c.getMeta()));
36971
37028
  while (this.changing.length > 0) {
36972
37029
  this.changing.shift();
@@ -36993,7 +37050,9 @@ class MethodParameters {
36993
37050
  else if (meta.includes("importing" /* IdentifierMeta.MethodImporting */)) {
36994
37051
  extraMeta.push("read_only" /* IdentifierMeta.ReadOnly */);
36995
37052
  }
36996
- target.push(new method_param_1.MethodParam().runSyntax(p, scope, this.filename, [...meta, ...extraMeta]));
37053
+ const id = new method_param_1.MethodParam().runSyntax(p, scope, this.filename, [...meta, ...extraMeta]);
37054
+ scope.addIdentifier(id);
37055
+ target.push(id);
36997
37056
  if (opt.getLastToken().getStr().toUpperCase() === "OPTIONAL") {
36998
37057
  const name = target[target.length - 1].getName().toUpperCase();
36999
37058
  this.optional.push(name);
@@ -39938,7 +39997,7 @@ class LSPLookup {
39938
39997
  const hover = "Type Definition, " + cursor.token.getStr() + "\n\n" + this.dumpType(type);
39939
39998
  return { hover, definition: found, definitionId: type, scope: bottomScope };
39940
39999
  }
39941
- const method = this.findMethodDefinition(cursor, bottomScope);
40000
+ const method = this.findMethodDefinition(cursor, bottomScope.getParent());
39942
40001
  if (method !== undefined && method.getStart().equals(cursor.token.getStart())) {
39943
40002
  const found = _lsp_utils_1.LSPUtils.identiferToLocation(method);
39944
40003
  const hover = "Method Definition \"" + method.getName() + "\"";
@@ -40155,6 +40214,9 @@ class LSPLookup {
40155
40214
  }
40156
40215
  static findMethodDefinition(found, scope) {
40157
40216
  var _a, _b, _c, _d;
40217
+ if (scope === undefined) {
40218
+ return undefined;
40219
+ }
40158
40220
  if (scope.getIdentifier().stype !== _scope_type_1.ScopeType.ClassDefinition
40159
40221
  || !(found.snode.get() instanceof Statements.MethodDef)) {
40160
40222
  return undefined;
@@ -41844,6 +41906,9 @@ class MSAGReferences {
41844
41906
  this.filenameIndex = {};
41845
41907
  }
41846
41908
  addUsing(filename, token, messageClass, number) {
41909
+ if (number.length !== 3) {
41910
+ return;
41911
+ }
41847
41912
  if (this.filenameIndex[filename] === undefined) {
41848
41913
  this.filenameIndex[filename] = [];
41849
41914
  }
@@ -45484,6 +45549,7 @@ class MessageClass extends _abstract_object_1.AbstractObject {
45484
45549
  return "MSAG";
45485
45550
  }
45486
45551
  getDescription() {
45552
+ this.parseXML();
45487
45553
  // todo
45488
45554
  return undefined;
45489
45555
  }
@@ -45503,6 +45569,7 @@ class MessageClass extends _abstract_object_1.AbstractObject {
45503
45569
  return msg ? msg : [];
45504
45570
  }
45505
45571
  getByNumber(num) {
45572
+ this.parseXML();
45506
45573
  // todo, optimize performance,
45507
45574
  for (const message of this.getMessages()) {
45508
45575
  if (message.getNumber() === num) {
@@ -48557,7 +48624,7 @@ class Registry {
48557
48624
  }
48558
48625
  static abaplintVersion() {
48559
48626
  // magic, see build script "version.sh"
48560
- return "2.102.14";
48627
+ return "2.102.16";
48561
48628
  }
48562
48629
  getDDICReferences() {
48563
48630
  return this.ddicReferences;
@@ -57285,6 +57352,7 @@ class FunctionModuleRecommendationsConf extends _basic_rule_config_1.BasicRuleCo
57285
57352
  { name: "POPUP_TO_CONFIRM_STEP", replace: "use POPUP_TO_CONFIRM" },
57286
57353
  { name: "POPUP_TO_DECIDE", replace: "use POPUP_TO_CONFIRM" },
57287
57354
  { name: "POPUP_TO_GET_VALUE", replace: "use POPUP_GET_VALUES" },
57355
+ { name: "QF05_RANDOM_INTEGER", replace: "use CL_ABAP_RANDOM_INT" },
57288
57356
  { name: "REUSE_ALV_GRID_DISPLAY", replace: "use CL_SALV_TABLE=>FACTORY or CL_GUI_ALV_GRID" },
57289
57357
  { name: "ROUND", replace: "use built in function: round()" },
57290
57358
  { name: "SAPGUI_PROGRESS_INDICATOR", replace: "use CL_PROGRESS_INDICATOR" },
@@ -60556,17 +60624,23 @@ exports.MaxOneStatement = MaxOneStatement;
60556
60624
  Object.defineProperty(exports, "__esModule", ({ value: true }));
60557
60625
  exports.MessageExistsRule = exports.MessageExistsConf = void 0;
60558
60626
  const Expressions = __webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
60627
+ const Statements = __webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
60559
60628
  const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
60560
- const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
60561
60629
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
60562
60630
  const ddic_1 = __webpack_require__(/*! ../ddic */ "./node_modules/@abaplint/core/build/src/ddic.js");
60563
60631
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
60632
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
60633
+ const _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ "./node_modules/@abaplint/core/build/src/objects/_abap_object.js");
60634
+ const syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js");
60564
60635
  class MessageExistsConf extends _basic_rule_config_1.BasicRuleConfig {
60636
+ constructor() {
60637
+ super(...arguments);
60638
+ this.checkPlaceholders = true;
60639
+ }
60565
60640
  }
60566
60641
  exports.MessageExistsConf = MessageExistsConf;
60567
- class MessageExistsRule extends _abap_rule_1.ABAPRule {
60642
+ class MessageExistsRule {
60568
60643
  constructor() {
60569
- super(...arguments);
60570
60644
  this.conf = new MessageExistsConf();
60571
60645
  }
60572
60646
  getMetadata() {
@@ -60583,58 +60657,116 @@ class MessageExistsRule extends _abap_rule_1.ABAPRule {
60583
60657
  setConfig(conf) {
60584
60658
  this.conf = conf;
60585
60659
  }
60586
- runParsed(file) {
60660
+ initialize(reg) {
60661
+ this.msagReferences = reg.getMSAGReferences();
60662
+ this.reg = reg;
60663
+ // the SyntaxLogic builds the references
60664
+ for (const obj of reg.getObjects()) {
60665
+ if (obj instanceof _abap_object_1.ABAPObject) {
60666
+ new syntax_1.SyntaxLogic(reg, obj).run();
60667
+ }
60668
+ }
60669
+ return this;
60670
+ }
60671
+ run(obj) {
60587
60672
  const issues = [];
60588
- const struc = file.getStructure();
60589
- if (struc === undefined) {
60590
- return [];
60673
+ if (obj instanceof _abap_object_1.ABAPObject) {
60674
+ for (const file of obj.getABAPFiles()) {
60675
+ const struc = file.getStructure();
60676
+ if (struc === undefined) {
60677
+ return [];
60678
+ }
60679
+ issues.push(...this.checkReportStatement(file));
60680
+ issues.push(...this.checkSource(file));
60681
+ }
60591
60682
  }
60592
- const expressions = struc.findAllExpressionsMulti([Expressions.MessageClass, Expressions.MessageSource]);
60593
- for (const node of expressions) {
60594
- if (node.get() instanceof Expressions.MessageClass) {
60595
- const token = node.getFirstToken();
60596
- const name = token.getStr();
60597
- if (this.reg.getObject("MSAG", name) === undefined
60598
- && new ddic_1.DDIC(this.reg).inErrorNamespace(name) === true) {
60599
- const message = "Message class \"" + name + "\" not found";
60600
- const issue = issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity);
60683
+ return issues;
60684
+ }
60685
+ ////////////////////////////////
60686
+ checkReportStatement(file) {
60687
+ const issues = [];
60688
+ for (const statement of file.getStatements()) {
60689
+ if (!(statement.get() instanceof Statements.Report)) {
60690
+ continue;
60691
+ }
60692
+ const expression = statement.findFirstExpression(Expressions.MessageClass);
60693
+ if (expression) {
60694
+ const issue = this.checkClass(expression, file);
60695
+ if (issue) {
60601
60696
  issues.push(issue);
60602
60697
  }
60603
60698
  }
60604
60699
  }
60605
- for (const node of expressions) {
60606
- if (node.get() instanceof Expressions.MessageSource) {
60607
- const clas = node.findFirstExpression(Expressions.MessageClass);
60608
- if (clas === undefined) {
60609
- // todo, handle case where message class is defined on header level instead of in the statement
60610
- continue;
60611
- }
60612
- const token = clas.getFirstToken();
60613
- const name = token.getStr();
60614
- const msag = this.reg.getObject("MSAG", name);
60615
- if (msag === undefined) {
60616
- if (new ddic_1.DDIC(this.reg).inErrorNamespace(name) === true) {
60617
- const message = "Message class \"" + token.getStr() + "\" not found";
60618
- const issue = issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity);
60619
- issues.push(issue);
60700
+ return issues;
60701
+ }
60702
+ checkClass(node, file) {
60703
+ const token = node.getFirstToken();
60704
+ const name = token.getStr();
60705
+ if (this.reg.getObject("MSAG", name) === undefined
60706
+ && new ddic_1.DDIC(this.reg).inErrorNamespace(name) === true) {
60707
+ const message = "Message class \"" + name + "\" not found";
60708
+ return issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity);
60709
+ }
60710
+ return undefined;
60711
+ }
60712
+ checkSource(file) {
60713
+ const issues = [];
60714
+ const references = this.msagReferences.listByFilename(file.getFilename());
60715
+ for (const statement of file.getStatements()) {
60716
+ if (statement.get() instanceof Statements.Raise || statement.get() instanceof Statements.Message) {
60717
+ for (const ref of references) {
60718
+ // always max one message reference per statement? chained statements?
60719
+ if (ref.token.getStart().isBetween(statement.getStart(), statement.getEnd())) {
60720
+ const msag = this.reg.getObject("MSAG", ref.messageClass);
60721
+ if (msag === undefined) {
60722
+ if (new ddic_1.DDIC(this.reg).inErrorNamespace(ref.messageClass) === true) {
60723
+ const message = "Message class \"" + ref.token.getStr() + "\" not found";
60724
+ issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity));
60725
+ }
60726
+ continue;
60727
+ }
60728
+ const text = msag.getByNumber(ref.number);
60729
+ if (text === undefined) {
60730
+ const message = "Message number \"" + ref.number + "\" not found in class \"" + ref.messageClass + "\"";
60731
+ issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity));
60732
+ continue;
60733
+ }
60734
+ if (this.getConfig().checkPlaceholders === true) {
60735
+ const count = this.countWith(statement);
60736
+ const textCount = text.getPlaceholderCount();
60737
+ if (count !== textCount) {
60738
+ const message = `Message ${ref.number}, expected ${textCount} WITH parameters`;
60739
+ issues.push(issue_1.Issue.atToken(file, ref.token, message, this.getMetadata().key, this.conf.severity));
60740
+ }
60741
+ }
60620
60742
  }
60621
- continue;
60622
60743
  }
60623
- const typeNumber = node.findFirstExpression(Expressions.MessageTypeAndNumber);
60624
- if (typeNumber === undefined) {
60625
- continue;
60744
+ }
60745
+ }
60746
+ return issues;
60747
+ }
60748
+ countWith(statement) {
60749
+ const raiseWith = statement.findDirectExpression(Expressions.RaiseWith);
60750
+ if (raiseWith) {
60751
+ return raiseWith.getChildren().length - 1;
60752
+ }
60753
+ let count = 0;
60754
+ let afterWith = false;
60755
+ for (const expression of statement.getChildren()) {
60756
+ if (expression instanceof nodes_1.TokenNode && expression.concatTokens().toUpperCase() === "WITH") {
60757
+ afterWith = true;
60758
+ continue;
60759
+ }
60760
+ if (afterWith === true) {
60761
+ if (expression instanceof nodes_1.ExpressionNode) {
60762
+ count++;
60626
60763
  }
60627
- const numberToken = typeNumber.getFirstToken();
60628
- const num = numberToken.getStr().substr(1);
60629
- if (msag.getByNumber(num) === undefined) {
60630
- const message = "Message number \"" + num + "\" not found in class \"" + name + "\"";
60631
- const issue = issue_1.Issue.atToken(file, numberToken, message, this.getMetadata().key, this.conf.severity);
60632
- issues.push(issue);
60764
+ else {
60765
+ break;
60633
60766
  }
60634
60767
  }
60635
60768
  }
60636
- // todo, check number of placeholders in message vs code matches
60637
- return issues;
60769
+ return count;
60638
60770
  }
60639
60771
  }
60640
60772
  exports.MessageExistsRule = MessageExistsRule;
@@ -63224,15 +63356,21 @@ This rule makes sure the spaces are consistently required across the language.`,
63224
63356
  return issues;
63225
63357
  }
63226
63358
  missingSpace(statement) {
63227
- const found = statement.findAllExpressionsMulti([Expressions.CondSub, Expressions.SQLCond,
63228
- Expressions.ValueBodyLine, Expressions.NewObject, Expressions.Cond,
63229
- Expressions.ComponentCond, Expressions.ComponentCondSub, Expressions.MethodCallParam], true);
63359
+ const found = statement.findAllExpressionsMulti([
63360
+ Expressions.CondSub, Expressions.SQLCond, Expressions.ValueBodyLine,
63361
+ Expressions.NewObject, Expressions.Cond, Expressions.ComponentCond,
63362
+ Expressions.Source,
63363
+ Expressions.ComponentCondSub, Expressions.MethodCallParam
63364
+ ], true);
63230
63365
  let pos = undefined;
63231
63366
  for (const f of found) {
63232
63367
  const type = f.get();
63233
63368
  if (type instanceof Expressions.Cond) {
63234
63369
  pos = this.checkCond(f);
63235
63370
  }
63371
+ else if (type instanceof Expressions.Source) {
63372
+ pos = this.checkSource(f);
63373
+ }
63236
63374
  else if (type instanceof Expressions.CondSub) {
63237
63375
  pos = this.checkCondSub(f);
63238
63376
  }
@@ -63385,6 +63523,20 @@ This rule makes sure the spaces are consistently required across the language.`,
63385
63523
  }
63386
63524
  return undefined;
63387
63525
  }
63526
+ checkSource(cond) {
63527
+ const children = cond.getAllTokens();
63528
+ if (children.length < 2) {
63529
+ return undefined;
63530
+ }
63531
+ const nextLast = children[children.length - 2];
63532
+ const last = children[children.length - 1];
63533
+ if (nextLast.getStr().startsWith("'")
63534
+ && nextLast.getRow() === last.getRow()
63535
+ && nextLast.getEnd().getCol() === last.getStart().getCol()) {
63536
+ return last.getEnd();
63537
+ }
63538
+ return undefined;
63539
+ }
63388
63540
  checkMethodCallParam(call) {
63389
63541
  const children = call.getChildren();
63390
63542
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.102.14",
3
+ "version": "2.102.16",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -38,19 +38,19 @@
38
38
  },
39
39
  "homepage": "https://abaplint.org",
40
40
  "devDependencies": {
41
- "@abaplint/core": "^2.102.14",
41
+ "@abaplint/core": "^2.102.16",
42
42
  "@types/chai": "^4.3.5",
43
43
  "@types/glob": "^7.2.0",
44
44
  "@types/minimist": "^1.2.2",
45
45
  "@types/mocha": "^10.0.1",
46
- "@types/node": "^20.4.5",
46
+ "@types/node": "^20.4.8",
47
47
  "@types/progress": "^2.0.5",
48
48
  "chai": "^4.3.7",
49
49
  "chalk": "^5.3.0",
50
50
  "eslint": "^8.46.0",
51
51
  "glob": "^7.2.3",
52
52
  "json5": "^2.2.3",
53
- "memfs": "^4.2.0",
53
+ "memfs": "^4.2.1",
54
54
  "minimist": "^1.2.8",
55
55
  "mocha": "^10.2.0",
56
56
  "progress": "^2.0.3",