@abaplint/transpiler 2.10.38 → 2.10.40
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.
- package/build/src/index.js +3 -2
- package/build/src/initialization.d.ts +8 -0
- package/build/src/initialization.js +119 -0
- package/build/src/unit_test.d.ts +0 -5
- package/build/src/unit_test.js +44 -164
- package/package.json +1 -1
package/build/src/index.js
CHANGED
|
@@ -20,6 +20,7 @@ const handle_smim_1 = require("./handlers/handle_smim");
|
|
|
20
20
|
const handle_msag_1 = require("./handlers/handle_msag");
|
|
21
21
|
const handle_oa2p_1 = require("./handlers/handle_oa2p");
|
|
22
22
|
const handle_fugr_1 = require("./handlers/handle_fugr");
|
|
23
|
+
const initialization_1 = require("./initialization");
|
|
23
24
|
class Transpiler {
|
|
24
25
|
constructor(options) {
|
|
25
26
|
this.options = options;
|
|
@@ -44,8 +45,8 @@ class Transpiler {
|
|
|
44
45
|
objects: [],
|
|
45
46
|
unitTestScript: new unit_test_1.UnitTest().unitTestScript(reg, this.options?.skip),
|
|
46
47
|
unitTestScriptOpen: new unit_test_1.UnitTest().unitTestScriptOpen(reg, this.options?.skip),
|
|
47
|
-
initializationScript: new
|
|
48
|
-
initializationScript2: new
|
|
48
|
+
initializationScript: new initialization_1.Initialization().script(reg, dbSetup, this.options?.extraSetup),
|
|
49
|
+
initializationScript2: new initialization_1.Initialization().script(reg, dbSetup, this.options?.extraSetup, true),
|
|
49
50
|
databaseSetup: dbSetup,
|
|
50
51
|
reg: reg,
|
|
51
52
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DatabaseSetupResult } from "./db/database_setup_result";
|
|
2
|
+
import * as abaplint from "@abaplint/core";
|
|
3
|
+
export declare function escapeNamespaceFilename(filename: string): string;
|
|
4
|
+
export declare class Initialization {
|
|
5
|
+
script(reg: abaplint.IRegistry, dbSetup: DatabaseSetupResult, extraSetup?: string, useImport?: boolean): string;
|
|
6
|
+
private buildImports;
|
|
7
|
+
private hasClassConstructor;
|
|
8
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Initialization = void 0;
|
|
4
|
+
exports.escapeNamespaceFilename = escapeNamespaceFilename;
|
|
5
|
+
const abaplint = require("@abaplint/core");
|
|
6
|
+
function escapeNamespaceFilename(filename) {
|
|
7
|
+
// ES modules are resolved and cached as URLs. This means that special characters must be
|
|
8
|
+
// percent-encoded, such as # with %23 and ? with %3F.
|
|
9
|
+
return filename.replace(/\//g, "%23");
|
|
10
|
+
}
|
|
11
|
+
class Initialization {
|
|
12
|
+
script(reg, dbSetup, extraSetup, useImport) {
|
|
13
|
+
let ret = "";
|
|
14
|
+
if (useImport === true) {
|
|
15
|
+
ret = `/* eslint-disable import/newline-after-import */
|
|
16
|
+
import "./_top.mjs";\n`;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
ret = `/* eslint-disable import/newline-after-import */
|
|
20
|
+
import runtime from "@abaplint/runtime";
|
|
21
|
+
globalThis.abap = new runtime.ABAP();\n`;
|
|
22
|
+
}
|
|
23
|
+
ret += `${this.buildImports(reg, useImport)}
|
|
24
|
+
|
|
25
|
+
export async function initializeABAP() {\n`;
|
|
26
|
+
ret += ` const sqlite = [];\n`;
|
|
27
|
+
for (const i of dbSetup.schemas.sqlite) {
|
|
28
|
+
ret += ` sqlite.push(\`${i}\`);\n`;
|
|
29
|
+
}
|
|
30
|
+
ret += ` const hdb = \`${dbSetup.schemas.hdb}\`;\n`;
|
|
31
|
+
ret += ` const pg = [];\n`;
|
|
32
|
+
for (const i of dbSetup.schemas.pg) {
|
|
33
|
+
ret += ` pg.push(\`${i}\`);\n`;
|
|
34
|
+
}
|
|
35
|
+
ret += ` const snowflake = [];\n`;
|
|
36
|
+
for (const i of dbSetup.schemas.snowflake) {
|
|
37
|
+
ret += ` snowflake.push(\`${i}\`);\n`;
|
|
38
|
+
}
|
|
39
|
+
ret += ` const schemas = {sqlite, hdb, pg, snowflake};\n`;
|
|
40
|
+
ret += `\n`;
|
|
41
|
+
ret += ` const insert = [];\n`;
|
|
42
|
+
for (const i of dbSetup.insert) {
|
|
43
|
+
ret += ` insert.push(\`${i}\`);\n`;
|
|
44
|
+
}
|
|
45
|
+
ret += `\n`;
|
|
46
|
+
if (extraSetup === undefined || extraSetup === "") {
|
|
47
|
+
ret += `// no setup logic specified in config\n`;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
ret += ` const {setup} = await import("${extraSetup}");\n` +
|
|
51
|
+
` await setup(globalThis.abap, schemas, insert);\n`;
|
|
52
|
+
}
|
|
53
|
+
ret += `}`;
|
|
54
|
+
return ret;
|
|
55
|
+
}
|
|
56
|
+
buildImports(reg, useImport) {
|
|
57
|
+
// note: ES modules are hoised, so use the dynamic import(), due to setting of globalThis.abap
|
|
58
|
+
// some sorting required: eg. a class constructor using constant from interface
|
|
59
|
+
const list = [];
|
|
60
|
+
const late = [];
|
|
61
|
+
const imp = (filename) => {
|
|
62
|
+
if (useImport === true) {
|
|
63
|
+
return `import "./${filename}.mjs";`;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return `await import("./${filename}.mjs");`;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
for (const obj of reg.getObjects()) {
|
|
70
|
+
if (obj instanceof abaplint.Objects.Table
|
|
71
|
+
|| obj instanceof abaplint.Objects.DataElement
|
|
72
|
+
|| obj instanceof abaplint.Objects.LockObject
|
|
73
|
+
|| obj instanceof abaplint.Objects.MessageClass
|
|
74
|
+
|| obj instanceof abaplint.Objects.MIMEObject
|
|
75
|
+
|| obj instanceof abaplint.Objects.Oauth2Profile
|
|
76
|
+
|| obj instanceof abaplint.Objects.WebMIME
|
|
77
|
+
|| obj instanceof abaplint.Objects.TypePool
|
|
78
|
+
|| obj instanceof abaplint.Objects.TableType) {
|
|
79
|
+
list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const obj of reg.getObjects()) {
|
|
83
|
+
if (obj instanceof abaplint.Objects.FunctionGroup) {
|
|
84
|
+
list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.fugr`));
|
|
85
|
+
}
|
|
86
|
+
else if (obj instanceof abaplint.Objects.Class) {
|
|
87
|
+
if (obj.getName().toUpperCase() !== "CL_ABAP_CHAR_UTILITIES"
|
|
88
|
+
&& this.hasClassConstructor(reg, obj)) {
|
|
89
|
+
// this will not solve all problems with class constors 100%, but probably good enough
|
|
90
|
+
late.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (obj instanceof abaplint.Objects.Interface) {
|
|
97
|
+
list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...list.sort(), ...late].join("\n");
|
|
101
|
+
}
|
|
102
|
+
// class constructors might make early use of eg. constants from interfaces
|
|
103
|
+
// sub classes will import() super classes and trigger a class constructor of the super
|
|
104
|
+
hasClassConstructor(reg, clas) {
|
|
105
|
+
if (clas.getDefinition()?.getMethodDefinitions().getByName("CLASS_CONSTRUCTOR") !== undefined) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
const sup = clas.getDefinition()?.getSuperClass();
|
|
109
|
+
if (sup !== undefined) {
|
|
110
|
+
const superClass = reg.getObject("CLAS", sup);
|
|
111
|
+
if (superClass) {
|
|
112
|
+
return this.hasClassConstructor(reg, superClass);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.Initialization = Initialization;
|
|
119
|
+
//# sourceMappingURL=initialization.js.map
|
package/build/src/unit_test.d.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import * as abaplint from "@abaplint/core";
|
|
2
|
-
import { DatabaseSetupResult } from "./db/database_setup_result";
|
|
3
2
|
export type TestMethodList = {
|
|
4
3
|
object: string;
|
|
5
4
|
class: string;
|
|
6
5
|
method: string;
|
|
7
6
|
}[];
|
|
8
7
|
export declare class UnitTest {
|
|
9
|
-
initializationScript(reg: abaplint.IRegistry, dbSetup: DatabaseSetupResult, extraSetup?: string, useImport?: boolean): string;
|
|
10
|
-
private escapeNamespace;
|
|
11
8
|
unitTestScriptOpen(reg: abaplint.IRegistry, _skip?: TestMethodList): string;
|
|
12
9
|
private getSortedTests;
|
|
13
10
|
unitTestScript(reg: abaplint.IRegistry, skip?: TestMethodList): string;
|
|
14
|
-
private buildImports;
|
|
15
|
-
private hasClassConstructor;
|
|
16
11
|
}
|
package/build/src/unit_test.js
CHANGED
|
@@ -3,56 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.UnitTest = void 0;
|
|
4
4
|
/* eslint-disable max-len */
|
|
5
5
|
const abaplint = require("@abaplint/core");
|
|
6
|
+
const initialization_1 = require("./initialization");
|
|
6
7
|
class UnitTest {
|
|
7
|
-
// todo, move this method somewhere else, its much more than just unit test relevant
|
|
8
|
-
initializationScript(reg, dbSetup, extraSetup, useImport) {
|
|
9
|
-
let ret = "";
|
|
10
|
-
if (useImport === true) {
|
|
11
|
-
ret = `/* eslint-disable import/newline-after-import */
|
|
12
|
-
import "./_top.mjs";\n`;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
ret = `/* eslint-disable import/newline-after-import */
|
|
16
|
-
import runtime from "@abaplint/runtime";
|
|
17
|
-
globalThis.abap = new runtime.ABAP();\n`;
|
|
18
|
-
}
|
|
19
|
-
ret += `${this.buildImports(reg, useImport)}
|
|
20
|
-
|
|
21
|
-
export async function initializeABAP() {\n`;
|
|
22
|
-
ret += ` const sqlite = [];\n`;
|
|
23
|
-
for (const i of dbSetup.schemas.sqlite) {
|
|
24
|
-
ret += ` sqlite.push(\`${i}\`);\n`;
|
|
25
|
-
}
|
|
26
|
-
ret += ` const hdb = \`${dbSetup.schemas.hdb}\`;\n`;
|
|
27
|
-
ret += ` const pg = [];\n`;
|
|
28
|
-
for (const i of dbSetup.schemas.pg) {
|
|
29
|
-
ret += ` pg.push(\`${i}\`);\n`;
|
|
30
|
-
}
|
|
31
|
-
ret += ` const snowflake = [];\n`;
|
|
32
|
-
for (const i of dbSetup.schemas.snowflake) {
|
|
33
|
-
ret += ` snowflake.push(\`${i}\`);\n`;
|
|
34
|
-
}
|
|
35
|
-
ret += ` const schemas = {sqlite, hdb, pg, snowflake};\n`;
|
|
36
|
-
ret += `\n`;
|
|
37
|
-
ret += ` const insert = [];\n`;
|
|
38
|
-
for (const i of dbSetup.insert) {
|
|
39
|
-
ret += ` insert.push(\`${i}\`);\n`;
|
|
40
|
-
}
|
|
41
|
-
ret += `\n`;
|
|
42
|
-
if (extraSetup === undefined || extraSetup === "") {
|
|
43
|
-
ret += `// no setup logic specified in config\n`;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
ret += ` const {setup} = await import("${extraSetup}");\n` +
|
|
47
|
-
` await setup(globalThis.abap, schemas, insert);\n`;
|
|
48
|
-
}
|
|
49
|
-
ret += `}`;
|
|
50
|
-
return ret;
|
|
51
|
-
}
|
|
52
|
-
escapeNamespace(filename) {
|
|
53
|
-
// ES modules are resolved and cached as URLs. This means that special characters must be percent-encoded, such as # with %23 and ? with %3F.
|
|
54
|
-
return filename.replace(/\//g, "%23");
|
|
55
|
-
}
|
|
56
8
|
unitTestScriptOpen(reg, _skip) {
|
|
57
9
|
let ret = `/* eslint-disable curly */
|
|
58
10
|
import fs from "fs";
|
|
@@ -74,7 +26,7 @@ async function run() {
|
|
|
74
26
|
}
|
|
75
27
|
const hasTestFile = obj.getFiles().some(f => { return f.getFilename().includes(".testclasses."); });
|
|
76
28
|
if (hasTestFile === true) {
|
|
77
|
-
ret += ` await import("./${
|
|
29
|
+
ret += ` await import("./${(0, initialization_1.escapeNamespaceFilename)(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}.testclasses.mjs");\n`;
|
|
78
30
|
}
|
|
79
31
|
for (const file of obj.getABAPFiles()) {
|
|
80
32
|
for (const def of file.getInfo().listClassDefinitions()) {
|
|
@@ -136,7 +88,8 @@ run().then(() => {
|
|
|
136
88
|
}
|
|
137
89
|
tests.push({
|
|
138
90
|
obj,
|
|
139
|
-
|
|
91
|
+
filename: `./${(0, initialization_1.escapeNamespaceFilename)(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}.testclasses.mjs`,
|
|
92
|
+
localClass: def.name.toLowerCase(),
|
|
140
93
|
riskLevel: def.riskLevel,
|
|
141
94
|
duration: def.duration,
|
|
142
95
|
methods: methods,
|
|
@@ -192,65 +145,53 @@ run().then(() => {
|
|
|
192
145
|
return tests;
|
|
193
146
|
}
|
|
194
147
|
unitTestScript(reg, skip) {
|
|
148
|
+
const callSpecial = (name) => {
|
|
149
|
+
let ret = "";
|
|
150
|
+
ret += `if (test.${name}) await test.${name}();\n`;
|
|
151
|
+
ret += ` if (test.FRIENDS_ACCESS_INSTANCE.${name}) await test.FRIENDS_ACCESS_INSTANCE.${name}();\n`;
|
|
152
|
+
ret += ` if (test.FRIENDS_ACCESS_INSTANCE.SUPER && test.FRIENDS_ACCESS_INSTANCE.SUPER.${name}) await test.FRIENDS_ACCESS_INSTANCE.SUPER.${name}();`;
|
|
153
|
+
return ret;
|
|
154
|
+
};
|
|
195
155
|
let ret = `/* eslint-disable curly */
|
|
196
|
-
|
|
197
|
-
import path from "path";
|
|
198
|
-
import {fileURLToPath} from "url";
|
|
156
|
+
/* eslint-disable max-len */
|
|
199
157
|
import {initializeABAP} from "./init.mjs";
|
|
200
|
-
import runtime from "@abaplint/runtime";
|
|
201
158
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
async function run() {
|
|
205
|
-
await initializeABAP();
|
|
206
|
-
const unit = new runtime.UnitTestResult();
|
|
207
|
-
let clas;
|
|
208
|
-
let locl;
|
|
209
|
-
let meth;
|
|
210
|
-
try {\n`;
|
|
159
|
+
function getData() {
|
|
160
|
+
const ret = [];\n`;
|
|
211
161
|
for (const st of this.getSortedTests(reg)) {
|
|
212
|
-
|
|
213
|
-
ret += ` clas = unit.addObject("${st.obj.getName()}");\n`;
|
|
214
|
-
const lc = st.localClass.toLowerCase();
|
|
215
|
-
ret += ` {
|
|
216
|
-
const {${lc}} = await import("./${this.escapeNamespace(st.obj.getName().toLowerCase())}.${st.obj.getType().toLowerCase()}.testclasses.mjs");
|
|
217
|
-
locl = clas.addTestClass("${lc}");
|
|
218
|
-
if (${lc}.class_setup) await ${lc}.class_setup();\n`;
|
|
162
|
+
const methods = [];
|
|
219
163
|
for (const m of st.methods) {
|
|
220
|
-
const skipThis = (skip || []).some(a => a.object === st.obj.getName()
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
ret += ` if (test.${name}) await test.${name}();\n`;
|
|
230
|
-
ret += ` if (test.FRIENDS_ACCESS_INSTANCE.${name}) await test.FRIENDS_ACCESS_INSTANCE.${name}();\n`;
|
|
231
|
-
ret += ` if (test.FRIENDS_ACCESS_INSTANCE.SUPER && test.FRIENDS_ACCESS_INSTANCE.SUPER.${name}) await test.FRIENDS_ACCESS_INSTANCE.SUPER.${name}();\n`;
|
|
232
|
-
return ret;
|
|
233
|
-
};
|
|
234
|
-
ret += ` {\n const test = await (new ${lc}()).constructor_();\n`;
|
|
235
|
-
ret += callSpecial("setup");
|
|
236
|
-
ret += ` console.log("${st.obj.getName()}: running ${lc}->${m}");\n`;
|
|
237
|
-
ret += ` meth = locl.addMethod("${m}");\n`;
|
|
238
|
-
ret += ` await test.FRIENDS_ACCESS_INSTANCE.${m}();\n`;
|
|
239
|
-
ret += ` meth.pass();\n`;
|
|
240
|
-
ret += callSpecial("teardown");
|
|
241
|
-
ret += ` }\n`;
|
|
242
|
-
}
|
|
243
|
-
ret += ` if (${lc}.class_teardown) await ${lc}.class_teardown();\n`;
|
|
244
|
-
ret += ` }\n`;
|
|
164
|
+
const skipThis = (skip || []).some(a => a.object.toUpperCase() === st.obj.getName().toUpperCase()
|
|
165
|
+
&& a.class.toUpperCase() === st.localClass.toUpperCase()
|
|
166
|
+
&& a.method.toUpperCase() === m.toUpperCase());
|
|
167
|
+
methods.push({
|
|
168
|
+
name: m,
|
|
169
|
+
skip: skipThis,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
ret += ` ret.push({objectName: "${st.obj.getName()}", localClass: "${st.localClass}", methods: ${JSON.stringify(methods)}, filename: "${st.filename}"});\n`;
|
|
245
173
|
}
|
|
246
|
-
ret +=
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
174
|
+
ret += ` return ret;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function run() {
|
|
178
|
+
await initializeABAP();
|
|
179
|
+
for (const st of getData()) {
|
|
180
|
+
const imported = await import(st.filename);
|
|
181
|
+
const localClass = imported[st.localClass];
|
|
182
|
+
if (localClass.class_setup) await localClass.class_setup();
|
|
183
|
+
for (const m of st.methods) {
|
|
184
|
+
if (m.skip) {
|
|
185
|
+
console.log(st.objectName + ": running " + st.localClass + "->" + m.name + ", skipped");
|
|
186
|
+
} else {
|
|
187
|
+
const test = await (new localClass()).constructor_();
|
|
188
|
+
${callSpecial("setup")}
|
|
189
|
+
console.log(st.objectName + ": running " + st.localClass + "->" + m.name);
|
|
190
|
+
await test.FRIENDS_ACCESS_INSTANCE[m.name]();
|
|
191
|
+
${callSpecial("teardown")}
|
|
192
|
+
}
|
|
251
193
|
}
|
|
252
|
-
|
|
253
|
-
throw e;
|
|
194
|
+
if (localClass.class_teardown) await localClass.class_teardown();
|
|
254
195
|
}
|
|
255
196
|
}
|
|
256
197
|
|
|
@@ -262,67 +203,6 @@ run().then(() => {
|
|
|
262
203
|
});`;
|
|
263
204
|
return ret;
|
|
264
205
|
}
|
|
265
|
-
buildImports(reg, useImport) {
|
|
266
|
-
// note: ES modules are hoised, so use the dynamic import(), due to setting of globalThis.abap
|
|
267
|
-
// some sorting required: eg. a class constructor using constant from interface
|
|
268
|
-
const list = [];
|
|
269
|
-
const late = [];
|
|
270
|
-
const imp = (filename) => {
|
|
271
|
-
if (useImport === true) {
|
|
272
|
-
return `import "./${filename}.mjs";`;
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
return `await import("./${filename}.mjs");`;
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
for (const obj of reg.getObjects()) {
|
|
279
|
-
if (obj instanceof abaplint.Objects.Table
|
|
280
|
-
|| obj instanceof abaplint.Objects.DataElement
|
|
281
|
-
|| obj instanceof abaplint.Objects.LockObject
|
|
282
|
-
|| obj instanceof abaplint.Objects.MessageClass
|
|
283
|
-
|| obj instanceof abaplint.Objects.MIMEObject
|
|
284
|
-
|| obj instanceof abaplint.Objects.Oauth2Profile
|
|
285
|
-
|| obj instanceof abaplint.Objects.WebMIME
|
|
286
|
-
|| obj instanceof abaplint.Objects.TypePool
|
|
287
|
-
|| obj instanceof abaplint.Objects.TableType) {
|
|
288
|
-
list.push(imp(`${this.escapeNamespace(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
for (const obj of reg.getObjects()) {
|
|
292
|
-
if (obj instanceof abaplint.Objects.FunctionGroup) {
|
|
293
|
-
list.push(imp(`${this.escapeNamespace(obj.getName().toLowerCase())}.fugr`));
|
|
294
|
-
}
|
|
295
|
-
else if (obj instanceof abaplint.Objects.Class) {
|
|
296
|
-
if (obj.getName().toUpperCase() !== "CL_ABAP_CHAR_UTILITIES"
|
|
297
|
-
&& this.hasClassConstructor(reg, obj)) {
|
|
298
|
-
// this will not solve all problems with class constors 100%, but probably good enough
|
|
299
|
-
late.push(imp(`${this.escapeNamespace(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
list.push(imp(`${this.escapeNamespace(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
else if (obj instanceof abaplint.Objects.Interface) {
|
|
306
|
-
list.push(imp(`${this.escapeNamespace(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return [...list.sort(), ...late].join("\n");
|
|
310
|
-
}
|
|
311
|
-
// class constructors might make early use of eg. constants from interfaces
|
|
312
|
-
// sub classes will import() super classes and trigger a class constructor of the super
|
|
313
|
-
hasClassConstructor(reg, clas) {
|
|
314
|
-
if (clas.getDefinition()?.getMethodDefinitions().getByName("CLASS_CONSTRUCTOR") !== undefined) {
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
317
|
-
const sup = clas.getDefinition()?.getSuperClass();
|
|
318
|
-
if (sup !== undefined) {
|
|
319
|
-
const superClass = reg.getObject("CLAS", sup);
|
|
320
|
-
if (superClass) {
|
|
321
|
-
return this.hasClassConstructor(reg, superClass);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return false;
|
|
325
|
-
}
|
|
326
206
|
}
|
|
327
207
|
exports.UnitTest = UnitTest;
|
|
328
208
|
//# sourceMappingURL=unit_test.js.map
|