@abaplint/cli 2.120.57 → 2.120.58

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 +414 -1
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -70685,7 +70685,7 @@ class Registry {
70685
70685
  }
70686
70686
  static abaplintVersion() {
70687
70687
  // magic, see build script "version.js"
70688
- return "2.120.57";
70688
+ return "2.120.58";
70689
70689
  }
70690
70690
  getDDICReferences() {
70691
70691
  return this.ddicReferences;
@@ -85081,7 +85081,9 @@ __exportStar(__webpack_require__(/*! ./prefer_insert_into_table */ "../core/buil
85081
85081
  __exportStar(__webpack_require__(/*! ./prefer_is_not */ "../core/build/src/rules/prefer_is_not.js"), exports);
85082
85082
  __exportStar(__webpack_require__(/*! ./prefer_pragmas */ "../core/build/src/rules/prefer_pragmas.js"), exports);
85083
85083
  __exportStar(__webpack_require__(/*! ./prefer_abap_bool */ "../core/build/src/rules/prefer_abap_bool.js"), exports);
85084
+ __exportStar(__webpack_require__(/*! ./prefer_abap_bool_values */ "../core/build/src/rules/prefer_abap_bool_values.js"), exports);
85084
85085
  __exportStar(__webpack_require__(/*! ./prefer_raise_exception_new */ "../core/build/src/rules/prefer_raise_exception_new.js"), exports);
85086
+ __exportStar(__webpack_require__(/*! ./prefer_string_template */ "../core/build/src/rules/prefer_string_template.js"), exports);
85085
85087
  __exportStar(__webpack_require__(/*! ./prefer_returning_to_exporting */ "../core/build/src/rules/prefer_returning_to_exporting.js"), exports);
85086
85088
  __exportStar(__webpack_require__(/*! ./prefer_xsdbool */ "../core/build/src/rules/prefer_xsdbool.js"), exports);
85087
85089
  __exportStar(__webpack_require__(/*! ./preferred_compare_operator */ "../core/build/src/rules/preferred_compare_operator.js"), exports);
@@ -92484,6 +92486,272 @@ exports.PreferAbapBool = PreferAbapBool;
92484
92486
 
92485
92487
  /***/ },
92486
92488
 
92489
+ /***/ "../core/build/src/rules/prefer_abap_bool_values.js"
92490
+ /*!**********************************************************!*\
92491
+ !*** ../core/build/src/rules/prefer_abap_bool_values.js ***!
92492
+ \**********************************************************/
92493
+ (__unused_webpack_module, exports, __webpack_require__) {
92494
+
92495
+ "use strict";
92496
+
92497
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
92498
+ if (k2 === undefined) k2 = k;
92499
+ var desc = Object.getOwnPropertyDescriptor(m, k);
92500
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
92501
+ desc = { enumerable: true, get: function() { return m[k]; } };
92502
+ }
92503
+ Object.defineProperty(o, k2, desc);
92504
+ }) : (function(o, m, k, k2) {
92505
+ if (k2 === undefined) k2 = k;
92506
+ o[k2] = m[k];
92507
+ }));
92508
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
92509
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
92510
+ }) : function(o, v) {
92511
+ o["default"] = v;
92512
+ });
92513
+ var __importStar = (this && this.__importStar) || (function () {
92514
+ var ownKeys = function(o) {
92515
+ ownKeys = Object.getOwnPropertyNames || function (o) {
92516
+ var ar = [];
92517
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
92518
+ return ar;
92519
+ };
92520
+ return ownKeys(o);
92521
+ };
92522
+ return function (mod) {
92523
+ if (mod && mod.__esModule) return mod;
92524
+ var result = {};
92525
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
92526
+ __setModuleDefault(result, mod);
92527
+ return result;
92528
+ };
92529
+ })();
92530
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
92531
+ exports.PreferAbapBoolValues = exports.PreferAbapBoolValuesConf = void 0;
92532
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
92533
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
92534
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
92535
+ const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "../core/build/src/abap/2_statements/statements/index.js"));
92536
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
92537
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
92538
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "../core/build/src/edit_helper.js");
92539
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "../core/build/src/abap/nodes/index.js");
92540
+ const ABAP_BOOL = "ABAP_BOOL";
92541
+ const ABAP_TRUE = "abap_true";
92542
+ const ABAP_FALSE = "abap_false";
92543
+ const VALID_VALUES = new Set(["ABAP_TRUE", "ABAP_FALSE", "ABAP_UNDEFINED"]);
92544
+ class PreferAbapBoolValuesConf extends _basic_rule_config_1.BasicRuleConfig {
92545
+ }
92546
+ exports.PreferAbapBoolValuesConf = PreferAbapBoolValuesConf;
92547
+ class PreferAbapBoolValues extends _abap_rule_1.ABAPRule {
92548
+ constructor() {
92549
+ super(...arguments);
92550
+ this.conf = new PreferAbapBoolValuesConf();
92551
+ }
92552
+ getMetadata() {
92553
+ return {
92554
+ key: "prefer_abap_bool_values",
92555
+ title: "Prefer abap_true and abap_false",
92556
+ shortDescription: `Use abap_true and abap_false instead of 'X' and ' ' for abap_bool variables`,
92557
+ // eslint-disable-next-line max-len
92558
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use-abap_true-abap_false-and-abap_undefined-for-abap_bool-variables`,
92559
+ tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
92560
+ badExample: `DATA lv_flag TYPE abap_bool.\nlv_flag = 'X'.`,
92561
+ goodExample: `DATA lv_flag TYPE abap_bool.\nlv_flag = abap_true.`,
92562
+ };
92563
+ }
92564
+ getConfig() {
92565
+ return this.conf;
92566
+ }
92567
+ setConfig(conf) {
92568
+ this.conf = conf;
92569
+ }
92570
+ runParsed(file) {
92571
+ const issues = [];
92572
+ const structure = file.getStructure();
92573
+ if (structure === undefined) {
92574
+ return [];
92575
+ }
92576
+ const boolVars = this.collectBoolVars(file);
92577
+ // Check Move statements: target = source
92578
+ for (const stat of structure.findAllStatements(Statements.Move)) {
92579
+ const target = stat.findFirstExpression(Expressions.Target);
92580
+ const source = stat.findFirstExpression(Expressions.Source);
92581
+ if (target === undefined || source === undefined) {
92582
+ continue;
92583
+ }
92584
+ const targetName = target.concatTokens().toUpperCase();
92585
+ if (!boolVars.has(targetName)) {
92586
+ continue;
92587
+ }
92588
+ this.checkSourceNode(source, file, issues);
92589
+ }
92590
+ // Check comparisons: IF/ELSEIF conditions
92591
+ const compareStatements = [
92592
+ ...structure.findAllStatements(Statements.If),
92593
+ ...structure.findAllStatements(Statements.ElseIf),
92594
+ ];
92595
+ for (const stat of compareStatements) {
92596
+ const cond = stat.findFirstExpression(Expressions.Cond);
92597
+ if (cond === undefined) {
92598
+ continue;
92599
+ }
92600
+ for (const compare of cond.findAllExpressions(Expressions.Compare)) {
92601
+ this.checkCompareBoolLiteral(compare, boolVars, file, issues);
92602
+ }
92603
+ }
92604
+ return issues;
92605
+ }
92606
+ collectBoolVars(file) {
92607
+ var _a;
92608
+ const boolVars = new Set();
92609
+ const structure = file.getStructure();
92610
+ if (structure === undefined) {
92611
+ return boolVars;
92612
+ }
92613
+ const statements = [
92614
+ ...structure.findAllStatements(Statements.Data),
92615
+ ...structure.findAllStatements(Statements.ClassData),
92616
+ ...structure.findAllStatements(Statements.FieldSymbol),
92617
+ ];
92618
+ for (const stat of statements) {
92619
+ const typeNameExpr = stat.findFirstExpression(Expressions.TypeName);
92620
+ if (typeNameExpr === undefined) {
92621
+ continue;
92622
+ }
92623
+ if (typeNameExpr.concatTokens().toUpperCase() !== ABAP_BOOL) {
92624
+ continue;
92625
+ }
92626
+ const nameExpr = (_a = stat.findFirstExpression(Expressions.DefinitionName)) !== null && _a !== void 0 ? _a : stat.findFirstExpression(Expressions.FieldSymbol);
92627
+ if (nameExpr === undefined) {
92628
+ continue;
92629
+ }
92630
+ boolVars.add(nameExpr.concatTokens().toUpperCase());
92631
+ }
92632
+ return boolVars;
92633
+ }
92634
+ checkSourceNode(source, file, issues) {
92635
+ const firstToken = source.getFirstToken().getStr().toUpperCase();
92636
+ if (firstToken === "COND") {
92637
+ const condBody = source.findDirectExpression(Expressions.CondBody);
92638
+ if (condBody) {
92639
+ this.checkCondBodyBranches(condBody, file, issues);
92640
+ }
92641
+ return;
92642
+ }
92643
+ if (firstToken === "SWITCH") {
92644
+ const switchBody = source.findDirectExpression(Expressions.SwitchBody);
92645
+ if (switchBody) {
92646
+ this.checkSwitchBodyBranches(switchBody, file, issues);
92647
+ }
92648
+ return;
92649
+ }
92650
+ // Plain literal assignment
92651
+ const issue = this.checkLiteralSource(source, file);
92652
+ if (issue) {
92653
+ issues.push(issue);
92654
+ }
92655
+ }
92656
+ checkLiteralSource(source, file) {
92657
+ const constantStr = source.findFirstExpression(Expressions.ConstantString);
92658
+ if (constantStr === undefined) {
92659
+ return undefined;
92660
+ }
92661
+ const token = constantStr.getFirstToken();
92662
+ const val = token.getStr();
92663
+ if (val === "'X'") {
92664
+ const fix = edit_helper_1.EditHelper.replaceToken(file, token, ABAP_TRUE);
92665
+ return issue_1.Issue.atToken(file, token, `Use ${ABAP_TRUE} instead of 'X'`, this.getMetadata().key, this.conf.severity, fix);
92666
+ }
92667
+ if (val === "' '") {
92668
+ const fix = edit_helper_1.EditHelper.replaceToken(file, token, ABAP_FALSE);
92669
+ return issue_1.Issue.atToken(file, token, `Use ${ABAP_FALSE} instead of ' '`, this.getMetadata().key, this.conf.severity, fix);
92670
+ }
92671
+ return undefined;
92672
+ }
92673
+ checkCondBodyBranches(condBody, file, issues) {
92674
+ // CondBody: WHEN <cond> THEN <source> [WHEN <cond> THEN <source>]* [ELSE <source>]
92675
+ // Walk children; Source nodes after THEN/ELSE are the result values
92676
+ let afterThenOrElse = false;
92677
+ for (const child of condBody.getChildren()) {
92678
+ const tokenStr = child.getFirstToken().getStr().toUpperCase();
92679
+ if (tokenStr === "THEN" || tokenStr === "ELSE") {
92680
+ afterThenOrElse = true;
92681
+ continue;
92682
+ }
92683
+ if (tokenStr === "WHEN") {
92684
+ afterThenOrElse = false;
92685
+ continue;
92686
+ }
92687
+ if (afterThenOrElse && child instanceof nodes_1.ExpressionNode && child.get() instanceof Expressions.Source) {
92688
+ const issue = this.checkLiteralSource(child, file);
92689
+ if (issue) {
92690
+ issues.push(issue);
92691
+ }
92692
+ afterThenOrElse = false;
92693
+ }
92694
+ }
92695
+ }
92696
+ checkSwitchBodyBranches(switchBody, file, issues) {
92697
+ // SwitchBody: <source> WHEN <val> [OR <val>]* THEN <source> [ELSE <source>]
92698
+ // First Source is the operand; Source after THEN/ELSE are result values
92699
+ let firstSourceSeen = false;
92700
+ let afterThenOrElse = false;
92701
+ for (const child of switchBody.getChildren()) {
92702
+ const tokenStr = child.getFirstToken().getStr().toUpperCase();
92703
+ if (tokenStr === "THEN" || tokenStr === "ELSE") {
92704
+ afterThenOrElse = true;
92705
+ continue;
92706
+ }
92707
+ if (tokenStr === "WHEN" || tokenStr === "OR") {
92708
+ afterThenOrElse = false;
92709
+ continue;
92710
+ }
92711
+ if (child instanceof nodes_1.ExpressionNode && child.get() instanceof Expressions.Source) {
92712
+ if (!firstSourceSeen) {
92713
+ firstSourceSeen = true;
92714
+ continue;
92715
+ }
92716
+ if (afterThenOrElse) {
92717
+ const issue = this.checkLiteralSource(child, file);
92718
+ if (issue) {
92719
+ issues.push(issue);
92720
+ }
92721
+ afterThenOrElse = false;
92722
+ }
92723
+ }
92724
+ }
92725
+ }
92726
+ checkCompareBoolLiteral(compare, boolVars, file, issues) {
92727
+ // Compare: Source CompareOperator Source (or other forms)
92728
+ const sources = compare.findDirectExpressions(Expressions.Source);
92729
+ if (sources.length < 2) {
92730
+ return;
92731
+ }
92732
+ const [left, right] = sources;
92733
+ const leftStr = left.concatTokens().toUpperCase();
92734
+ const rightStr = right.concatTokens().toUpperCase();
92735
+ let literalSource;
92736
+ if (boolVars.has(leftStr) && !VALID_VALUES.has(rightStr)) {
92737
+ literalSource = right;
92738
+ }
92739
+ else if (boolVars.has(rightStr) && !VALID_VALUES.has(leftStr)) {
92740
+ literalSource = left;
92741
+ }
92742
+ if (literalSource) {
92743
+ const issue = this.checkLiteralSource(literalSource, file);
92744
+ if (issue) {
92745
+ issues.push(issue);
92746
+ }
92747
+ }
92748
+ }
92749
+ }
92750
+ exports.PreferAbapBoolValues = PreferAbapBoolValues;
92751
+ //# sourceMappingURL=prefer_abap_bool_values.js.map
92752
+
92753
+ /***/ },
92754
+
92487
92755
  /***/ "../core/build/src/rules/prefer_corresponding.js"
92488
92756
  /*!*******************************************************!*\
92489
92757
  !*** ../core/build/src/rules/prefer_corresponding.js ***!
@@ -93473,6 +93741,151 @@ exports.PreferReturningToExporting = PreferReturningToExporting;
93473
93741
 
93474
93742
  /***/ },
93475
93743
 
93744
+ /***/ "../core/build/src/rules/prefer_string_template.js"
93745
+ /*!*********************************************************!*\
93746
+ !*** ../core/build/src/rules/prefer_string_template.js ***!
93747
+ \*********************************************************/
93748
+ (__unused_webpack_module, exports, __webpack_require__) {
93749
+
93750
+ "use strict";
93751
+
93752
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
93753
+ if (k2 === undefined) k2 = k;
93754
+ var desc = Object.getOwnPropertyDescriptor(m, k);
93755
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
93756
+ desc = { enumerable: true, get: function() { return m[k]; } };
93757
+ }
93758
+ Object.defineProperty(o, k2, desc);
93759
+ }) : (function(o, m, k, k2) {
93760
+ if (k2 === undefined) k2 = k;
93761
+ o[k2] = m[k];
93762
+ }));
93763
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
93764
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
93765
+ }) : function(o, v) {
93766
+ o["default"] = v;
93767
+ });
93768
+ var __importStar = (this && this.__importStar) || (function () {
93769
+ var ownKeys = function(o) {
93770
+ ownKeys = Object.getOwnPropertyNames || function (o) {
93771
+ var ar = [];
93772
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
93773
+ return ar;
93774
+ };
93775
+ return ownKeys(o);
93776
+ };
93777
+ return function (mod) {
93778
+ if (mod && mod.__esModule) return mod;
93779
+ var result = {};
93780
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
93781
+ __setModuleDefault(result, mod);
93782
+ return result;
93783
+ };
93784
+ })();
93785
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
93786
+ exports.PreferStringTemplate = exports.PreferStringTemplateConf = void 0;
93787
+ const issue_1 = __webpack_require__(/*! ../issue */ "../core/build/src/issue.js");
93788
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "../core/build/src/rules/_abap_rule.js");
93789
+ const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
93790
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "../core/build/src/rules/_basic_rule_config.js");
93791
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "../core/build/src/rules/_irule.js");
93792
+ const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "../core/build/src/abap/nodes/index.js");
93793
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "../core/build/src/edit_helper.js");
93794
+ class PreferStringTemplateConf extends _basic_rule_config_1.BasicRuleConfig {
93795
+ }
93796
+ exports.PreferStringTemplateConf = PreferStringTemplateConf;
93797
+ class PreferStringTemplate extends _abap_rule_1.ABAPRule {
93798
+ constructor() {
93799
+ super(...arguments);
93800
+ this.conf = new PreferStringTemplateConf();
93801
+ }
93802
+ getMetadata() {
93803
+ return {
93804
+ key: "prefer_string_template",
93805
+ title: "Prefer string template over &&",
93806
+ shortDescription: `Use string templates instead of && to assemble text`,
93807
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#use--to-assemble-text`,
93808
+ tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
93809
+ badExample: `DATA(msg) = \`Hello \` && name && \`!\`.`,
93810
+ goodExample: `DATA(msg) = |Hello { name }!|.`,
93811
+ };
93812
+ }
93813
+ getConfig() {
93814
+ return this.conf;
93815
+ }
93816
+ setConfig(conf) {
93817
+ this.conf = conf;
93818
+ }
93819
+ runParsed(file) {
93820
+ const issues = [];
93821
+ const structure = file.getStructure();
93822
+ if (structure === undefined) {
93823
+ return [];
93824
+ }
93825
+ const allSources = structure.findAllExpressions(Expressions.Source);
93826
+ // collect all Source nodes that appear as the RHS (children[2]) of a && expression
93827
+ const rhsChildren = new Set();
93828
+ for (const source of allSources) {
93829
+ const children = source.getChildren();
93830
+ if (children.length === 3 && children[1].getFirstToken().getStr() === "&&") {
93831
+ rhsChildren.add(children[2]);
93832
+ }
93833
+ }
93834
+ for (const source of allSources) {
93835
+ const children = source.getChildren();
93836
+ if (children.length !== 3) {
93837
+ continue;
93838
+ }
93839
+ if (children[1].getFirstToken().getStr() !== "&&") {
93840
+ continue;
93841
+ }
93842
+ // only process top-level && roots (not nested RHS children)
93843
+ if (rhsChildren.has(source)) {
93844
+ continue;
93845
+ }
93846
+ const operands = this.flattenChain(source);
93847
+ if (!operands.some(op => { const c = op.getFirstToken().getStr()[0]; return c === "'" || c === "`"; })) {
93848
+ continue;
93849
+ }
93850
+ const template = this.buildTemplate(operands);
93851
+ const start = source.getFirstToken().getStart();
93852
+ const end = source.getLastToken().getEnd();
93853
+ const fix = edit_helper_1.EditHelper.replaceRange(file, start, end, template);
93854
+ const token = children[1].getFirstToken();
93855
+ issues.push(issue_1.Issue.atToken(file, token, "Use string template instead of &&", this.getMetadata().key, this.conf.severity, fix));
93856
+ }
93857
+ return issues;
93858
+ }
93859
+ flattenChain(node) {
93860
+ const children = node.getChildren();
93861
+ if (children.length === 3 && children[1].getFirstToken().getStr() === "&&") {
93862
+ return [...this.flattenChain(children[0]), ...this.flattenChain(children[2])];
93863
+ }
93864
+ if (children.length === 1 && children[0] instanceof nodes_1.ExpressionNode) {
93865
+ return this.flattenChain(children[0]);
93866
+ }
93867
+ return [node];
93868
+ }
93869
+ buildTemplate(operands) {
93870
+ let inner = "";
93871
+ for (const op of operands) {
93872
+ const raw = op.getFirstToken().getStr();
93873
+ const firstChar = raw[0];
93874
+ if (firstChar === "'" || firstChar === "`") {
93875
+ inner += raw.slice(1, -1);
93876
+ }
93877
+ else {
93878
+ inner += `{ ${op.concatTokens()} }`;
93879
+ }
93880
+ }
93881
+ return `|${inner}|`;
93882
+ }
93883
+ }
93884
+ exports.PreferStringTemplate = PreferStringTemplate;
93885
+ //# sourceMappingURL=prefer_string_template.js.map
93886
+
93887
+ /***/ },
93888
+
93476
93889
  /***/ "../core/build/src/rules/prefer_xsdbool.js"
93477
93890
  /*!*************************************************!*\
93478
93891
  !*** ../core/build/src/rules/prefer_xsdbool.js ***!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.57",
3
+ "version": "2.120.58",
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.57",
42
+ "@abaplint/core": "^2.120.58",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",