@abaplint/cli 2.113.217 → 2.113.219

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 +86 -19
  2. package/package.json +7 -7
package/build/cli.js CHANGED
@@ -437,7 +437,7 @@ class CodeClimate {
437
437
  end: issue.getEnd().getRow(),
438
438
  },
439
439
  },
440
- severity: (severityArray.includes(issue.getSeverity().toLowerCase())) ? issue.getSeverity().toLowerCase() : defaultSeverity,
440
+ severity: severityArray.includes(issue.getSeverity().toLowerCase()) ? issue.getSeverity().toLowerCase() : defaultSeverity,
441
441
  fingerprint: md5(issue.getKey() + issue.getMessage() + issue.getFilename() + issue.getStart().getRow() + issue.getEnd().getRow()),
442
442
  };
443
443
  out.push(single);
@@ -478,7 +478,7 @@ class CodeFrame {
478
478
  const builtIssues = this.convertAllIssues(issues).sort(issueSort); // Make sure it is sorted by filename for caching to work
479
479
  return [
480
480
  ...builtIssues.map(i => this.renderIssue(i)),
481
- (issues.length > 0 ? chalk_1.default.red(new total_1.Total().output(issues, fileCount)) : chalk_1.default.green(new total_1.Total().output(issues, fileCount))),
481
+ issues.length > 0 ? chalk_1.default.red(new total_1.Total().output(issues, fileCount)) : chalk_1.default.green(new total_1.Total().output(issues, fileCount)),
482
482
  ].join("\n");
483
483
  }
484
484
  convertAllIssues(issues) {
@@ -737,7 +737,7 @@ class Sonarqube {
737
737
  const single = {
738
738
  engineId: "abaplint",
739
739
  ruleId: issue.getKey(),
740
- severity: (severityArray.includes(issue.getSeverity().toUpperCase())) ? issue.getSeverity().toUpperCase() : defaultSeverity,
740
+ severity: severityArray.includes(issue.getSeverity().toUpperCase()) ? issue.getSeverity().toUpperCase() : defaultSeverity,
741
741
  type: "CODE_SMELL",
742
742
  primaryLocation: {
743
743
  message: issue.getMessage(),
@@ -1192,7 +1192,7 @@ class Rename {
1192
1192
  continue;
1193
1193
  }
1194
1194
  for (const p of rconfig.patterns || []) {
1195
- if (!(o.getType().match(p.type))) {
1195
+ if (!o.getType().match(p.type)) {
1196
1196
  continue;
1197
1197
  }
1198
1198
  const regex = new RegExp(p.oldName, "i");
@@ -23835,7 +23835,7 @@ class TypeUtils {
23835
23835
  if (!(sourceRowType instanceof basic_1.StructureType)) {
23836
23836
  return false;
23837
23837
  }
23838
- else if (!(this.structureContainsString(sourceRowType))
23838
+ else if (!this.structureContainsString(sourceRowType)
23839
23839
  && this.structureContainsVoid(sourceRowType) === false) {
23840
23840
  return false;
23841
23841
  }
@@ -23845,7 +23845,7 @@ class TypeUtils {
23845
23845
  if (!(targetRowType instanceof basic_1.StructureType)) {
23846
23846
  return false;
23847
23847
  }
23848
- else if (!(this.structureContainsString(targetRowType))
23848
+ else if (!this.structureContainsString(targetRowType)
23849
23849
  && this.structureContainsVoid(targetRowType) === false) {
23850
23850
  return false;
23851
23851
  }
@@ -25643,7 +25643,7 @@ class CorrespondingBody {
25643
25643
  }
25644
25644
  const base = (_a = node.findDirectExpression(Expressions.CorrespondingBodyBase)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Source);
25645
25645
  if (base) {
25646
- source_1.Source.runSyntax(base, input);
25646
+ source_1.Source.runSyntax(base, input, targetType);
25647
25647
  }
25648
25648
  let type = undefined;
25649
25649
  for (const s of node.findDirectExpressions(Expressions.Source)) {
@@ -54549,7 +54549,7 @@ class Registry {
54549
54549
  }
54550
54550
  static abaplintVersion() {
54551
54551
  // magic, see build script "version.sh"
54552
- return "2.113.217";
54552
+ return "2.113.219";
54553
54553
  }
54554
54554
  getDDICReferences() {
54555
54555
  return this.ddicReferences;
@@ -60587,7 +60587,6 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
60587
60587
  const source = high.findExpressionAfterToken("MESSAGE");
60588
60588
  if ((source === null || source === void 0 ? void 0 : source.get()) instanceof Expressions.MessageSourceSource
60589
60589
  && ((_a = source.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Source) {
60590
- ;
60591
60590
  const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
60592
60591
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
60593
60592
  const firstToken = high.getFirstToken();
@@ -64019,7 +64018,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
64019
64018
  for (const stat of file.getStatements()) {
64020
64019
  if ((stat.get() instanceof Statements.Constant
64021
64020
  || (this.conf.checkData === true && stat.get() instanceof Statements.Data))
64022
- && (!this.isTyped(stat))) {
64021
+ && !this.isTyped(stat)) {
64023
64022
  const type = stat.get() instanceof Statements.Constant ? "constant definition" : "data definition";
64024
64023
  let token = (_a = stat.findFirstExpression(expressions_1.NamespaceSimpleName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
64025
64024
  if (token === undefined) {
@@ -64034,7 +64033,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
64034
64033
  return issues;
64035
64034
  }
64036
64035
  isTyped(stat) {
64037
- return (stat.findFirstExpression(expressions_1.Type) || stat.findFirstExpression(expressions_1.TypeTable));
64036
+ return stat.findFirstExpression(expressions_1.Type) || stat.findFirstExpression(expressions_1.TypeTable);
64038
64037
  }
64039
64038
  }
64040
64039
  exports.FullyTypeConstants = FullyTypeConstants;
@@ -65144,7 +65143,15 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
65144
65143
  const issue = issue_1.Issue.atIdentifier(found, "Do not implement abstract method \"" + md.name + "\"", this.getMetadata().key, this.conf.severity);
65145
65144
  ret.push(issue);
65146
65145
  }
65147
- continue;
65146
+ if (def.isAbstract) {
65147
+ continue;
65148
+ }
65149
+ else {
65150
+ const message = "Abstract methods can only be defined in abstract classes.";
65151
+ const issue = issue_1.Issue.atIdentifier(def.identifier, message, this.getMetadata().key, this.conf.severity);
65152
+ ret.push(issue);
65153
+ break;
65154
+ }
65148
65155
  }
65149
65156
  if (impl === undefined) {
65150
65157
  const message = "Class implementation for \"" + def.name + "\" not found";
@@ -65247,8 +65254,16 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
65247
65254
  return [idef];
65248
65255
  }
65249
65256
  for (const m of this.findInterfaceMethods(idef)) {
65250
- if (interfaceInfo.abstractMethods.includes(m.method.name.toUpperCase())) {
65251
- continue;
65257
+ if (this.isAbstract(m, interfaceInfo, def)) {
65258
+ if (def.isAbstract) {
65259
+ continue;
65260
+ }
65261
+ else {
65262
+ const message = "Abstract methods can only be defined in abstract classes.";
65263
+ const issue = issue_1.Issue.atIdentifier(def.identifier, message, this.getMetadata().key, this.conf.severity);
65264
+ ret.push(issue);
65265
+ break;
65266
+ }
65252
65267
  }
65253
65268
  if (this.isImplemented(m, def, impl) === false) {
65254
65269
  const message = "Implement method \"" + m.method.name + "\" from interface \"" + m.objectName + "\"";
@@ -65266,6 +65281,23 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
65266
65281
  }
65267
65282
  return ret;
65268
65283
  }
65284
+ isAbstract(m, interfaceInfo, def) {
65285
+ if (interfaceInfo.abstractMethods.includes(m.method.name.toUpperCase())) {
65286
+ return true;
65287
+ }
65288
+ if (!def.superClassName) {
65289
+ return false;
65290
+ }
65291
+ // look up in superclass if method is abstract there
65292
+ const superClass = this.findClass(def.superClassName);
65293
+ const superInterface = superClass === null || superClass === void 0 ? void 0 : superClass.def.interfaces.find(iface => iface.name.toUpperCase() === m.objectName.toUpperCase());
65294
+ if (superClass && superInterface) {
65295
+ return this.isAbstract(m, superInterface, superClass.def);
65296
+ }
65297
+ else {
65298
+ return false;
65299
+ }
65300
+ }
65269
65301
  isImplemented(m, def, impl) {
65270
65302
  if (impl === undefined) {
65271
65303
  return false;
@@ -70646,6 +70678,7 @@ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@ab
70646
70678
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
70647
70679
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
70648
70680
  const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
70681
+ const __1 = __webpack_require__(/*! .. */ "./node_modules/@abaplint/core/build/src/index.js");
70649
70682
  class Parser702ChainingConf extends _basic_rule_config_1.BasicRuleConfig {
70650
70683
  }
70651
70684
  exports.Parser702ChainingConf = Parser702ChainingConf;
@@ -70657,7 +70690,7 @@ class Parser702Chaining extends _abap_rule_1.ABAPRule {
70657
70690
  getMetadata() {
70658
70691
  return {
70659
70692
  key: "parser_702_chaining",
70660
- title: "Parser Error, bad chanining on 702",
70693
+ title: "Parser Error, bad chaining on 702",
70661
70694
  shortDescription: `ABAP on 702 does not allow for method chaining with IMPORTING/EXPORTING/CHANGING keywords,
70662
70695
  this rule finds these and reports errors.
70663
70696
  Only active on target version 702 and below.`,
@@ -70698,13 +70731,47 @@ Only active on target version 702 and below.`,
70698
70731
  || param.findDirectTokenByText("CHANGING")
70699
70732
  || param.findDirectTokenByText("EXCEPTIONS")) {
70700
70733
  const message = "This kind of method chaining not possible in 702";
70701
- const issue = issue_1.Issue.atPosition(file, param.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity);
70702
- issues.push(issue);
70734
+ this.pushIssue(message, file, param, issues);
70735
+ }
70736
+ }
70737
+ }
70738
+ // after a value assignment (move statement whose source is a method call, or method parameter assignment),
70739
+ // there can't be any EXPORTING/IMPORTING/CHANGING/EXCEPTIONS
70740
+ for (const statement of file.getStatements()) {
70741
+ if (!(statement.get() instanceof __1.Statements.Move)) {
70742
+ continue;
70743
+ }
70744
+ const source = statement.findDirectExpression(Expressions.Source);
70745
+ if (source === undefined) {
70746
+ continue;
70747
+ }
70748
+ this.ensureSourceHasNoProceduralKeywords(source, file, issues);
70749
+ }
70750
+ for (const methodParameters of stru.findAllExpressions(Expressions.MethodParameters)) {
70751
+ for (const params of methodParameters.findAllExpressions(Expressions.ParameterS)) {
70752
+ const source = params.findDirectExpression(Expressions.Source);
70753
+ if (source === undefined) {
70754
+ continue;
70703
70755
  }
70756
+ this.ensureSourceHasNoProceduralKeywords(source, file, issues);
70704
70757
  }
70705
70758
  }
70706
70759
  return issues;
70707
70760
  }
70761
+ ensureSourceHasNoProceduralKeywords(source, file, issues) {
70762
+ const forbiddenTokens = ["EXPORTING", "IMPORTING", "CHANGING", "EXCEPTIONS"];
70763
+ for (const param of source.findAllExpressions(Expressions.MethodParameters)) {
70764
+ const usedForbiddenToken = forbiddenTokens.find(text => param.findDirectTokenByText(text));
70765
+ if (usedForbiddenToken) {
70766
+ const message = `Unexpected word ${usedForbiddenToken} in functional method call`;
70767
+ this.pushIssue(message, file, param, issues);
70768
+ }
70769
+ }
70770
+ }
70771
+ pushIssue(message, file, node, issues) {
70772
+ const issue = issue_1.Issue.atPosition(file, node.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity);
70773
+ issues.push(issue);
70774
+ }
70708
70775
  }
70709
70776
  exports.Parser702Chaining = Parser702Chaining;
70710
70777
  //# sourceMappingURL=parser_702_chaining.js.map
@@ -75628,9 +75695,9 @@ ENDFORM.`,
75628
75695
  for (let i = 0; i < statements.length; i++) {
75629
75696
  const node = statements[i];
75630
75697
  const nodeType = node.get();
75631
- if ((nodeType instanceof Statements.MethodImplementation
75698
+ if (nodeType instanceof Statements.MethodImplementation
75632
75699
  || nodeType instanceof Statements.Form
75633
- || nodeType instanceof Statements.FunctionModule)) {
75700
+ || nodeType instanceof Statements.FunctionModule) {
75634
75701
  statementCounter = 0;
75635
75702
  continue;
75636
75703
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.113.217",
3
+ "version": "2.113.219",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -38,11 +38,11 @@
38
38
  },
39
39
  "homepage": "https://abaplint.org",
40
40
  "devDependencies": {
41
- "@abaplint/core": "^2.113.217",
41
+ "@abaplint/core": "^2.113.219",
42
42
  "@types/chai": "^4.3.20",
43
43
  "@types/minimist": "^1.2.5",
44
44
  "@types/mocha": "^10.0.10",
45
- "@types/node": "^24.5.2",
45
+ "@types/node": "^24.6.2",
46
46
  "@types/progress": "^2.0.7",
47
47
  "chai": "^4.5.0",
48
48
  "p-limit": "^3.1.0",
@@ -50,12 +50,12 @@
50
50
  "eslint": "^9.36.0",
51
51
  "glob": "^11.0.3",
52
52
  "json5": "^2.2.3",
53
- "memfs": "^4.46.1",
53
+ "memfs": "^4.48.1",
54
54
  "minimist": "^1.2.8",
55
- "mocha": "^11.7.2",
55
+ "mocha": "^11.7.4",
56
56
  "progress": "^2.0.3",
57
- "typescript": "^5.9.2",
58
- "webpack": "^5.101.3",
57
+ "typescript": "^5.9.3",
58
+ "webpack": "^5.102.0",
59
59
  "webpack-cli": "^6.0.1",
60
60
  "xml-js": "^1.6.11"
61
61
  }