@abaplint/cli 2.120.62 → 2.120.64

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 +229 -8
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -27548,6 +27548,7 @@ class TypeUtils {
27548
27548
  || type instanceof basic_1.StringType
27549
27549
  || type instanceof basic_1.CLikeType
27550
27550
  || type instanceof basic_1.CSequenceType
27551
+ || type instanceof basic_1.DataType
27551
27552
  || this.isCharLikeField(type);
27552
27553
  }
27553
27554
  isCharLike(type) {
@@ -28798,6 +28799,7 @@ class BasicTypes {
28798
28799
  }
28799
28800
  parseType(node, qualifiedName) {
28800
28801
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
28802
+ var _l;
28801
28803
  const typeName = node.findFirstExpression(Expressions.TypeName);
28802
28804
  let text = (_a = node.findFirstExpression(Expressions.Type)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
28803
28805
  if (text === undefined) {
@@ -28948,6 +28950,9 @@ class BasicTypes {
28948
28950
  length = parseInt(int.concatTokens(), 10);
28949
28951
  }
28950
28952
  }
28953
+ else if (node.get() instanceof Statements.Parameter) {
28954
+ length = (_l = this.findParameterLength(node)) !== null && _l !== void 0 ? _l : length;
28955
+ }
28951
28956
  found = new Types.CharacterType(length, { qualifiedName: qualifiedName }); // fallback
28952
28957
  if (this.isOccurs(node)) {
28953
28958
  found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE"), keyType: Types.TableKeyType.default }, qualifiedName);
@@ -29317,11 +29322,43 @@ class BasicTypes {
29317
29322
  throw new Error("findValue, unexpected");
29318
29323
  }
29319
29324
  findDecimals(node) {
29320
- var _a, _b;
29325
+ var _a, _b, _c;
29321
29326
  const dec = (_b = (_a = node.findDirectExpression(Expressions.Decimals)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Integer)) === null || _b === void 0 ? void 0 : _b.concatTokens();
29322
29327
  if (dec) {
29323
29328
  return parseInt(dec, 10);
29324
29329
  }
29330
+ if (node.get() instanceof Statements.Parameter) {
29331
+ // PARAMETERS spells it seq("DECIMALS", Source) instead of the Decimals expression
29332
+ const source = (_c = this.findParameterAddition(node, "DECIMALS")) === null || _c === void 0 ? void 0 : _c.concatTokens();
29333
+ if (source && /^\d+$/.test(source)) {
29334
+ return parseInt(source, 10);
29335
+ }
29336
+ }
29337
+ return undefined;
29338
+ }
29339
+ // PARAMETERS spells it seq("LENGTH", Constant) instead of the Length expression
29340
+ findParameterLength(node) {
29341
+ const constant = this.findParameterAddition(node, "LENGTH");
29342
+ if (constant === undefined) {
29343
+ return undefined;
29344
+ }
29345
+ const length = this.parseInt(constant.concatTokens());
29346
+ return length === undefined || isNaN(length) ? undefined : length;
29347
+ }
29348
+ // finds the expression following a direct keyword token, "VISIBLE LENGTH" is not "LENGTH"
29349
+ findParameterAddition(node, keyword) {
29350
+ var _a;
29351
+ const children = node.getChildren();
29352
+ for (let i = 0; i < children.length - 1; i++) {
29353
+ const child = children[i];
29354
+ const next = children[i + 1];
29355
+ if (child instanceof nodes_1.ExpressionNode
29356
+ || child.getFirstToken().getStr().toUpperCase() !== keyword
29357
+ || ((_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr().toUpperCase()) === "VISIBLE") {
29358
+ continue;
29359
+ }
29360
+ return next instanceof nodes_1.ExpressionNode ? next : undefined;
29361
+ }
29325
29362
  return undefined;
29326
29363
  }
29327
29364
  findLength(node) {
@@ -29342,6 +29379,9 @@ class BasicTypes {
29342
29379
  }
29343
29380
  }
29344
29381
  if (val === undefined) {
29382
+ if (node.get() instanceof Statements.Parameter) {
29383
+ return this.findParameterLength(node);
29384
+ }
29345
29385
  return undefined;
29346
29386
  }
29347
29387
  const intExpr = val.findFirstExpression(Expressions.Integer);
@@ -56498,7 +56538,7 @@ class DDIC {
56498
56538
  return new Types.PackedType(length, 0, { qualifiedName: qualifiedName });
56499
56539
  }
56500
56540
  else {
56501
- return new Types.PackedType(8, 0, { qualifiedName: qualifiedName });
56541
+ return new Types.PackedType(8, decimals !== null && decimals !== void 0 ? decimals : 0, { qualifiedName: qualifiedName });
56502
56542
  }
56503
56543
  case "C":
56504
56544
  if (length) {
@@ -68934,11 +68974,17 @@ class Table extends _abstract_object_1.AbstractObject {
68934
68974
  }
68935
68975
  const ret = [];
68936
68976
  for (const p of this.parsedData.fields) {
68937
- if (p.KEYFLAG === "X" && p.FIELDNAME === ".INCLUDE") {
68938
- const lookup = new ddic_1.DDIC(reg).lookupTableOrView(p.PRECFIELD).type;
68977
+ if (p.KEYFLAG === "X" && (p.FIELDNAME === ".INCLUDE" || p.FIELDNAME.startsWith(".INCLU-"))) {
68978
+ let lookup = new ddic_1.DDIC(reg).lookupTableOrView(p.PRECFIELD).type;
68979
+ if (lookup instanceof _typed_identifier_1.TypedIdentifier) {
68980
+ lookup = lookup.getType();
68981
+ }
68982
+ // same naming as in parseType(), "--AP" are .APPENDS and get no suffix
68983
+ const postfix = p.FIELDNAME.startsWith(".INCLU-") && p.FIELDNAME !== ".INCLU--AP"
68984
+ ? p.FIELDNAME.substring(".INCLU-".length) : "";
68939
68985
  if (lookup instanceof Types.StructureType) {
68940
68986
  for (const c of lookup.getComponents()) {
68941
- ret.push(c.name);
68987
+ ret.push(c.name + postfix);
68942
68988
  }
68943
68989
  }
68944
68990
  }
@@ -70763,7 +70809,7 @@ class Registry {
70763
70809
  }
70764
70810
  static abaplintVersion() {
70765
70811
  // magic, see build script "version.js"
70766
- return "2.120.62";
70812
+ return "2.120.64";
70767
70813
  }
70768
70814
  getDDICReferences() {
70769
70815
  return this.ddicReferences;
@@ -81259,6 +81305,178 @@ exports.EasyToFindMessages = EasyToFindMessages;
81259
81305
 
81260
81306
  /***/ },
81261
81307
 
81308
+ /***/ "../core/build/src/rules/else_after_all_returns.js"
81309
+ /*!*********************************************************!*\
81310
+ !*** ../core/build/src/rules/else_after_all_returns.js ***!
81311
+ \*********************************************************/
81312
+ (__unused_webpack_module, exports, __webpack_require__) {
81313
+
81314
+ "use strict";
81315
+
81316
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
81317
+ if (k2 === undefined) k2 = k;
81318
+ var desc = Object.getOwnPropertyDescriptor(m, k);
81319
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
81320
+ desc = { enumerable: true, get: function() { return m[k]; } };
81321
+ }
81322
+ Object.defineProperty(o, k2, desc);
81323
+ }) : (function(o, m, k, k2) {
81324
+ if (k2 === undefined) k2 = k;
81325
+ o[k2] = m[k];
81326
+ }));
81327
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
81328
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
81329
+ }) : function(o, v) {
81330
+ o["default"] = v;
81331
+ });
81332
+ var __importStar = (this && this.__importStar) || (function () {
81333
+ var ownKeys = function(o) {
81334
+ ownKeys = Object.getOwnPropertyNames || function (o) {
81335
+ var ar = [];
81336
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
81337
+ return ar;
81338
+ };
81339
+ return ownKeys(o);
81340
+ };
81341
+ return function (mod) {
81342
+ if (mod && mod.__esModule) return mod;
81343
+ var result = {};
81344
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
81345
+ __setModuleDefault(result, mod);
81346
+ return result;
81347
+ };
81348
+ })();
81349
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
81350
+ exports.ElseAfterAllReturns = exports.ElseAfterAllReturnsConf = void 0;
81351
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
81352
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
81353
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
81354
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
81355
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
81356
+ const Structures = __importStar(__webpack_require__(/*! ../abap/3_structures/structures */ "../core/build/src/abap/3_structures/structures/index.js"));
81357
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
81358
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "../core/build/src/abap/nodes/index.js");
81359
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "../core/build/src/edit_helper.js");
81360
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "../core/build/src/abap/2_statements/statements/_statement.js");
81361
+ class ElseAfterAllReturnsConf extends _basic_rule_config_1.BasicRuleConfig {
81362
+ }
81363
+ exports.ElseAfterAllReturnsConf = ElseAfterAllReturnsConf;
81364
+ class ElseAfterAllReturns extends _abap_rule_1.ABAPRule {
81365
+ constructor() {
81366
+ super(...arguments);
81367
+ this.conf = new ElseAfterAllReturnsConf();
81368
+ }
81369
+ getMetadata() {
81370
+ return {
81371
+ key: "else_after_all_returns",
81372
+ title: "Else after all returns",
81373
+ shortDescription: `Finds ELSE branches that are redundant because all prior branches exit unconditionally.`,
81374
+ extendedInformation: `When every branch preceding ELSE ends with RETURN, EXIT, or CONTINUE (or a non-resumable RAISE / LEAVE), ` +
81375
+ `the ELSE keyword adds no logical value and can be removed by de-indenting its body.`,
81376
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix],
81377
+ badExample: `IF x = 1.\n RETURN.\nELSE.\n WRITE 'hello'.\nENDIF.`,
81378
+ goodExample: `IF x = 1.\n RETURN.\nENDIF.\nWRITE 'hello'.`,
81379
+ };
81380
+ }
81381
+ getConfig() {
81382
+ return this.conf;
81383
+ }
81384
+ setConfig(conf) {
81385
+ this.conf = conf;
81386
+ }
81387
+ runParsed(file, _obj) {
81388
+ const issues = [];
81389
+ const structure = file.getStructure();
81390
+ if (structure === undefined) {
81391
+ return [];
81392
+ }
81393
+ for (const ifNode of structure.findAllStructures(Structures.If)) {
81394
+ const elseNode = ifNode.findDirectStructure(Structures.Else);
81395
+ if (elseNode === undefined) {
81396
+ continue;
81397
+ }
81398
+ if (this.allBranchesExit(ifNode)) {
81399
+ const elseStatement = elseNode.findFirstStatement(Statements.Else);
81400
+ const endifStatement = ifNode.findDirectStatement(Statements.EndIf);
81401
+ if (elseStatement === undefined || endifStatement === undefined) {
81402
+ continue;
81403
+ }
81404
+ const fix = edit_helper_1.EditHelper.merge(edit_helper_1.EditHelper.replaceRange(file, elseStatement.getFirstToken().getStart(), elseStatement.getLastToken().getEnd(), "ENDIF."), edit_helper_1.EditHelper.deleteStatement(file, endifStatement));
81405
+ // eslint-disable-next-line max-len
81406
+ issues.push(issue_1.Issue.atStatement(file, elseStatement, "Redundant ELSE: all prior branches exit unconditionally", this.getMetadata().key, this.conf.severity, fix));
81407
+ }
81408
+ }
81409
+ return issues;
81410
+ }
81411
+ // Returns true if every branch before the ELSE ends with an unconditional exit.
81412
+ allBranchesExit(ifNode) {
81413
+ // Main IF body
81414
+ const mainBody = ifNode.findDirectStructure(Structures.Body);
81415
+ if (!this.bodyEndsWithExit(mainBody)) {
81416
+ return false;
81417
+ }
81418
+ // Each ELSEIF body
81419
+ for (const elseifNode of ifNode.findDirectStructures(Structures.ElseIf)) {
81420
+ const elseifBody = elseifNode.findDirectStructure(Structures.Body);
81421
+ if (!this.bodyEndsWithExit(elseifBody)) {
81422
+ return false;
81423
+ }
81424
+ }
81425
+ return true;
81426
+ }
81427
+ bodyEndsWithExit(body) {
81428
+ if (body === undefined) {
81429
+ return false;
81430
+ }
81431
+ const last = this.lastNonCommentStatement(body);
81432
+ if (last === undefined) {
81433
+ return false;
81434
+ }
81435
+ return this.isExit(last);
81436
+ }
81437
+ collectStatements(node) {
81438
+ const result = [];
81439
+ for (const child of node.getChildren()) {
81440
+ if (child instanceof nodes_1.StatementNode) {
81441
+ result.push(child);
81442
+ }
81443
+ else if (child instanceof nodes_1.StructureNode) {
81444
+ result.push(...this.collectStatements(child));
81445
+ }
81446
+ }
81447
+ return result;
81448
+ }
81449
+ lastNonCommentStatement(node) {
81450
+ const all = this.collectStatements(node);
81451
+ for (let i = all.length - 1; i >= 0; i--) {
81452
+ if (!(all[i].get() instanceof _statement_1.Comment)) {
81453
+ return all[i];
81454
+ }
81455
+ }
81456
+ return undefined;
81457
+ }
81458
+ isExit(node) {
81459
+ const s = node.get();
81460
+ if (s instanceof Statements.Return
81461
+ || s instanceof Statements.Exit
81462
+ || s instanceof Statements.Continue) {
81463
+ return true;
81464
+ }
81465
+ if (s instanceof Statements.Raise) {
81466
+ return !node.concatTokens().toUpperCase().includes("RESUMABLE");
81467
+ }
81468
+ if (s instanceof Statements.Leave) {
81469
+ const tokens = node.concatTokens().toUpperCase();
81470
+ return !tokens.includes("LIST-PROCESSING") && node.findFirstExpression(Expressions.AndReturn) === undefined;
81471
+ }
81472
+ return false;
81473
+ }
81474
+ }
81475
+ exports.ElseAfterAllReturns = ElseAfterAllReturns;
81476
+ //# sourceMappingURL=else_after_all_returns.js.map
81477
+
81478
+ /***/ },
81479
+
81262
81480
  /***/ "../core/build/src/rules/empty_event.js"
81263
81481
  /*!**********************************************!*\
81264
81482
  !*** ../core/build/src/rules/empty_event.js ***!
@@ -85080,6 +85298,7 @@ __exportStar(__webpack_require__(/*! ./empty_event */ "../core/build/src/rules/e
85080
85298
  __exportStar(__webpack_require__(/*! ./empty_line_in_statement */ "../core/build/src/rules/empty_line_in_statement.js"), exports);
85081
85299
  __exportStar(__webpack_require__(/*! ./empty_statement */ "../core/build/src/rules/empty_statement.js"), exports);
85082
85300
  __exportStar(__webpack_require__(/*! ./empty_structure */ "../core/build/src/rules/empty_structure.js"), exports);
85301
+ __exportStar(__webpack_require__(/*! ./else_after_all_returns */ "../core/build/src/rules/else_after_all_returns.js"), exports);
85083
85302
  __exportStar(__webpack_require__(/*! ./exit_or_check */ "../core/build/src/rules/exit_or_check.js"), exports);
85084
85303
  __exportStar(__webpack_require__(/*! ./expand_macros */ "../core/build/src/rules/expand_macros.js"), exports);
85085
85304
  __exportStar(__webpack_require__(/*! ./exporting */ "../core/build/src/rules/exporting.js"), exports);
@@ -101874,6 +102093,8 @@ class XMLConsistencyConf extends _basic_rule_config_1.BasicRuleConfig {
101874
102093
  this.textAndTranslationLengthSeverity = severity_1.Severity.Error;
101875
102094
  /** Problem severity for data element(DTEL) field checks */
101876
102095
  this.dataElementSeverity = severity_1.Severity.Error;
102096
+ /** Problem severity for transparent table checks */
102097
+ this.transparentTableSeverity = severity_1.Severity.Error;
101877
102098
  }
101878
102099
  }
101879
102100
  exports.XMLConsistencyConf = XMLConsistencyConf;
@@ -102161,11 +102382,11 @@ class XMLConsistency {
102161
102382
  if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
102162
102383
  if (!((_c = obj.getDeliveryClass()) === null || _c === void 0 ? void 0 : _c.trim())) {
102163
102384
  const message = `Transparent table must have delivery class(CONTFLAG in DD02V) set`;
102164
- issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
102385
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.transparentTableSeverity));
102165
102386
  }
102166
102387
  if (!((_d = obj.getSizeCategory()) === null || _d === void 0 ? void 0 : _d.trim())) {
102167
102388
  const message = `Transparent table must have size category(TABKAT in DD09L) set`;
102168
- issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
102389
+ issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.transparentTableSeverity));
102169
102390
  }
102170
102391
  }
102171
102392
  return issues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.62",
3
+ "version": "2.120.64",
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.62",
42
+ "@abaplint/core": "^2.120.64",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",