@abaplint/core 2.93.1 → 2.93.4

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.
@@ -0,0 +1,17 @@
1
+ import {MemoryFile} from "../src";
2
+ import {Lexer} from "../src/abap/1_lexer/lexer";
3
+ import * as fs from "fs";
4
+
5
+ console.log("========================");
6
+ const file = new MemoryFile("abapgit.abap", fs.readFileSync("./lexer_performance.abap", "utf-8"));
7
+
8
+ let total = 0;
9
+ for (let i = 0; i < 10; i++) {
10
+ const before = Date.now();
11
+ const result = Lexer.run(file);
12
+ const runtime = Date.now() - before;
13
+ console.log("Runtime: " + runtime + "ms");
14
+ total += runtime;
15
+ console.log("Tokens: " + result.tokens.length);
16
+ }
17
+ console.log("Total: " + total);
@@ -4488,7 +4488,6 @@ export declare class Registry implements IRegistry {
4488
4488
  private readonly dependencies;
4489
4489
  private readonly references;
4490
4490
  private conf;
4491
- private issues;
4492
4491
  constructor(conf?: IConfiguration);
4493
4492
  static abaplintVersion(): string;
4494
4493
  getDDICReferences(): IDDICReferences;
@@ -4519,8 +4518,6 @@ export declare class Registry implements IRegistry {
4519
4518
  parseAsync(input?: IRunInput): Promise<this>;
4520
4519
  private parsePrivate;
4521
4520
  private isDirty;
4522
- private runRules;
4523
- private excludeIssues;
4524
4521
  private findOrCreate;
4525
4522
  private removeObject;
4526
4523
  private find;
@@ -4602,6 +4599,14 @@ declare class RollbackEntities implements IStatement {
4602
4599
  getMatcher(): IStatementRunnable;
4603
4600
  }
4604
4601
 
4602
+ export declare class RulesRunner {
4603
+ private readonly reg;
4604
+ constructor(reg: IRegistry);
4605
+ objectsToCheck(objects: Iterable<IObject>): readonly IObject[];
4606
+ runRules(objects: Iterable<IObject>, input?: IRunInput): readonly Issue[];
4607
+ excludeIssues(issues: Issue[]): Issue[];
4608
+ }
4609
+
4605
4610
  declare enum RuleTag {
4606
4611
  Experimental = "Experimental",
4607
4612
  DeprecationCandidate = "DeprecationCandidate",
@@ -5516,6 +5521,7 @@ declare class StructureNode extends AbstractNode<StructureNode | StatementNode>
5516
5521
  findAllStatements(type: new () => IStatement): StatementNode[];
5517
5522
  findAllStatementNodes(): StatementNode[];
5518
5523
  findAllStructuresRecursive(type: new () => IStructure): StructureNode[];
5524
+ findAllStructuresMulti(type: (new () => IStructure)[]): StructureNode[];
5519
5525
  findAllStructures(type: new () => IStructure): StructureNode[];
5520
5526
  findDirectStructure(type: new () => IStructure): StructureNode | undefined;
5521
5527
  findFirstStructure(type: new () => IStructure): StructureNode | undefined;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const src_1 = require("../src");
4
+ const lexer_1 = require("../src/abap/1_lexer/lexer");
5
+ const fs = require("fs");
6
+ console.log("========================");
7
+ const file = new src_1.MemoryFile("abapgit.abap", fs.readFileSync("./lexer_performance.abap", "utf-8"));
8
+ let total = 0;
9
+ for (let i = 0; i < 10; i++) {
10
+ const before = Date.now();
11
+ const result = lexer_1.Lexer.run(file);
12
+ const runtime = Date.now() - before;
13
+ console.log("Runtime: " + runtime + "ms");
14
+ total += runtime;
15
+ console.log("Tokens: " + result.tokens.length);
16
+ }
17
+ console.log("Total: " + total);
18
+ //# sourceMappingURL=lexer_performance.js.map
@@ -318,7 +318,7 @@ class Lexer {
318
318
  && buf.length > 1
319
319
  && current === "`"
320
320
  && aahead !== "``"
321
- && (buf.match(/`/g) || []).length % 2 === 0
321
+ && (buf.split("`").length - 1) % 2 === 0
322
322
  && ahead !== "`") {
323
323
  // end of ping
324
324
  this.add();
@@ -341,7 +341,7 @@ class Lexer {
341
341
  && current === "'"
342
342
  && buf.length > 1
343
343
  && aahead !== "''"
344
- && (buf.match(/'/g) || []).length % 2 === 0
344
+ && (buf.split("'").length - 1) % 2 === 0
345
345
  && ahead !== "'") {
346
346
  // end of string
347
347
  this.add();
@@ -174,6 +174,30 @@ class StructureNode extends _abstract_node_1.AbstractNode {
174
174
  }
175
175
  return ret;
176
176
  }
177
+ findAllStructuresMulti(type) {
178
+ const ret = [];
179
+ for (const t of type) {
180
+ if (this.get() instanceof t) {
181
+ return [this];
182
+ }
183
+ }
184
+ for (const child of this.getChildren()) {
185
+ if (child instanceof statement_node_1.StatementNode) {
186
+ continue;
187
+ }
188
+ let found = false;
189
+ for (const t of type) {
190
+ if (this.get() instanceof t) {
191
+ ret.push(child);
192
+ found = true;
193
+ }
194
+ }
195
+ if (found === false) {
196
+ ret.push(...child.findAllStructuresMulti(type));
197
+ }
198
+ }
199
+ return ret;
200
+ }
177
201
  findAllStructures(type) {
178
202
  const ret = [];
179
203
  if (this.get() instanceof type) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Severity = exports.Visibility = exports.Info = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = exports.ABAPFile = 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.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
4
4
  const issue_1 = require("./issue");
5
5
  Object.defineProperty(exports, "Issue", { enumerable: true, get: function () { return issue_1.Issue; } });
6
6
  const config_1 = require("./config");
@@ -92,4 +92,6 @@ const ddl_parser_1 = require("./ddl/ddl_parser");
92
92
  Object.defineProperty(exports, "DDLParser", { enumerable: true, get: function () { return ddl_parser_1.DDLParser; } });
93
93
  const cds_parser_1 = require("./cds/cds_parser");
94
94
  Object.defineProperty(exports, "CDSParser", { enumerable: true, get: function () { return cds_parser_1.CDSParser; } });
95
+ const rules_runner_1 = require("./rules_runner");
96
+ Object.defineProperty(exports, "RulesRunner", { enumerable: true, get: function () { return rules_runner_1.RulesRunner; } });
95
97
  //# sourceMappingURL=index.js.map
@@ -26,7 +26,7 @@ class UnknownObject extends _abstract_object_1.AbstractObject {
26
26
  const pos = new position_1.Position(1, 1);
27
27
  const file = this.getFiles()[0];
28
28
  const message = "Unknown object type, currently not supported in abaplint, open issue on github";
29
- const issue = issue_1.Issue.atPosition(file, pos, message, "registry_add", severity_1.Severity.Error);
29
+ const issue = issue_1.Issue.atPosition(file, pos, message, "parser_error", severity_1.Severity.Error);
30
30
  return [issue];
31
31
  }
32
32
  }
@@ -3,13 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Registry = void 0;
4
4
  const config_1 = require("./config");
5
5
  const artifacts_objects_1 = require("./artifacts_objects");
6
- const artifacts_rules_1 = require("./artifacts_rules");
7
- const skip_logic_1 = require("./skip_logic");
8
- const _abap_object_1 = require("./objects/_abap_object");
9
6
  const find_global_definitions_1 = require("./abap/5_syntax/global_definitions/find_global_definitions");
10
- const syntax_1 = require("./abap/5_syntax/syntax");
11
7
  const excludeHelper_1 = require("./utils/excludeHelper");
12
8
  const ddic_references_1 = require("./ddic_references");
9
+ const rules_runner_1 = require("./rules_runner");
13
10
  // todo, this should really be an instance in case there are multiple Registry'ies
14
11
  class ParsingPerformance {
15
12
  static clear() {
@@ -61,13 +58,12 @@ class Registry {
61
58
  this.objects = {};
62
59
  this.objectsByType = {};
63
60
  this.dependencies = {};
64
- this.issues = [];
65
61
  this.conf = conf ? conf : config_1.Config.getDefault();
66
62
  this.references = new ddic_references_1.DDICReferences();
67
63
  }
68
64
  static abaplintVersion() {
69
65
  // magic, see build script "version.sh"
70
- return "2.93.1";
66
+ return "2.93.4";
71
67
  }
72
68
  getDDICReferences() {
73
69
  return this.references;
@@ -245,14 +241,14 @@ class Registry {
245
241
  if (this.isDirty() === true) {
246
242
  this.parse();
247
243
  }
248
- return this.runRules(input);
244
+ return new rules_runner_1.RulesRunner(this).runRules(this.getObjects(), input);
249
245
  }
250
246
  // todo, this will be changed to async sometime
251
247
  findIssuesObject(iobj) {
252
248
  if (this.isDirty() === true) {
253
249
  this.parse();
254
250
  }
255
- return this.runRules(undefined, iobj);
251
+ return new rules_runner_1.RulesRunner(this).runRules([iobj]);
256
252
  }
257
253
  // todo, this will be changed to async sometime
258
254
  parse() {
@@ -260,10 +256,8 @@ class Registry {
260
256
  return this;
261
257
  }
262
258
  ParsingPerformance.clear();
263
- this.issues = [];
264
259
  for (const o of this.getObjects()) {
265
260
  this.parsePrivate(o);
266
- this.issues.push(...o.getParsingIssues());
267
261
  }
268
262
  new find_global_definitions_1.FindGlobalDefinitions(this).run();
269
263
  return this;
@@ -275,11 +269,9 @@ class Registry {
275
269
  }
276
270
  ParsingPerformance.clear();
277
271
  (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(this.getObjectCount(false), "Lexing and parsing");
278
- this.issues = [];
279
272
  for (const o of this.getObjects()) {
280
273
  await ((_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Lexing and parsing(" + this.conf.getVersion() + ") - " + o.getType() + " " + o.getName()));
281
274
  this.parsePrivate(o);
282
- this.issues.push(...o.getParsingIssues());
283
275
  }
284
276
  if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
285
277
  ParsingPerformance.output();
@@ -303,91 +295,6 @@ class Registry {
303
295
  }
304
296
  return false;
305
297
  }
306
- runRules(input, iobj) {
307
- var _a, _b, _c, _d, _e, _f;
308
- const rulePerformance = {};
309
- const issues = this.issues.slice(0);
310
- const objects = iobj ? [iobj] : this.getObjects();
311
- const rules = this.conf.getEnabledRules();
312
- const skipLogic = new skip_logic_1.SkipLogic(this);
313
- (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(iobj ? 1 : this.getObjectCount(false), "Run Syntax");
314
- const check = [];
315
- for (const obj of objects) {
316
- (_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Run Syntax - " + obj.getName());
317
- if (skipLogic.skip(obj) || this.isDependency(obj)) {
318
- continue;
319
- }
320
- if (obj instanceof _abap_object_1.ABAPObject) {
321
- new syntax_1.SyntaxLogic(this, obj).run();
322
- }
323
- check.push(obj);
324
- }
325
- (_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, "Initialize Rules");
326
- for (const rule of rules) {
327
- (_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick("Initialize Rules - " + rule.getMetadata().key);
328
- if (rule.initialize === undefined) {
329
- throw new Error(rule.getMetadata().key + " missing initialize method");
330
- }
331
- rule.initialize(this);
332
- rulePerformance[rule.getMetadata().key] = 0;
333
- }
334
- (_e = input === null || input === void 0 ? void 0 : input.progress) === null || _e === void 0 ? void 0 : _e.set(check.length, "Finding Issues");
335
- for (const obj of check) {
336
- (_f = input === null || input === void 0 ? void 0 : input.progress) === null || _f === void 0 ? void 0 : _f.tick("Finding Issues - " + obj.getType() + " " + obj.getName());
337
- for (const rule of rules) {
338
- const before = Date.now();
339
- issues.push(...rule.run(obj));
340
- const runtime = Date.now() - before;
341
- rulePerformance[rule.getMetadata().key] = rulePerformance[rule.getMetadata().key] + runtime;
342
- }
343
- }
344
- if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
345
- const perf = [];
346
- for (const p in rulePerformance) {
347
- if (rulePerformance[p] > 100) { // ignore rules if it takes less than 100ms
348
- perf.push({ name: p, time: rulePerformance[p] });
349
- }
350
- }
351
- perf.sort((a, b) => { return b.time - a.time; });
352
- for (const p of perf) {
353
- process.stderr.write("\t" + p.time + "ms\t" + p.name + "\n");
354
- }
355
- }
356
- return this.excludeIssues(issues);
357
- }
358
- excludeIssues(issues) {
359
- var _a;
360
- const ret = issues;
361
- const globalNoIssues = this.conf.getGlobal().noIssues || [];
362
- const globalNoIssuesPatterns = globalNoIssues.map(x => new RegExp(x, "i"));
363
- if (globalNoIssuesPatterns.length > 0) {
364
- for (let i = ret.length - 1; i >= 0; i--) {
365
- const filename = ret[i].getFilename();
366
- if (excludeHelper_1.ExcludeHelper.isExcluded(filename, globalNoIssuesPatterns)) {
367
- ret.splice(i, 1);
368
- }
369
- }
370
- }
371
- // exclude issues, as now we know both the filename and issue key
372
- for (const rule of artifacts_rules_1.ArtifactsRules.getRules()) {
373
- const key = rule.getMetadata().key;
374
- const ruleExclude = (_a = this.conf.readByKey(key, "exclude")) !== null && _a !== void 0 ? _a : [];
375
- if (ruleExclude.length === 0) {
376
- continue;
377
- }
378
- const ruleExcludePatterns = ruleExclude.map(x => new RegExp(x, "i"));
379
- for (let i = ret.length - 1; i >= 0; i--) {
380
- if (ret[i].getKey() !== key) {
381
- continue;
382
- }
383
- const filename = ret[i].getFilename();
384
- if (excludeHelper_1.ExcludeHelper.isExcluded(filename, ruleExcludePatterns)) {
385
- ret.splice(i, 1);
386
- }
387
- }
388
- }
389
- return ret;
390
- }
391
298
  findOrCreate(name, type) {
392
299
  try {
393
300
  return this.find(name, type);
@@ -24,11 +24,11 @@ class BeginEndNames extends _abap_rule_1.ABAPRule {
24
24
  shortDescription: `Check BEGIN OF and END OF names match, plus there must be statements between BEGIN and END`,
25
25
  tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
26
26
  badExample: `DATA: BEGIN OF stru,
27
- field TYPE i,
28
- END OF structure_not_the_same.`,
27
+ field TYPE i,
28
+ END OF structure_not_the_same.`,
29
29
  goodExample: `DATA: BEGIN OF stru,
30
- field TYPE i,
31
- END OF stru.`,
30
+ field TYPE i,
31
+ END OF stru.`,
32
32
  };
33
33
  }
34
34
  getConfig() {
@@ -56,16 +56,15 @@ https://docs.abapopenchecks.org/checks/17/`,
56
56
  if (containsUnknown === true) {
57
57
  return [];
58
58
  }
59
- const routines = structure.findAllStructures(Structures.Form).concat(structure.findAllStructures(Structures.Method));
59
+ const routines = structure.findAllStructuresMulti([Structures.Form, Structures.Method]);
60
60
  for (const r of routines) {
61
61
  // one fix per routine
62
62
  this.fixed = false;
63
63
  this.mode = DEFINITION;
64
64
  this.moveTo = (_a = r.getFirstStatement()) === null || _a === void 0 ? void 0 : _a.getLastToken().getEnd();
65
- if (this.reg.getConfig().getVersion() !== version_1.Version.v702) {
66
- if (r.findFirstExpression(Expressions.InlineData)) {
67
- continue;
68
- }
65
+ if (this.reg.getConfig().getVersion() !== version_1.Version.v702
66
+ && r.findFirstExpression(Expressions.InlineData)) {
67
+ continue;
69
68
  }
70
69
  const found = this.walk(r, file);
71
70
  if (found) {
@@ -79,20 +78,23 @@ https://docs.abapopenchecks.org/checks/17/`,
79
78
  var _a, _b, _c, _d, _e, _f;
80
79
  let previous = undefined;
81
80
  for (const c of r.getChildren()) {
82
- if (c instanceof nodes_1.StatementNode && c.get() instanceof _statement_1.Comment) {
83
- continue;
84
- }
85
- else if (c instanceof nodes_1.StatementNode && c.get() instanceof Statements.Form) {
86
- continue;
87
- }
88
- else if (c instanceof nodes_1.StatementNode && c.get() instanceof Statements.MethodImplementation) {
89
- continue;
81
+ const get = c.get();
82
+ if (c instanceof nodes_1.StatementNode) {
83
+ if (get instanceof _statement_1.Comment) {
84
+ continue;
85
+ }
86
+ else if (get instanceof Statements.Form) {
87
+ continue;
88
+ }
89
+ else if (get instanceof Statements.MethodImplementation) {
90
+ continue;
91
+ }
90
92
  }
91
93
  if (c instanceof nodes_1.StructureNode
92
- && (c.get() instanceof Structures.Data
93
- || c.get() instanceof Structures.Types
94
- || c.get() instanceof Structures.Constants
95
- || c.get() instanceof Structures.Statics)) {
94
+ && (get instanceof Structures.Data
95
+ || get instanceof Structures.Types
96
+ || get instanceof Structures.Constants
97
+ || get instanceof Structures.Statics)) {
96
98
  if (this.mode === AFTER) {
97
99
  // These are chained structured statements
98
100
  let fix = undefined;
@@ -118,11 +120,11 @@ https://docs.abapopenchecks.org/checks/17/`,
118
120
  }
119
121
  }
120
122
  else if (c instanceof nodes_1.StatementNode
121
- && (c.get() instanceof Statements.Data
122
- || c.get() instanceof Statements.Type
123
- || c.get() instanceof Statements.Constant
124
- || c.get() instanceof Statements.Static
125
- || c.get() instanceof Statements.FieldSymbol)) {
123
+ && (get instanceof Statements.Data
124
+ || get instanceof Statements.Type
125
+ || get instanceof Statements.Constant
126
+ || get instanceof Statements.Static
127
+ || get instanceof Statements.FieldSymbol)) {
126
128
  if (this.mode === AFTER) {
127
129
  // only one fix per routine, as it reorders a lot
128
130
  let fix = undefined;
@@ -136,11 +138,11 @@ https://docs.abapopenchecks.org/checks/17/`,
136
138
  this.moveTo = c.getLastToken().getEnd();
137
139
  }
138
140
  }
139
- else if (c instanceof nodes_1.StructureNode && c.get() instanceof Structures.Define) {
141
+ else if (c instanceof nodes_1.StructureNode && get instanceof Structures.Define) {
140
142
  this.mode = IGNORE;
141
143
  return undefined;
142
144
  }
143
- else if (c instanceof nodes_1.StatementNode && c.get() instanceof _statement_1.Unknown) {
145
+ else if (c instanceof nodes_1.StatementNode && get instanceof _statement_1.Unknown) {
144
146
  this.mode = IGNORE;
145
147
  return undefined;
146
148
  }