@abaplint/cli 2.120.58 → 2.120.60

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 +281 -9
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -6355,7 +6355,9 @@ const combi_1 = __webpack_require__(/*! ../combi */ "../core/build/src/abap/2_st
6355
6355
  const _1 = __webpack_require__(/*! . */ "../core/build/src/abap/2_statements/expressions/index.js");
6356
6356
  class MethodDefExceptions extends combi_1.Expression {
6357
6357
  getRunnable() {
6358
- const exceptions = (0, combi_1.seq)("EXCEPTIONS", (0, combi_1.plusPrio)(_1.NamespaceSimpleName));
6358
+ // parameter section keywords cannot be exception names
6359
+ const name = (0, combi_1.seq)((0, combi_1.stopBefore1)("IMPORTING", "EXPORTING", "CHANGING", "RETURNING", "RAISING", "EXCEPTIONS"), _1.NamespaceSimpleName);
6360
+ const exceptions = (0, combi_1.seq)("EXCEPTIONS", (0, combi_1.plusPrio)(name));
6359
6361
  return exceptions;
6360
6362
  }
6361
6363
  }
@@ -6427,7 +6429,9 @@ const class_name_1 = __webpack_require__(/*! ./class_name */ "../core/build/src/
6427
6429
  class MethodDefRaising extends combi_1.Expression {
6428
6430
  getRunnable() {
6429
6431
  const resumable = (0, combi_1.seq)("RESUMABLE", (0, combi_1.tok)(tokens_1.ParenLeft), class_name_1.ClassName, (0, combi_1.tok)(tokens_1.ParenRightW));
6430
- const raising = (0, combi_1.seq)("RAISING", (0, combi_1.plus)((0, combi_1.altPrio)(resumable, class_name_1.ClassName)));
6432
+ // parameter section keywords cannot be exception names
6433
+ const name = (0, combi_1.seq)((0, combi_1.stopBefore1)("IMPORTING", "EXPORTING", "CHANGING", "RETURNING", "RAISING", "EXCEPTIONS"), class_name_1.ClassName);
6434
+ const raising = (0, combi_1.seq)("RAISING", (0, combi_1.plus)((0, combi_1.altPrio)(resumable, name)));
6431
6435
  return raising;
6432
6436
  }
6433
6437
  }
@@ -16731,7 +16735,7 @@ class MethodDef {
16731
16735
  (0, combi_1.seq)("VALIDATE ON SAVE IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("MODIFY", (0, combi_1.opt)("IMPORTING"), (0, combi_1.plus)((0, combi_1.seq)(expressions_1.MethodParamName, modify))), (0, combi_1.seq)("PRECHECK IMPORTING", expressions_1.MethodParamName, modify), (0, combi_1.seq)("DETERMINATION", expressions_1.TypeName, "IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("VALIDATION", expressions_1.TypeName, "IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("NUMBERING IMPORTING", expressions_1.MethodParamName, modify), (0, combi_1.seq)("READ IMPORTING", expressions_1.MethodParamName, (0, combi_1.altPrio)(forRead, forfunction)), (0, combi_1.seq)("FEATURES IMPORTING", expressions_1.MethodParamName, "REQUEST", expressions_1.NamespaceSimpleName, "FOR", expressions_1.NamespaceSimpleName, result), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR CREATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR UPDATE", expressions_1.TypeName, expressions_1.MethodParamName, "FOR DELETE", expressions_1.TypeName), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR READ", expressions_1.TypeName, result), (0, combi_1.seq)("BEHAVIOR IMPORTING", expressions_1.MethodParamName, "FOR UPDATE", expressions_1.TypeName), (0, combi_1.seq)((0, combi_1.alt)("BEHAVIOR", "LOCK"), "IMPORTING", expressions_1.MethodParamName, "FOR LOCK", expressions_1.TypeName), (0, combi_1.seq)("DETERMINE", (0, combi_1.alt)("ON MODIFY", "ON SAVE"), "IMPORTING", expressions_1.MethodParamName, "FOR", expressions_1.TypeName), (0, combi_1.seq)("GLOBAL AUTHORIZATION IMPORTING REQUEST", expressions_1.MethodParamName, "FOR", expressions_1.TypeName, result), (0, combi_1.seq)("GLOBAL FEATURES IMPORTING REQUEST", expressions_1.MethodParamName, "FOR", expressions_1.TypeName, result), (0, combi_1.seq)((0, combi_1.seq)((0, combi_1.opt)("INSTANCE"), "AUTHORIZATION IMPORTING"), expressions_1.MethodParamName, "REQUEST", expressions_1.MethodParamName, "FOR", expressions_1.TypeName, result), (0, combi_1.seq)("INSTANCE FEATURES IMPORTING", expressions_1.MethodParamName, "REQUEST", expressions_1.MethodParamName, "FOR", expressions_1.TypeName, result));
16732
16736
  // todo, this is only from version something
16733
16737
  // AMDP OPTIONS clause blocked in KeyUser
16734
- const amdp = (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("AMDP OPTIONS", (0, combi_1.optPrio)("READ-ONLY"), "CDS SESSION CLIENT", (0, combi_1.alt)("CURRENT", "DEPENDENT"), (0, combi_1.optPrio)(expressions_1.MethodDefImporting), (0, combi_1.optPrio)(expressions_1.MethodDefExporting), (0, combi_1.optPrio)(expressions_1.MethodDefRaising)));
16738
+ const amdp = (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("AMDP OPTIONS", (0, combi_1.per)("READ-ONLY", (0, combi_1.seq)("CDS SESSION CLIENT", (0, combi_1.alt)("CURRENT", "DEPENDENT"))), (0, combi_1.optPrio)(expressions_1.MethodDefImporting), (0, combi_1.optPrio)(expressions_1.MethodDefExporting), (0, combi_1.optPrio)(expressions_1.MethodDefRaising)));
16735
16739
  // FOR DDL OBJECT / FOR TABLE FUNCTION / FOR SCALAR FUNCTION blocked in KeyUser
16736
16740
  const regular = (0, combi_1.seq)((0, combi_1.altPrio)("CLASS-METHODS", "METHODS"), expressions_1.MethodName, (0, combi_1.alt)((0, combi_1.seq)((0, combi_1.optPrio)(expressions_1.Abstract), (0, combi_1.optPrio)(def), expressions_1.EventHandler), parameters, testing, (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("FOR", behavior)), amdp, "NOT AT END OF MODE", (0, combi_1.optPrio)(expressions_1.Redefinition)));
16737
16741
  // RAP event handlers are instance methods; CLASS-METHODS is not allowed.
@@ -16762,7 +16766,8 @@ class MethodImplementation {
16762
16766
  const name = (0, combi_1.regex)(/[\w~]+/);
16763
16767
  const kernel = (0, combi_1.seq)("KERNEL MODULE", (0, combi_1.plus)(name), (0, combi_1.optPrio)((0, combi_1.altPrio)("FAIL", "IGNORE")));
16764
16768
  const using = (0, combi_1.seq)("USING", (0, combi_1.plus)(expressions_1.SimpleFieldChain));
16765
- const database = (0, combi_1.seq)("DATABASE", (0, combi_1.alt)("PROCEDURE", "FUNCTION", "GRAPH WORKSPACE"), "FOR HDB", expressions_1.Language, (0, combi_1.opt)("OPTIONS READ-ONLY"), (0, combi_1.opt)(using));
16769
+ const options = (0, combi_1.seq)("OPTIONS", (0, combi_1.per)("READ-ONLY", "SUPPRESS SYNTAX ERRORS", "DETERMINISTIC"));
16770
+ const database = (0, combi_1.seq)("DATABASE", (0, combi_1.alt)("PROCEDURE", "FUNCTION", "GRAPH WORKSPACE"), "FOR HDB", expressions_1.Language, (0, combi_1.opt)(options), (0, combi_1.opt)(using));
16766
16771
  // BY DATABASE and BY KERNEL both blocked in KeyUser
16767
16772
  const by = (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("BY", (0, combi_1.alt)(kernel, database)));
16768
16773
  return (0, combi_1.seq)("METHOD", expressions_1.MethodName, (0, combi_1.optPrio)(by));
@@ -34781,6 +34786,11 @@ class Source {
34781
34786
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
34782
34787
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
34783
34788
  }
34789
+ if ((foundType === null || foundType === void 0 ? void 0 : foundType.isGeneric()) && bodyType !== undefined) {
34790
+ this.addIfInferred(node, input, bodyType);
34791
+ this.traverseRemainingChildren(children, input);
34792
+ return bodyType;
34793
+ }
34784
34794
  this.addIfInferred(node, input, foundType);
34785
34795
  this.traverseRemainingChildren(children, input);
34786
34796
  return foundType;
@@ -39448,10 +39458,22 @@ const basic_types_1 = __webpack_require__(/*! ../basic_types */ "../core/build/s
39448
39458
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/abap/types/basic/index.js");
39449
39459
  const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifier */ "../core/build/src/abap/types/_typed_identifier.js");
39450
39460
  const _reference_1 = __webpack_require__(/*! ../_reference */ "../core/build/src/abap/5_syntax/_reference.js");
39461
+ const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
39451
39462
  class CreateData {
39452
39463
  runSyntax(node, input) {
39464
+ const likeLineOf = node.concatTokens().toUpperCase().includes(" LIKE LINE OF ");
39453
39465
  for (const s of node.findDirectExpressions(Expressions.Source)) {
39454
- source_1.Source.runSyntax(s, input);
39466
+ const sourceType = source_1.Source.runSyntax(s, input);
39467
+ if (likeLineOf === true
39468
+ && sourceType !== undefined
39469
+ && !(sourceType instanceof basic_1.TableType)
39470
+ && !(sourceType instanceof basic_1.VoidType)
39471
+ && !(sourceType instanceof basic_1.UnknownType)
39472
+ && !(sourceType instanceof basic_1.AnyType)) {
39473
+ const message = `"${s.concatTokens()}" is not an internal table`;
39474
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
39475
+ return;
39476
+ }
39455
39477
  }
39456
39478
  for (const t of node.findDirectExpressions(Expressions.Target)) {
39457
39479
  target_1.Target.runSyntax(t, input);
@@ -39636,6 +39658,11 @@ class CreateObject {
39636
39658
  ooName = found.getVoided();
39637
39659
  }
39638
39660
  input.scope.addReference(t === null || t === void 0 ? void 0 : t.getFirstToken(), cdef, _reference_1.ReferenceType.ConstructorReference, input.filename, { ooName: ooName });
39661
+ if (type && type.get() instanceof Expressions.Dynamic) {
39662
+ // the class is only known at runtime, cdef is the static type of the target
39663
+ this.validateParameters(undefined, node, input);
39664
+ return;
39665
+ }
39639
39666
  if (cdef !== undefined) {
39640
39667
  const err = CreateObject.checkInstantiationAllowed(cdef, input);
39641
39668
  if (err) {
@@ -70685,7 +70712,7 @@ class Registry {
70685
70712
  }
70686
70713
  static abaplintVersion() {
70687
70714
  // magic, see build script "version.js"
70688
- return "2.120.58";
70715
+ return "2.120.60";
70689
70716
  }
70690
70717
  getDDICReferences() {
70691
70718
  return this.ddicReferences;
@@ -71318,12 +71345,13 @@ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-on
71318
71345
  return issues;
71319
71346
  }
71320
71347
  getAbapdoc(rows, pos) {
71348
+ var _a, _b, _c;
71321
71349
  let previousRow = pos.getRow() - 2;
71322
- let rowText = rows[previousRow].trim().toUpperCase();
71350
+ let rowText = ((_a = rows[previousRow]) !== null && _a !== void 0 ? _a : "").trim().toUpperCase();
71323
71351
  const text = [];
71324
71352
  if (rowText === "METHODS" || rowText === "CLASS-METHODS") {
71325
71353
  previousRow--;
71326
- rowText = rows[previousRow].trim().toUpperCase();
71354
+ rowText = ((_b = rows[previousRow]) !== null && _b !== void 0 ? _b : "").trim().toUpperCase();
71327
71355
  }
71328
71356
  text.push(rowText);
71329
71357
  //we need to push the first row despite if it is actually an abapdoc or not
@@ -71331,7 +71359,7 @@ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#abap-doc-on
71331
71359
  if (rowText.trim().substring(0, 2) === "\"!") {
71332
71360
  while (previousRow >= 0) {
71333
71361
  previousRow--;
71334
- rowText = rows[previousRow].trim().toUpperCase();
71362
+ rowText = ((_c = rows[previousRow]) !== null && _c !== void 0 ? _c : "").trim().toUpperCase();
71335
71363
  if (rowText.trim().substring(0, 2) !== "\"!") {
71336
71364
  break;
71337
71365
  }
@@ -85123,6 +85151,7 @@ __exportStar(__webpack_require__(/*! ./types_naming */ "../core/build/src/rules/
85123
85151
  __exportStar(__webpack_require__(/*! ./uncaught_exception */ "../core/build/src/rules/uncaught_exception.js"), exports);
85124
85152
  __exportStar(__webpack_require__(/*! ./unknown_types */ "../core/build/src/rules/unknown_types.js"), exports);
85125
85153
  __exportStar(__webpack_require__(/*! ./unnecessary_chaining */ "../core/build/src/rules/unnecessary_chaining.js"), exports);
85154
+ __exportStar(__webpack_require__(/*! ./unnecessary_loop_guard */ "../core/build/src/rules/unnecessary_loop_guard.js"), exports);
85126
85155
  __exportStar(__webpack_require__(/*! ./unnecessary_pragma */ "../core/build/src/rules/unnecessary_pragma.js"), exports);
85127
85156
  __exportStar(__webpack_require__(/*! ./unnecessary_return */ "../core/build/src/rules/unnecessary_return.js"), exports);
85128
85157
  __exportStar(__webpack_require__(/*! ./unreachable_code */ "../core/build/src/rules/unreachable_code.js"), exports);
@@ -85135,6 +85164,7 @@ __exportStar(__webpack_require__(/*! ./unused_variables */ "../core/build/src/ru
85135
85164
  __exportStar(__webpack_require__(/*! ./use_bool_expression */ "../core/build/src/rules/use_bool_expression.js"), exports);
85136
85165
  __exportStar(__webpack_require__(/*! ./use_class_based_exceptions */ "../core/build/src/rules/use_class_based_exceptions.js"), exports);
85137
85166
  __exportStar(__webpack_require__(/*! ./use_line_exists */ "../core/build/src/rules/use_line_exists.js"), exports);
85167
+ __exportStar(__webpack_require__(/*! ./use_message_class */ "../core/build/src/rules/use_message_class.js"), exports);
85138
85168
  __exportStar(__webpack_require__(/*! ./use_new */ "../core/build/src/rules/use_new.js"), exports);
85139
85169
  __exportStar(__webpack_require__(/*! ./when_others_last */ "../core/build/src/rules/when_others_last.js"), exports);
85140
85170
  __exportStar(__webpack_require__(/*! ./whitespace_end */ "../core/build/src/rules/whitespace_end.js"), exports);
@@ -98871,6 +98901,151 @@ exports.UnnecessaryChaining = UnnecessaryChaining;
98871
98901
 
98872
98902
  /***/ },
98873
98903
 
98904
+ /***/ "../core/build/src/rules/unnecessary_loop_guard.js"
98905
+ /*!*********************************************************!*\
98906
+ !*** ../core/build/src/rules/unnecessary_loop_guard.js ***!
98907
+ \*********************************************************/
98908
+ (__unused_webpack_module, exports, __webpack_require__) {
98909
+
98910
+ "use strict";
98911
+
98912
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
98913
+ if (k2 === undefined) k2 = k;
98914
+ var desc = Object.getOwnPropertyDescriptor(m, k);
98915
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
98916
+ desc = { enumerable: true, get: function() { return m[k]; } };
98917
+ }
98918
+ Object.defineProperty(o, k2, desc);
98919
+ }) : (function(o, m, k, k2) {
98920
+ if (k2 === undefined) k2 = k;
98921
+ o[k2] = m[k];
98922
+ }));
98923
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
98924
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
98925
+ }) : function(o, v) {
98926
+ o["default"] = v;
98927
+ });
98928
+ var __importStar = (this && this.__importStar) || (function () {
98929
+ var ownKeys = function(o) {
98930
+ ownKeys = Object.getOwnPropertyNames || function (o) {
98931
+ var ar = [];
98932
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
98933
+ return ar;
98934
+ };
98935
+ return ownKeys(o);
98936
+ };
98937
+ return function (mod) {
98938
+ if (mod && mod.__esModule) return mod;
98939
+ var result = {};
98940
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
98941
+ __setModuleDefault(result, mod);
98942
+ return result;
98943
+ };
98944
+ })();
98945
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
98946
+ exports.UnnecessaryLoopGuard = exports.UnnecessaryLoopGuardConf = void 0;
98947
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
98948
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
98949
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
98950
+ const Structures = __importStar(__webpack_require__(/*! ../abap/3_structures/structures */ "../core/build/src/abap/3_structures/structures/index.js"));
98951
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
98952
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
98953
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
98954
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "../core/build/src/edit_helper.js");
98955
+ class UnnecessaryLoopGuardConf extends _basic_rule_config_1.BasicRuleConfig {
98956
+ }
98957
+ exports.UnnecessaryLoopGuardConf = UnnecessaryLoopGuardConf;
98958
+ class UnnecessaryLoopGuard extends _abap_rule_1.ABAPRule {
98959
+ constructor() {
98960
+ super(...arguments);
98961
+ this.conf = new UnnecessaryLoopGuardConf();
98962
+ }
98963
+ getMetadata() {
98964
+ return {
98965
+ key: "unnecessary_loop_guard",
98966
+ title: "Unnecessary loop guard",
98967
+ shortDescription: `Detects unnecessary IS [NOT] INITIAL check before LOOP AT`,
98968
+ extendedInformation: `LOOP AT iterates zero times on an empty table, so an IS [NOT] INITIAL guard is redundant.`,
98969
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix],
98970
+ badExample: `IF lt_data IS NOT INITIAL.
98971
+ LOOP AT lt_data INTO DATA(ls_item).
98972
+ WRITE ls_item-name.
98973
+ ENDLOOP.
98974
+ ENDIF.`,
98975
+ goodExample: `LOOP AT lt_data INTO DATA(ls_item).
98976
+ WRITE ls_item-name.
98977
+ ENDLOOP.`,
98978
+ };
98979
+ }
98980
+ getConfig() {
98981
+ return this.conf;
98982
+ }
98983
+ setConfig(conf) {
98984
+ this.conf = conf;
98985
+ }
98986
+ runParsed(file) {
98987
+ const issues = [];
98988
+ const stru = file.getStructure();
98989
+ if (stru === undefined) {
98990
+ return issues;
98991
+ }
98992
+ for (const ifStru of stru.findAllStructuresRecursive(Structures.If)) {
98993
+ if (ifStru.findDirectStructures(Structures.ElseIf).length > 0
98994
+ || ifStru.findDirectStructures(Structures.Else).length > 0) {
98995
+ continue;
98996
+ }
98997
+ const ifStatement = ifStru.findDirectStatement(Statements.If);
98998
+ if (ifStatement === undefined) {
98999
+ continue;
99000
+ }
99001
+ const cond = ifStatement.findDirectExpression(Expressions.Cond);
99002
+ if (cond === undefined) {
99003
+ continue;
99004
+ }
99005
+ const compareNodes = cond.findDirectExpressions(Expressions.Compare);
99006
+ if (compareNodes.length !== 1) {
99007
+ continue;
99008
+ }
99009
+ const m = compareNodes[0].concatTokens().toUpperCase().match(/^(.+?)\s+IS\s+(?:NOT\s+)?INITIAL\s*$/);
99010
+ if (!m) {
99011
+ continue;
99012
+ }
99013
+ const tableName = m[1];
99014
+ const bodyStructures = ifStru.findDirectStructures(Structures.Body);
99015
+ if (bodyStructures.length !== 1) {
99016
+ continue;
99017
+ }
99018
+ const normalStructures = bodyStructures[0].findDirectStructures(Structures.Normal);
99019
+ if (normalStructures.length !== 1) {
99020
+ continue;
99021
+ }
99022
+ const loopStructures = normalStructures[0].findDirectStructures(Structures.Loop);
99023
+ if (loopStructures.length !== 1) {
99024
+ continue;
99025
+ }
99026
+ const loopStatement = loopStructures[0].findDirectStatement(Statements.Loop);
99027
+ if (loopStatement === undefined) {
99028
+ continue;
99029
+ }
99030
+ const loopSource = loopStatement.findFirstExpression(Expressions.LoopSource);
99031
+ if (loopSource === undefined) {
99032
+ continue;
99033
+ }
99034
+ if (loopSource.concatTokens().toUpperCase() !== tableName) {
99035
+ continue;
99036
+ }
99037
+ const endifStatement = ifStru.findDirectStatement(Statements.EndIf);
99038
+ const fix = edit_helper_1.EditHelper.merge(edit_helper_1.EditHelper.deleteStatement(file, ifStatement), edit_helper_1.EditHelper.deleteStatement(file, endifStatement));
99039
+ issues.push(issue_1.Issue.atStatement(file, ifStatement, "Unnecessary IS [NOT] INITIAL check before LOOP AT", this.getMetadata().key, this.conf.severity, fix));
99040
+ }
99041
+ return issues;
99042
+ }
99043
+ }
99044
+ exports.UnnecessaryLoopGuard = UnnecessaryLoopGuard;
99045
+ //# sourceMappingURL=unnecessary_loop_guard.js.map
99046
+
99047
+ /***/ },
99048
+
98874
99049
  /***/ "../core/build/src/rules/unnecessary_pragma.js"
98875
99050
  /*!*****************************************************!*\
98876
99051
  !*** ../core/build/src/rules/unnecessary_pragma.js ***!
@@ -100945,6 +101120,103 @@ exports.UseLineExists = UseLineExists;
100945
101120
 
100946
101121
  /***/ },
100947
101122
 
101123
+ /***/ "../core/build/src/rules/use_message_class.js"
101124
+ /*!****************************************************!*\
101125
+ !*** ../core/build/src/rules/use_message_class.js ***!
101126
+ \****************************************************/
101127
+ (__unused_webpack_module, exports, __webpack_require__) {
101128
+
101129
+ "use strict";
101130
+
101131
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
101132
+ if (k2 === undefined) k2 = k;
101133
+ var desc = Object.getOwnPropertyDescriptor(m, k);
101134
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
101135
+ desc = { enumerable: true, get: function() { return m[k]; } };
101136
+ }
101137
+ Object.defineProperty(o, k2, desc);
101138
+ }) : (function(o, m, k, k2) {
101139
+ if (k2 === undefined) k2 = k;
101140
+ o[k2] = m[k];
101141
+ }));
101142
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
101143
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
101144
+ }) : function(o, v) {
101145
+ o["default"] = v;
101146
+ });
101147
+ var __importStar = (this && this.__importStar) || (function () {
101148
+ var ownKeys = function(o) {
101149
+ ownKeys = Object.getOwnPropertyNames || function (o) {
101150
+ var ar = [];
101151
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
101152
+ return ar;
101153
+ };
101154
+ return ownKeys(o);
101155
+ };
101156
+ return function (mod) {
101157
+ if (mod && mod.__esModule) return mod;
101158
+ var result = {};
101159
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
101160
+ __setModuleDefault(result, mod);
101161
+ return result;
101162
+ };
101163
+ })();
101164
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
101165
+ exports.UseMessageClass = exports.UseMessageClassConf = void 0;
101166
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
101167
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
101168
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
101169
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
101170
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
101171
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
101172
+ class UseMessageClassConf extends _basic_rule_config_1.BasicRuleConfig {
101173
+ }
101174
+ exports.UseMessageClassConf = UseMessageClassConf;
101175
+ class UseMessageClass extends _abap_rule_1.ABAPRule {
101176
+ constructor() {
101177
+ super(...arguments);
101178
+ this.conf = new UseMessageClassConf();
101179
+ }
101180
+ getMetadata() {
101181
+ return {
101182
+ key: "use_message_class",
101183
+ title: "Use message class",
101184
+ shortDescription: `Define messages in SE91 instead of using inline text or variables`,
101185
+ tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
101186
+ badExample: `MESSAGE 'Something went wrong' TYPE 'E'.`,
101187
+ goodExample: `MESSAGE e001(bc_msg).`,
101188
+ };
101189
+ }
101190
+ getConfig() {
101191
+ return this.conf;
101192
+ }
101193
+ setConfig(conf) {
101194
+ this.conf = conf;
101195
+ }
101196
+ runParsed(file, _obj) {
101197
+ const structure = file.getStructure();
101198
+ if (structure === undefined) {
101199
+ return [];
101200
+ }
101201
+ const issues = [];
101202
+ const key = this.getMetadata().key;
101203
+ for (const statement of structure.findAllStatements(Statements.Message)) {
101204
+ // The parser populates MessageSource only for the class-based forms (e001(bc_msg) or ID/TYPE/NUMBER).
101205
+ // The text form (MESSAGE <source> TYPE <source>) uses MessageSourceSource directly with no MessageSource child.
101206
+ // Absence of MessageSource is therefore a reliable discriminator between the two forms.
101207
+ if (statement.findDirectExpression(Expressions.MessageSource) !== undefined) {
101208
+ continue;
101209
+ }
101210
+ issues.push(issue_1.Issue.atStatement(file, statement, "Use a message class (SE91) instead of inline text or variable", key, this.conf.severity));
101211
+ }
101212
+ return issues;
101213
+ }
101214
+ }
101215
+ exports.UseMessageClass = UseMessageClass;
101216
+ //# sourceMappingURL=use_message_class.js.map
101217
+
101218
+ /***/ },
101219
+
100948
101220
  /***/ "../core/build/src/rules/use_new.js"
100949
101221
  /*!******************************************!*\
100950
101222
  !*** ../core/build/src/rules/use_new.js ***!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.58",
3
+ "version": "2.120.60",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://abaplint.org",
41
41
  "devDependencies": {
42
- "@abaplint/core": "^2.120.58",
42
+ "@abaplint/core": "^2.120.60",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",