@abaplint/core 2.113.137 → 2.113.139
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.
|
@@ -80,12 +80,14 @@ class FunctionGroup extends _abap_object_1.ABAPObject {
|
|
|
80
80
|
}
|
|
81
81
|
if ((i.startsWith("L") || namespaced) && f.getFilename().includes(search.toLowerCase() + ".")) {
|
|
82
82
|
ret.push({ file: f, name: i });
|
|
83
|
+
break;
|
|
83
84
|
}
|
|
84
85
|
// fix for URL encoded? Uris
|
|
85
86
|
if (namespaced) {
|
|
86
87
|
search = i.replace(/\//g, "%23");
|
|
87
88
|
if (f.getFilename().includes(search.toLowerCase() + ".")) {
|
|
88
89
|
ret.push({ file: f, name: i });
|
|
90
|
+
break;
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -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,35 @@ function getABAPObjects(reg) {
|
|
|
22
23
|
}
|
|
23
24
|
class Graph {
|
|
24
25
|
constructor() {
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
26
|
+
this.verticesIncludenameIndex = {};
|
|
27
|
+
this.verticesFilenameIndex = {};
|
|
28
|
+
this.edges = {};
|
|
27
29
|
}
|
|
28
30
|
addVertex(vertex) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
findInclude(includeName) {
|
|
32
|
-
for (const v of this.vertices) {
|
|
33
|
-
if (v.includeName.toUpperCase() === includeName.toUpperCase()) {
|
|
34
|
-
return v;
|
|
35
|
-
}
|
|
31
|
+
if (vertex.includeName !== undefined) {
|
|
32
|
+
this.verticesIncludenameIndex[vertex.includeName.toUpperCase()] = vertex;
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
this.verticesFilenameIndex[vertex.filename.toUpperCase()] = vertex;
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
36
|
+
findVertexViaIncludename(includeName) {
|
|
37
|
+
return this.verticesIncludenameIndex[includeName.toUpperCase()];
|
|
38
|
+
}
|
|
39
|
+
findVertexByFilename(filename) {
|
|
40
|
+
return this.verticesFilenameIndex[filename.toUpperCase()];
|
|
46
41
|
}
|
|
47
42
|
addEdge(from, toFilename) {
|
|
48
|
-
this.edges
|
|
43
|
+
if (this.edges[from.filename] === undefined) {
|
|
44
|
+
this.edges[from.filename] = [];
|
|
45
|
+
}
|
|
46
|
+
this.edges[from.filename].push(toFilename);
|
|
49
47
|
}
|
|
50
48
|
findTop(filename) {
|
|
51
49
|
const ret = [];
|
|
52
|
-
for (const
|
|
53
|
-
|
|
54
|
-
ret.push(...this.findTop(e.to));
|
|
55
|
-
}
|
|
50
|
+
for (const to of this.edges[filename] || []) {
|
|
51
|
+
ret.push(...this.findTop(to));
|
|
56
52
|
}
|
|
57
53
|
if (ret.length === 0) {
|
|
58
|
-
const found = this.
|
|
54
|
+
const found = this.findVertexByFilename(filename);
|
|
59
55
|
if (found !== undefined) {
|
|
60
56
|
ret.push(found);
|
|
61
57
|
}
|
|
@@ -99,19 +95,23 @@ class IncludeGraph {
|
|
|
99
95
|
this.addVertices();
|
|
100
96
|
for (const o of getABAPObjects(this.reg)) {
|
|
101
97
|
for (const f of o.getABAPFiles()) {
|
|
98
|
+
if (f.getFilename().includes(".prog.screen_") || f.getFilename().includes(".fugr.screen_")) {
|
|
99
|
+
// skip dynpro files
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
102
|
for (const s of f.getStatements()) {
|
|
103
103
|
if (s.get() instanceof statements_1.Include) {
|
|
104
|
-
const ifFound = s.concatTokens().toUpperCase().includes("IF FOUND");
|
|
105
104
|
const iexp = s.findFirstExpression(expressions_1.IncludeName);
|
|
106
105
|
if (iexp === undefined) {
|
|
107
106
|
throw new Error("unexpected Include node");
|
|
108
107
|
}
|
|
109
108
|
const name = iexp.getFirstToken().getStr().toUpperCase();
|
|
110
|
-
if (name.match(
|
|
109
|
+
if (name.match(FMXXINCLUDE)) { // function module XX includes, possibily namespaced
|
|
111
110
|
continue;
|
|
112
111
|
}
|
|
113
|
-
const found = this.graph.
|
|
112
|
+
const found = this.graph.findVertexViaIncludename(name);
|
|
114
113
|
if (found === undefined) {
|
|
114
|
+
const ifFound = s.concatTokens().toUpperCase().includes("IF FOUND");
|
|
115
115
|
if (ifFound === false) {
|
|
116
116
|
const issue = issue_1.Issue.atStatement(f, s, "Include " + name + " not found", new check_include_1.CheckInclude().getMetadata().key, severity_1.Severity.Error);
|
|
117
117
|
this.issues.push(issue);
|
|
@@ -131,7 +131,7 @@ class IncludeGraph {
|
|
|
131
131
|
this.findUnusedIncludes();
|
|
132
132
|
}
|
|
133
133
|
findUnusedIncludes() {
|
|
134
|
-
for (const v of this.graph.
|
|
134
|
+
for (const v of Object.values(this.graph.verticesFilenameIndex)) {
|
|
135
135
|
if (v.include === true) {
|
|
136
136
|
if (this.listMainForInclude(v.filename).length === 0) {
|
|
137
137
|
const f = this.reg.getFileByName(v.filename);
|
|
@@ -161,7 +161,7 @@ class IncludeGraph {
|
|
|
161
161
|
if (file) {
|
|
162
162
|
this.graph.addVertex({
|
|
163
163
|
filename: file.getFilename(),
|
|
164
|
-
includeName:
|
|
164
|
+
includeName: undefined,
|
|
165
165
|
include: false
|
|
166
166
|
});
|
|
167
167
|
}
|
|
@@ -170,7 +170,7 @@ class IncludeGraph {
|
|
|
170
170
|
for (const f of o.getSequencedFiles()) {
|
|
171
171
|
this.graph.addVertex({
|
|
172
172
|
filename: f.getFilename(),
|
|
173
|
-
includeName:
|
|
173
|
+
includeName: undefined,
|
|
174
174
|
include: false
|
|
175
175
|
});
|
|
176
176
|
}
|
|
@@ -187,7 +187,7 @@ class IncludeGraph {
|
|
|
187
187
|
if (file) {
|
|
188
188
|
this.graph.addVertex({
|
|
189
189
|
filename: file.getFilename(),
|
|
190
|
-
includeName:
|
|
190
|
+
includeName: undefined, // this is the SAPL program
|
|
191
191
|
include: false
|
|
192
192
|
});
|
|
193
193
|
}
|