@abaplint/core 2.113.136 → 2.113.138

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.
@@ -5570,6 +5570,7 @@ export declare class Registry implements IRegistry {
5570
5570
  private readonly ddicReferences;
5571
5571
  private readonly msagReferences;
5572
5572
  private readonly macroReferences;
5573
+ private errorNamespace;
5573
5574
  private conf;
5574
5575
  constructor(conf?: IConfiguration);
5575
5576
  static abaplintVersion(): string;
@@ -5710,6 +5711,7 @@ declare class RollbackEntities implements IStatement {
5710
5711
 
5711
5712
  export declare class RulesRunner {
5712
5713
  private readonly reg;
5714
+ private readonly syntaxPerformance;
5713
5715
  constructor(reg: IRegistry);
5714
5716
  objectsToCheck(objects: Iterable<IObject>): readonly IObject[];
5715
5717
  runRules(objects: Iterable<IObject>, input?: IRunInput): readonly Issue[];
@@ -6,7 +6,7 @@ const combi_1 = require("../combi");
6
6
  class MessageClass extends combi_1.Expression {
7
7
  getRunnable() {
8
8
  // "&1" can be used for almost anything(field names, method names etc.) in macros
9
- return (0, combi_1.seq)((0, combi_1.regex)(/^>?[\w\/]+#?@?\/?!?&?>?\$?\??<?$/), (0, combi_1.starPrio)((0, combi_1.tok)(tokens_1.Plus)), (0, combi_1.starPrio)((0, combi_1.tok)(tokens_1.PlusW)), (0, combi_1.starPrio)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), (0, combi_1.optPrio)((0, combi_1.regex)(/^\w+$/)))), (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.DashW)));
9
+ return (0, combi_1.seq)((0, combi_1.regex)(/^>?[\w\/]+#?@?\/?!?&?>?\$?\??<?§?~?$/), (0, combi_1.starPrio)((0, combi_1.tok)(tokens_1.Plus)), (0, combi_1.starPrio)((0, combi_1.tok)(tokens_1.PlusW)), (0, combi_1.starPrio)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), (0, combi_1.optPrio)((0, combi_1.regex)(/^\w+$/)))), (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.DashW)));
10
10
  }
11
11
  }
12
12
  exports.MessageClass = MessageClass;
@@ -7,7 +7,7 @@ const version_1 = require("../../../version");
7
7
  const transporting_fields_1 = require("../expressions/transporting_fields");
8
8
  class ReadTable {
9
9
  getMatcher() {
10
- const comparing = (0, combi_1.seq)("COMPARING", (0, combi_1.alt)((0, combi_1.plus)(expressions_1.FieldSub), expressions_1.Dynamic));
10
+ const comparing = (0, combi_1.seq)("COMPARING", (0, combi_1.alt)((0, combi_1.plus)(expressions_1.FieldSub), (0, combi_1.plus)(expressions_1.Dynamic)));
11
11
  const index = (0, combi_1.seq)("INDEX", expressions_1.Source);
12
12
  const components = (0, combi_1.seq)((0, combi_1.alt)(expressions_1.Field, expressions_1.Dynamic), "COMPONENTS", expressions_1.ComponentCompareSimple);
13
13
  const key = (0, combi_1.seq)((0, combi_1.altPrio)("WITH KEY", "WITH TABLE KEY"), (0, combi_1.alt)(expressions_1.ComponentCompareSimple, components, (0, combi_1.seq)((0, combi_1.optPrio)("="), expressions_1.Source)));
@@ -60,14 +60,14 @@ class Registry {
60
60
  this.objects = {};
61
61
  this.objectsByType = {};
62
62
  this.dependencies = {};
63
- this.conf = conf ? conf : config_1.Config.getDefault();
63
+ this.setConfig(conf ? conf : config_1.Config.getDefault());
64
64
  this.ddicReferences = new ddic_references_1.DDICReferences();
65
65
  this.msagReferences = new msag_references_1.MSAGReferences();
66
66
  this.macroReferences = new macro_references_1.MacroReferences();
67
67
  }
68
68
  static abaplintVersion() {
69
69
  // magic, see build script "version.sh"
70
- return "2.113.136";
70
+ return "2.113.138";
71
71
  }
72
72
  getDDICReferences() {
73
73
  return this.ddicReferences;
@@ -145,12 +145,11 @@ class Registry {
145
145
  obj.setDirty();
146
146
  }
147
147
  this.conf = conf;
148
+ this.errorNamespace = new RegExp(this.getConfig().getSyntaxSetttings().errorNamespace, "i");
148
149
  return this;
149
150
  }
150
151
  inErrorNamespace(name) {
151
- // todo: performance? cache regexp?
152
- const reg = new RegExp(this.getConfig().getSyntaxSetttings().errorNamespace, "i");
153
- return reg.test(name);
152
+ return this.errorNamespace.test(name);
154
153
  }
155
154
  addFile(file) {
156
155
  return this.addFiles([file]);
@@ -6,9 +6,35 @@ const artifacts_rules_1 = require("./artifacts_rules");
6
6
  const _abap_object_1 = require("./objects/_abap_object");
7
7
  const skip_logic_1 = require("./skip_logic");
8
8
  const excludeHelper_1 = require("./utils/excludeHelper");
9
+ class SyntaxPerformance {
10
+ constructor() {
11
+ this.results = [];
12
+ }
13
+ push(obj, runtime) {
14
+ if (runtime < 100) {
15
+ return;
16
+ }
17
+ this.results.push({
18
+ runtime: runtime,
19
+ name: obj.getType() + " " + obj.getName(),
20
+ });
21
+ }
22
+ output() {
23
+ const MAX = 10;
24
+ this.results.sort((a, b) => { return b.runtime - a.runtime; });
25
+ for (let i = 0; i < MAX; i++) {
26
+ const row = this.results[i];
27
+ if (row === undefined) {
28
+ break;
29
+ }
30
+ process.stderr.write(`\t${row.runtime}ms\t${row.name}\n`);
31
+ }
32
+ }
33
+ }
9
34
  class RulesRunner {
10
35
  constructor(reg) {
11
36
  this.reg = reg;
37
+ this.syntaxPerformance = new SyntaxPerformance();
12
38
  }
13
39
  objectsToCheck(objects) {
14
40
  const check = [];
@@ -33,12 +59,25 @@ class RulesRunner {
33
59
  for (const obj of check) {
34
60
  (_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Run Syntax - " + obj.getName());
35
61
  if (obj instanceof _abap_object_1.ABAPObject) {
62
+ const start = Date.now();
36
63
  new syntax_1.SyntaxLogic(this.reg, obj).run();
64
+ if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
65
+ this.syntaxPerformance.push(obj, Date.now() - start);
66
+ }
37
67
  }
38
68
  }
69
+ if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
70
+ process.stderr.write("Syntax Performance:\n");
71
+ this.syntaxPerformance.output();
72
+ }
39
73
  (_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, "Initialize Rules");
40
74
  for (const rule of rules) {
41
- (_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick("Initialize Rules - " + rule.getMetadata().key);
75
+ if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
76
+ process.stderr.write("Initializing rule " + rule.getMetadata().key + "\n");
77
+ }
78
+ else {
79
+ (_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick("Initialize Rules - " + rule.getMetadata().key);
80
+ }
42
81
  if (rule.initialize === undefined) {
43
82
  throw new Error(rule.getMetadata().key + " missing initialize method");
44
83
  }
@@ -11,6 +11,7 @@ const _abap_object_1 = require("../objects/_abap_object");
11
11
  const severity_1 = require("../severity");
12
12
  // todo, check for cycles/circular dependencies, method findTop
13
13
  // todo, add configurable error for multiple use includes
14
+ const FMXXINCLUDE = /^(\/\w+\/)?L.+XX$/;
14
15
  function getABAPObjects(reg) {
15
16
  const ret = [];
16
17
  for (const o of reg.getObjects()) {
@@ -22,40 +23,33 @@ function getABAPObjects(reg) {
22
23
  }
23
24
  class Graph {
24
25
  constructor() {
25
- this.vertices = [];
26
- this.edges = [];
26
+ this.verticesIncludenameIndex = {};
27
+ this.verticesFilenameIndex = {};
28
+ this.edges = {};
27
29
  }
28
30
  addVertex(vertex) {
29
- this.vertices.push(vertex);
31
+ this.verticesIncludenameIndex[vertex.includeName.toUpperCase()] = vertex;
32
+ this.verticesFilenameIndex[vertex.filename.toUpperCase()] = vertex;
30
33
  }
31
- findInclude(includeName) {
32
- for (const v of this.vertices) {
33
- if (v.includeName.toUpperCase() === includeName.toUpperCase()) {
34
- return v;
35
- }
36
- }
37
- return undefined;
34
+ findVertexViaIncludename(includeName) {
35
+ return this.verticesIncludenameIndex[includeName.toUpperCase()];
38
36
  }
39
- findVertex(filename) {
40
- for (const v of this.vertices) {
41
- if (v.filename.toUpperCase() === filename.toUpperCase()) {
42
- return v;
43
- }
44
- }
45
- return undefined;
37
+ findVertexByFilename(filename) {
38
+ return this.verticesFilenameIndex[filename.toUpperCase()];
46
39
  }
47
40
  addEdge(from, toFilename) {
48
- this.edges.push({ from: from.filename, to: toFilename });
41
+ if (this.edges[from.filename] === undefined) {
42
+ this.edges[from.filename] = [];
43
+ }
44
+ this.edges[from.filename].push(toFilename);
49
45
  }
50
46
  findTop(filename) {
51
47
  const ret = [];
52
- for (const e of this.edges) {
53
- if (e.from === filename) {
54
- ret.push(...this.findTop(e.to));
55
- }
48
+ for (const to of this.edges[filename] || []) {
49
+ ret.push(...this.findTop(to));
56
50
  }
57
51
  if (ret.length === 0) {
58
- const found = this.findVertex(filename);
52
+ const found = this.findVertexByFilename(filename);
59
53
  if (found !== undefined) {
60
54
  ret.push(found);
61
55
  }
@@ -99,19 +93,23 @@ class IncludeGraph {
99
93
  this.addVertices();
100
94
  for (const o of getABAPObjects(this.reg)) {
101
95
  for (const f of o.getABAPFiles()) {
96
+ if (f.getFilename().includes(".prog.screen_") || f.getFilename().includes(".fugr.screen_")) {
97
+ // skip dynpro files
98
+ continue;
99
+ }
102
100
  for (const s of f.getStatements()) {
103
101
  if (s.get() instanceof statements_1.Include) {
104
- const ifFound = s.concatTokens().toUpperCase().includes("IF FOUND");
105
102
  const iexp = s.findFirstExpression(expressions_1.IncludeName);
106
103
  if (iexp === undefined) {
107
104
  throw new Error("unexpected Include node");
108
105
  }
109
106
  const name = iexp.getFirstToken().getStr().toUpperCase();
110
- if (name.match(/^(\/\w+\/)?L.+XX$/)) { // function module XX includes, possibily namespaced
107
+ if (name.match(FMXXINCLUDE)) { // function module XX includes, possibily namespaced
111
108
  continue;
112
109
  }
113
- const found = this.graph.findInclude(name);
110
+ const found = this.graph.findVertexViaIncludename(name);
114
111
  if (found === undefined) {
112
+ const ifFound = s.concatTokens().toUpperCase().includes("IF FOUND");
115
113
  if (ifFound === false) {
116
114
  const issue = issue_1.Issue.atStatement(f, s, "Include " + name + " not found", new check_include_1.CheckInclude().getMetadata().key, severity_1.Severity.Error);
117
115
  this.issues.push(issue);
@@ -131,7 +129,7 @@ class IncludeGraph {
131
129
  this.findUnusedIncludes();
132
130
  }
133
131
  findUnusedIncludes() {
134
- for (const v of this.graph.vertices) {
132
+ for (const v of Object.values(this.graph.verticesFilenameIndex)) {
135
133
  if (v.include === true) {
136
134
  if (this.listMainForInclude(v.filename).length === 0) {
137
135
  const f = this.reg.getFileByName(v.filename);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.113.136",
3
+ "version": "2.113.138",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",