@abaplint/core 2.95.39 → 2.95.41

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.
@@ -1328,6 +1328,10 @@ declare class CustomizingTransaction extends AbstractObject {
1328
1328
  getDescription(): string | undefined;
1329
1329
  }
1330
1330
 
1331
+ export declare class CyclomaticComplexityStats {
1332
+ static run(obj: IObject): ICyclomaticComplexityResult[];
1333
+ }
1334
+
1331
1335
  declare class Dash extends Token {
1332
1336
  static railroad(): string;
1333
1337
  }
@@ -2799,6 +2803,13 @@ export declare interface IConfiguration {
2799
2803
  readByKey(rule: string, key: string): any;
2800
2804
  }
2801
2805
 
2806
+ declare interface ICyclomaticComplexityResult {
2807
+ file: IFile;
2808
+ pos: Position;
2809
+ name: string;
2810
+ count: number;
2811
+ }
2812
+
2802
2813
  declare interface IDDICReferences {
2803
2814
  setUsing(obj: IObject, using: readonly IObjectAndToken[]): void;
2804
2815
  addUsing(obj: IObject, using: IObjectAndToken | undefined): void;
@@ -5819,7 +5830,7 @@ export { Structures }
5819
5830
  declare class StructureType extends AbstractType {
5820
5831
  private readonly indexed;
5821
5832
  private readonly components;
5822
- constructor(components: IStructureComponent[], qualifiedName?: string);
5833
+ constructor(components: IStructureComponent[], qualifiedName?: string, ddicName?: string);
5823
5834
  getComponents(): IStructureComponent[];
5824
5835
  getComponentByName(name: string): AbstractType | undefined;
5825
5836
  toText(level: number): string;
@@ -330,7 +330,10 @@ class Lexer {
330
330
  const ahead = this.stream.nextChar();
331
331
  const aahead = this.stream.nextNextChar();
332
332
  if (this.m === this.ModeNormal) {
333
- if (ahead === "'") {
333
+ if (splits[ahead]) {
334
+ this.add();
335
+ }
336
+ else if (ahead === "'") {
334
337
  // start string
335
338
  this.add();
336
339
  this.m = this.ModeStr;
@@ -356,9 +359,6 @@ class Lexer {
356
359
  this.add();
357
360
  this.m = this.ModeComment;
358
361
  }
359
- else if (splits[ahead]) {
360
- this.add();
361
- }
362
362
  else if (ahead === "@" && buf.trim().length === 0) {
363
363
  this.add();
364
364
  }
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StructureType = void 0;
4
4
  const _abstract_type_1 = require("./_abstract_type");
5
5
  class StructureType extends _abstract_type_1.AbstractType {
6
- constructor(components, qualifiedName) {
7
- super({ qualifiedName: qualifiedName });
6
+ constructor(components, qualifiedName, ddicName) {
7
+ super({
8
+ qualifiedName: qualifiedName,
9
+ ddicName: ddicName,
10
+ });
8
11
  if (components.length === 0) {
9
12
  throw new Error("Structure does not contain any components");
10
13
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RuleTag = exports.Severity = exports.Visibility = exports.Info = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = exports.ABAPFile = exports.RulesRunner = exports.SpaghettiScope = exports.SyntaxLogic = exports.ABAPObject = exports.Tokens = exports.ExpressionsCDS = exports.CDSParser = exports.LanguageServerTypes = exports.DDLParser = exports.applyEditList = exports.applyEditSingle = exports.SpaghettiScopeNode = exports.AbstractFile = exports.Token = exports.ScopeType = exports.BasicTypes = exports.TypedIdentifier = exports.AbstractType = exports.VirtualPosition = exports.Comment = exports.Unknown = exports.Empty = exports.Identifier = exports.Nodes = exports.Types = exports.Expressions = exports.Statements = exports.Structures = exports.Objects = exports.ArtifactsRules = exports.ArtifactsObjects = exports.ArtifactsABAP = exports.BuiltIn = exports.MethodLengthStats = exports.LanguageServer = exports.Registry = exports.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
3
+ exports.Severity = exports.Visibility = exports.Info = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = exports.ABAPFile = exports.RulesRunner = exports.SpaghettiScope = exports.SyntaxLogic = exports.ABAPObject = exports.Tokens = exports.ExpressionsCDS = exports.CDSParser = exports.LanguageServerTypes = exports.DDLParser = exports.applyEditList = exports.applyEditSingle = exports.SpaghettiScopeNode = exports.AbstractFile = exports.Token = exports.ScopeType = exports.BasicTypes = exports.TypedIdentifier = exports.AbstractType = exports.VirtualPosition = exports.Comment = exports.Unknown = exports.Empty = exports.Identifier = exports.Nodes = exports.Types = exports.Expressions = exports.Statements = exports.Structures = exports.Objects = exports.ArtifactsRules = exports.ArtifactsObjects = exports.ArtifactsABAP = exports.BuiltIn = exports.MethodLengthStats = exports.LanguageServer = exports.Registry = exports.CyclomaticComplexityStats = exports.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
4
+ exports.RuleTag = void 0;
4
5
  const issue_1 = require("./issue");
5
6
  Object.defineProperty(exports, "Issue", { enumerable: true, get: function () { return issue_1.Issue; } });
6
7
  const config_1 = require("./config");
@@ -96,4 +97,6 @@ const rules_runner_1 = require("./rules_runner");
96
97
  Object.defineProperty(exports, "RulesRunner", { enumerable: true, get: function () { return rules_runner_1.RulesRunner; } });
97
98
  const _irule_1 = require("./rules/_irule");
98
99
  Object.defineProperty(exports, "RuleTag", { enumerable: true, get: function () { return _irule_1.RuleTag; } });
100
+ const cyclomatic_complexity_stats_1 = require("./utils/cyclomatic_complexity_stats");
101
+ Object.defineProperty(exports, "CyclomaticComplexityStats", { enumerable: true, get: function () { return cyclomatic_complexity_stats_1.CyclomaticComplexityStats; } });
99
102
  //# sourceMappingURL=index.js.map
@@ -231,7 +231,7 @@ class Table extends _abstract_object_1.AbstractObject {
231
231
  return new Types.UnknownType("Table/Structure " + this.getName() + " does not contain any components");
232
232
  }
233
233
  reg.getDDICReferences().setUsing(this, references);
234
- return new Types.StructureType(components, this.getName());
234
+ return new Types.StructureType(components, this.getName(), this.getName());
235
235
  }
236
236
  getTableCategory() {
237
237
  var _a;
@@ -31,7 +31,6 @@ exports.Position = Position;
31
31
  class VirtualPosition extends Position {
32
32
  constructor(virtual, row, col) {
33
33
  super(virtual.getRow(), virtual.getCol());
34
- // this.virtual = virtual;
35
34
  this.vrow = row;
36
35
  this.vcol = col;
37
36
  }
@@ -39,7 +38,8 @@ class VirtualPosition extends Position {
39
38
  if (!(p instanceof VirtualPosition)) {
40
39
  return false;
41
40
  }
42
- return super.equals(this) && this.vrow === p.vrow && this.vcol === p.vcol;
41
+ const casted = p;
42
+ return super.equals(this) && this.vrow === casted.vrow && this.vcol === casted.vcol;
43
43
  }
44
44
  }
45
45
  exports.VirtualPosition = VirtualPosition;
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.95.39";
66
+ return "2.95.41";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -25,6 +25,7 @@ const include_graph_1 = require("../utils/include_graph");
25
25
  const objects_1 = require("../objects");
26
26
  const _builtin_1 = require("../abap/5_syntax/_builtin");
27
27
  const _scope_type_1 = require("../abap/5_syntax/_scope_type");
28
+ const statements_1 = require("../abap/2_statements/statements");
28
29
  // todo: refactor each sub-rule to new classes?
29
30
  // todo: add configuration
30
31
  class DownportConf extends _basic_rule_config_1.BasicRuleConfig {
@@ -430,7 +431,7 @@ Only one transformation is applied to a statement at a time, so multiple steps m
430
431
  if (found) {
431
432
  return found;
432
433
  }
433
- found = this.replaceLineFunctions(high, lowFile, highSyntax);
434
+ found = this.replaceLineFunctions(high, lowFile, highSyntax, highFile);
434
435
  if (found) {
435
436
  return found;
436
437
  }
@@ -2471,7 +2472,7 @@ ${indentation} output = ${topTarget}.`;
2471
2472
  }
2472
2473
  return undefined;
2473
2474
  }
2474
- replaceLineFunctions(node, lowFile, highSyntax) {
2475
+ replaceLineFunctions(node, lowFile, highSyntax, highFile) {
2475
2476
  var _a, _b;
2476
2477
  const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
2477
2478
  for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {
@@ -2506,12 +2507,30 @@ ${indentation} output = ${topTarget}.`;
2506
2507
  indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
2507
2508
  indentation + uniqueName + ` = ${sy}.\n` +
2508
2509
  indentation;
2509
- const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
2510
+ let insertAt = node.getFirstToken().getStart();
2511
+ if (node.get() instanceof statements_1.ElseIf) {
2512
+ // assumption: no side effects in IF conditions
2513
+ insertAt = this.findStartOfIf(node, highFile);
2514
+ if (insertAt === undefined) {
2515
+ continue;
2516
+ }
2517
+ }
2518
+ const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, insertAt, code);
2510
2519
  const start = expression.getFirstToken().getStart();
2511
2520
  const end = expression.getLastToken().getEnd();
2512
2521
  const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, start, end, uniqueName + (func === "LINE_EXISTS" ? " = 0" : ""));
2513
2522
  const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
2514
- return issue_1.Issue.atToken(lowFile, token, "Use BOOLC", this.getMetadata().key, this.conf.severity, fix);
2523
+ return issue_1.Issue.atToken(lowFile, token, "Replace line function", this.getMetadata().key, this.conf.severity, fix);
2524
+ }
2525
+ }
2526
+ return undefined;
2527
+ }
2528
+ findStartOfIf(node, highFile) {
2529
+ var _a;
2530
+ const structure = highFile.getStructure();
2531
+ for (const c of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(Structures.If)) || []) {
2532
+ if (((_a = c.findDirectStructure(Structures.ElseIf)) === null || _a === void 0 ? void 0 : _a.getFirstStatement()) === node) {
2533
+ return c.getFirstToken().getStart();
2515
2534
  }
2516
2535
  }
2517
2536
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.95.39",
3
+ "version": "2.95.41",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -52,7 +52,7 @@
52
52
  "@types/mocha": "^10.0.1",
53
53
  "@types/node": "^18.15.0",
54
54
  "chai": "^4.3.7",
55
- "eslint": "^8.35.0",
55
+ "eslint": "^8.36.0",
56
56
  "mocha": "^10.2.0",
57
57
  "c8": "^7.13.0",
58
58
  "source-map-support": "^0.5.21",