@abaplint/cli 2.120.50 → 2.120.51

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 +204 -10
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -27714,6 +27714,20 @@ class TypeUtils {
27714
27714
  || node.findFirstExpression(Expressions.ArithOperator) !== undefined;
27715
27715
  return calculated;
27716
27716
  }
27717
+ // a character constant is only assignable to a hexadecimal target if it can be
27718
+ // interpreted as a hexadecimal value
27719
+ isHexConstant(node) {
27720
+ const constant = node === null || node === void 0 ? void 0 : node.concatTokens();
27721
+ if (constant === undefined) {
27722
+ return true;
27723
+ }
27724
+ if ((constant.startsWith("'") && constant.endsWith("'"))
27725
+ || (constant.startsWith("`") && constant.endsWith("`"))) {
27726
+ const value = constant.substring(1, constant.length - 1);
27727
+ return value.length > 0 && /^[0-9A-Fa-f]+$/.test(value);
27728
+ }
27729
+ return true;
27730
+ }
27717
27731
  isAssignableNew(source, target, node) {
27718
27732
  const calculated = (node === null || node === void 0 ? void 0 : node.findFirstExpression(Expressions.ArithOperator)) !== undefined;
27719
27733
  if (calculated && source instanceof basic_1.HexType && target instanceof basic_1.IntegerType) {
@@ -27779,7 +27793,7 @@ class TypeUtils {
27779
27793
  }
27780
27794
  else if (target instanceof basic_1.XStringType) {
27781
27795
  if (((_d = source.getAbstractTypeData()) === null || _d === void 0 ? void 0 : _d.derivedFromConstant) === true) {
27782
- return (node === null || node === void 0 ? void 0 : node.concatTokens()) !== "''";
27796
+ return this.isHexConstant(node);
27783
27797
  }
27784
27798
  return false;
27785
27799
  }
@@ -70549,7 +70563,7 @@ class Registry {
70549
70563
  }
70550
70564
  static abaplintVersion() {
70551
70565
  // magic, see build script "version.js"
70552
- return "2.120.50";
70566
+ return "2.120.51";
70553
70567
  }
70554
70568
  getDDICReferences() {
70555
70569
  return this.ddicReferences;
@@ -78686,15 +78700,19 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
78686
78700
  continue;
78687
78701
  }
78688
78702
  const condition = this.tableCondition(tableExpression);
78689
- const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
78703
+ // ASSIGNING, not INTO: from v740 a table expression in a read position addresses the
78704
+ // row rather than copying it, so "REF #( tab[ i ]-comp )" and "ASSIGN tab[ i ]-comp"
78705
+ // hand back an address INTO a work area would not preserve. The write path
78706
+ // (moveWithTableTarget) already lowers to ASSIGNING for the same reason.
78707
+ const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
78690
78708
  const tabixBackup = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
78691
78709
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
78692
78710
  const firstToken = high.getFirstToken();
78693
78711
  // note that the tabix restore should be done before throwing the exception
78694
- const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
78712
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${pre}.
78695
78713
  ${indentation}DATA ${tabixBackup} LIKE sy-tabix.
78696
78714
  ${indentation}${tabixBackup} = sy-tabix.
78697
- ${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
78715
+ ${indentation}READ TABLE ${pre} ${condition}ASSIGNING ${uniqueName}.
78698
78716
  ${indentation}sy-tabix = ${tabixBackup}.
78699
78717
  ${indentation}IF sy-subrc <> 0.
78700
78718
  ${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
@@ -79448,8 +79466,7 @@ CONSTANTS: BEGIN OF ${structureName},\n`;
79448
79466
  if (index === undefined) {
79449
79467
  return undefined;
79450
79468
  }
79451
- let uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
79452
- uniqueName = `<${uniqueName}>`;
79469
+ const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
79453
79470
  const tName = target.concatTokens().split("[")[0];
79454
79471
  const condition = this.tableCondition(tableExpression);
79455
79472
  const tabixBackup = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
@@ -80461,12 +80478,16 @@ ${indentation} output = ${uniqueName}.\n`;
80461
80478
  }
80462
80479
  return undefined;
80463
80480
  }
80464
- uniqueName(position, filename, highSyntax) {
80481
+ /** a FIELD-SYMBOLS declaration is known to the scope under its bracketed spelling, so
80482
+ * the collision check has to use that spelling too - otherwise a second outline in the
80483
+ * same method is handed a name that is already taken and the result does not compile */
80484
+ uniqueName(position, filename, highSyntax, fieldSymbol = false) {
80485
+ const decorate = (name) => fieldSymbol === true ? `<${name}>` : name;
80465
80486
  const spag = highSyntax.spaghetti.lookupPosition(position, filename);
80466
80487
  if (spag === undefined) {
80467
80488
  const name = "temprr" + this.counter;
80468
80489
  this.counter++;
80469
- return name;
80490
+ return decorate(name);
80470
80491
  }
80471
80492
  let postfix = "";
80472
80493
  if (spag.getIdentifier().stype === _scope_type_1.ScopeType.ClassDefinition) {
@@ -80475,7 +80496,7 @@ ${indentation} output = ${uniqueName}.\n`;
80475
80496
  postfix = "_" + hash.substring(0, 10);
80476
80497
  }
80477
80498
  while (true) {
80478
- const name = "temp" + this.counter + postfix;
80499
+ const name = decorate("temp" + this.counter + postfix);
80479
80500
  const exists = this.existsRecursive(spag, name);
80480
80501
  this.counter++;
80481
80502
  if (exists === false) {
@@ -84957,6 +84978,7 @@ __exportStar(__webpack_require__(/*! ./use_line_exists */ "../core/build/src/rul
84957
84978
  __exportStar(__webpack_require__(/*! ./use_new */ "../core/build/src/rules/use_new.js"), exports);
84958
84979
  __exportStar(__webpack_require__(/*! ./when_others_last */ "../core/build/src/rules/when_others_last.js"), exports);
84959
84980
  __exportStar(__webpack_require__(/*! ./whitespace_end */ "../core/build/src/rules/whitespace_end.js"), exports);
84981
+ __exportStar(__webpack_require__(/*! ./wrong_abapdoc_position */ "../core/build/src/rules/wrong_abapdoc_position.js"), exports);
84960
84982
  __exportStar(__webpack_require__(/*! ./xml_consistency */ "../core/build/src/rules/xml_consistency.js"), exports);
84961
84983
  __exportStar(__webpack_require__(/*! ./no_exclamation_escape */ "../core/build/src/rules/no_exclamation_escape.js"), exports);
84962
84984
  __exportStar(__webpack_require__(/*! ./xml_bom */ "../core/build/src/rules/xml_bom.js"), exports);
@@ -100439,6 +100461,178 @@ exports.WhitespaceEnd = WhitespaceEnd;
100439
100461
 
100440
100462
  /***/ },
100441
100463
 
100464
+ /***/ "../core/build/src/rules/wrong_abapdoc_position.js"
100465
+ /*!*********************************************************!*\
100466
+ !*** ../core/build/src/rules/wrong_abapdoc_position.js ***!
100467
+ \*********************************************************/
100468
+ (__unused_webpack_module, exports, __webpack_require__) {
100469
+
100470
+ "use strict";
100471
+
100472
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
100473
+ if (k2 === undefined) k2 = k;
100474
+ var desc = Object.getOwnPropertyDescriptor(m, k);
100475
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
100476
+ desc = { enumerable: true, get: function() { return m[k]; } };
100477
+ }
100478
+ Object.defineProperty(o, k2, desc);
100479
+ }) : (function(o, m, k, k2) {
100480
+ if (k2 === undefined) k2 = k;
100481
+ o[k2] = m[k];
100482
+ }));
100483
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
100484
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
100485
+ }) : function(o, v) {
100486
+ o["default"] = v;
100487
+ });
100488
+ var __importStar = (this && this.__importStar) || (function () {
100489
+ var ownKeys = function(o) {
100490
+ ownKeys = Object.getOwnPropertyNames || function (o) {
100491
+ var ar = [];
100492
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
100493
+ return ar;
100494
+ };
100495
+ return ownKeys(o);
100496
+ };
100497
+ return function (mod) {
100498
+ if (mod && mod.__esModule) return mod;
100499
+ var result = {};
100500
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
100501
+ __setModuleDefault(result, mod);
100502
+ return result;
100503
+ };
100504
+ })();
100505
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
100506
+ exports.WrongAbapdocPosition = exports.WrongAbapdocPositionConf = void 0;
100507
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
100508
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
100509
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
100510
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
100511
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
100512
+ const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "../core/build/src/abap/2_statements/statements/_statement.js");
100513
+ class WrongAbapdocPositionConf extends _basic_rule_config_1.BasicRuleConfig {
100514
+ }
100515
+ exports.WrongAbapdocPositionConf = WrongAbapdocPositionConf;
100516
+ class WrongAbapdocPosition extends _abap_rule_1.ABAPRule {
100517
+ constructor() {
100518
+ super(...arguments);
100519
+ this.conf = new WrongAbapdocPositionConf();
100520
+ }
100521
+ getMetadata() {
100522
+ return {
100523
+ key: "wrong_abapdoc_position",
100524
+ title: "Wrong ABAP Doc position",
100525
+ shortDescription: `ABAP Doc must be placed directly in front of the declaration it documents.`,
100526
+ extendedInformation: `ABAP Doc documents the single declaration following it, an ABAP Doc block placed
100527
+ elsewhere is silently ignored, leaving the declaration undocumented.
100528
+
100529
+ The following positions are reported,
100530
+ * in front of a chained keyword, ie. before "CONSTANTS:" instead of after the colon,
100531
+ * in the middle of a statement, ie. between the parameters of a METHODS definition,
100532
+ * directly in front of ENDCLASS, ENDINTERFACE or a SECTION statement.
100533
+
100534
+ Only checks ABAP Doc inside class definitions and interfaces.`,
100535
+ tags: [_irule_1.RuleTag.SingleFile],
100536
+ badExample: `CLASS zcl_foo DEFINITION PUBLIC.
100537
+ PUBLIC SECTION.
100538
+ "! Navigation modes
100539
+ CONSTANTS:
100540
+ BEGIN OF cs_nav_mode,
100541
+ back TYPE i VALUE 1,
100542
+ END OF cs_nav_mode.
100543
+ ENDCLASS.`,
100544
+ goodExample: `CLASS zcl_foo DEFINITION PUBLIC.
100545
+ PUBLIC SECTION.
100546
+ CONSTANTS:
100547
+ "! Navigation modes
100548
+ BEGIN OF cs_nav_mode,
100549
+ back TYPE i VALUE 1,
100550
+ END OF cs_nav_mode.
100551
+ ENDCLASS.`,
100552
+ };
100553
+ }
100554
+ getConfig() {
100555
+ return this.conf;
100556
+ }
100557
+ setConfig(conf) {
100558
+ this.conf = conf;
100559
+ }
100560
+ runParsed(file) {
100561
+ const issues = [];
100562
+ const statements = file.getStatements();
100563
+ let definition = false;
100564
+ for (let i = 0; i < statements.length; i++) {
100565
+ const statement = statements[i];
100566
+ const type = statement.get();
100567
+ if (type instanceof Statements.ClassDefinition || type instanceof Statements.Interface) {
100568
+ definition = true;
100569
+ continue;
100570
+ }
100571
+ else if (type instanceof Statements.EndClass || type instanceof Statements.EndInterface) {
100572
+ definition = false;
100573
+ continue;
100574
+ }
100575
+ else if (definition === false || this.isAbapdoc(statement) === false) {
100576
+ continue;
100577
+ }
100578
+ else if (this.isAbapdoc(statements[i - 1]) === true
100579
+ && statements[i - 1].getStart().getRow() + 1 === statement.getStart().getRow()) {
100580
+ continue; // only report the first row of each block
100581
+ }
100582
+ let next = undefined;
100583
+ for (let j = i + 1; j < statements.length; j++) {
100584
+ if (statements[j].get() instanceof _statement_1.Comment) {
100585
+ continue;
100586
+ }
100587
+ next = statements[j];
100588
+ break;
100589
+ }
100590
+ if (next === undefined) {
100591
+ continue;
100592
+ }
100593
+ const message = this.check(statement, next);
100594
+ if (message !== undefined) {
100595
+ issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
100596
+ }
100597
+ }
100598
+ return issues;
100599
+ }
100600
+ isAbapdoc(statement) {
100601
+ return (statement === null || statement === void 0 ? void 0 : statement.get()) instanceof _statement_1.Comment
100602
+ && statement.getFirstToken().getStr().startsWith(`"!`);
100603
+ }
100604
+ check(abapdoc, next) {
100605
+ const type = next.get();
100606
+ if (type instanceof Statements.EndClass
100607
+ || type instanceof Statements.EndInterface
100608
+ || type instanceof Statements.Public
100609
+ || type instanceof Statements.Protected
100610
+ || type instanceof Statements.Private) {
100611
+ return "ABAP Doc does not document anything, move or delete it";
100612
+ }
100613
+ const position = abapdoc.getStart();
100614
+ const colon = next.getColon();
100615
+ if (colon === undefined) {
100616
+ if (position.isAfter(next.getStart()) === true) {
100617
+ return "ABAP Doc inside statement, move it in front of the statement";
100618
+ }
100619
+ return undefined;
100620
+ }
100621
+ if (position.isBefore(colon.getStart()) === true) {
100622
+ return "ABAP Doc in front of chained statement, move it after the colon";
100623
+ }
100624
+ const member = next.getTokens().find(t => t.getStart().isAfter(colon.getStart()));
100625
+ if (member !== undefined && position.isAfter(member.getStart()) === true) {
100626
+ return "ABAP Doc inside statement, move it in front of the chained declaration";
100627
+ }
100628
+ return undefined;
100629
+ }
100630
+ }
100631
+ exports.WrongAbapdocPosition = WrongAbapdocPosition;
100632
+ //# sourceMappingURL=wrong_abapdoc_position.js.map
100633
+
100634
+ /***/ },
100635
+
100442
100636
  /***/ "../core/build/src/rules/xml_bom.js"
100443
100637
  /*!******************************************!*\
100444
100638
  !*** ../core/build/src/rules/xml_bom.js ***!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.50",
3
+ "version": "2.120.51",
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.50",
42
+ "@abaplint/core": "^2.120.51",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",