@abaplint/transpiler 1.6.68 → 1.7.2
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.
|
@@ -22,12 +22,15 @@ class ConstantTranspiler {
|
|
|
22
22
|
str = node.findFirstExpression(core_1.Expressions.TextElementString);
|
|
23
23
|
}
|
|
24
24
|
if (str) {
|
|
25
|
-
|
|
25
|
+
let res = str.getFirstToken().getStr();
|
|
26
26
|
if (res.startsWith("'") && this.addGet === false) {
|
|
27
27
|
const code = "new abap.types.Character({length: " + (res.length - 2) + "}).set(" + this.escape(res) + ")";
|
|
28
28
|
return new chunk_1.Chunk().append(code, node, traversal);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
+
if (res.startsWith("'")) {
|
|
32
|
+
res = "'" + res.substring(1, res.length - 1).trimEnd() + "'";
|
|
33
|
+
}
|
|
31
34
|
const code = this.escape(res);
|
|
32
35
|
return new chunk_1.Chunk().append(code, node, traversal);
|
|
33
36
|
}
|
|
@@ -12,14 +12,14 @@ class DoTranspiler {
|
|
|
12
12
|
const source = new expressions_1.SourceTranspiler(true).transpile(found, traversal).getCode();
|
|
13
13
|
const idSource = unique_identifier_1.UniqueIdentifier.get();
|
|
14
14
|
const id = unique_identifier_1.UniqueIdentifier.get();
|
|
15
|
-
return new chunk_1.Chunk(`const ${idSource} = ${source};
|
|
16
|
-
for (let ${id} = 0; ${id} < ${idSource}; ${id}++) {
|
|
15
|
+
return new chunk_1.Chunk(`const ${idSource} = ${source};
|
|
16
|
+
for (let ${id} = 0; ${id} < ${idSource}; ${id}++) {
|
|
17
17
|
abap.builtin.sy.get().index.set(${id} + 1);`);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
20
|
const unique = unique_identifier_1.UniqueIdentifier.get();
|
|
21
|
-
return new chunk_1.Chunk(`let ${unique} = 1;
|
|
22
|
-
while (true) {
|
|
21
|
+
return new chunk_1.Chunk(`let ${unique} = 1;
|
|
22
|
+
while (true) {
|
|
23
23
|
abap.builtin.sy.get().index.set(${unique}++);`);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -5,22 +5,38 @@ const abaplint = require("@abaplint/core");
|
|
|
5
5
|
const chunk_1 = require("../chunk");
|
|
6
6
|
class EndMethodTranspiler {
|
|
7
7
|
transpile(node, traversal) {
|
|
8
|
+
var _a, _b;
|
|
8
9
|
const token = node.getFirstToken();
|
|
9
10
|
const scope = traversal.findCurrentScopeByToken(token);
|
|
10
11
|
if (scope === undefined) {
|
|
11
12
|
throw new Error("EndMethodTranspiler, scope not found");
|
|
12
13
|
}
|
|
13
14
|
let returning = "";
|
|
15
|
+
let methodName = undefined;
|
|
16
|
+
if ((scope === null || scope === void 0 ? void 0 : scope.getIdentifier().stype) === abaplint.ScopeType.Method) {
|
|
17
|
+
methodName = scope === null || scope === void 0 ? void 0 : scope.getIdentifier().sname;
|
|
18
|
+
}
|
|
19
|
+
let className = undefined;
|
|
20
|
+
if (((_a = scope === null || scope === void 0 ? void 0 : scope.getParent()) === null || _a === void 0 ? void 0 : _a.getIdentifier().stype) === abaplint.ScopeType.ClassImplementation) {
|
|
21
|
+
className = (_b = scope === null || scope === void 0 ? void 0 : scope.getParent()) === null || _b === void 0 ? void 0 : _b.getIdentifier().sname;
|
|
22
|
+
}
|
|
23
|
+
if (methodName && className) {
|
|
24
|
+
const classDef = scope.findClassDefinition(className);
|
|
25
|
+
const methodDef = classDef === null || classDef === void 0 ? void 0 : classDef.getMethodDefinitions().getByName(methodName);
|
|
26
|
+
if (methodDef && methodDef.getExceptions().length > 0) {
|
|
27
|
+
returning += "abap.builtin.sy.get().subrc.set(0);\n";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
14
30
|
const vars = scope.getData().vars;
|
|
15
31
|
for (const n in vars) {
|
|
16
32
|
const identifier = vars[n];
|
|
17
33
|
if (identifier.getMeta().includes("returning" /* MethodReturning */)) {
|
|
18
|
-
returning
|
|
34
|
+
returning += "return " + n.toLowerCase() + ";\n";
|
|
19
35
|
}
|
|
20
36
|
}
|
|
21
37
|
const data = scope.getIdentifier();
|
|
22
38
|
if (data.stype === abaplint.ScopeType.Method && data.sname.toLowerCase() === "constructor") {
|
|
23
|
-
returning
|
|
39
|
+
returning += "return this;\n";
|
|
24
40
|
}
|
|
25
41
|
return new chunk_1.Chunk().append(returning + "}", node, traversal);
|
|
26
42
|
}
|
package/build/src/traversal.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare class Traversal {
|
|
|
17
17
|
findStatementInFile(pos: abaplint.Position): abaplint.Nodes.StatementNode | undefined;
|
|
18
18
|
private scopeCache;
|
|
19
19
|
findCurrentScopeByToken(token: abaplint.Token): abaplint.ISpaghettiScopeNode | undefined;
|
|
20
|
-
getInterfaceDefinition(token: abaplint.Token):
|
|
20
|
+
getInterfaceDefinition(token: abaplint.Token): abaplint.IInterfaceDefinition | undefined;
|
|
21
21
|
getClassDefinition(token: abaplint.Token): abaplint.IClassDefinition | undefined;
|
|
22
22
|
private isClassAttribute;
|
|
23
23
|
prefixAndName(t: abaplint.Token, filename?: string): string;
|
|
@@ -31,8 +31,9 @@ export declare class Traversal {
|
|
|
31
31
|
isInterfaceAttribute(token: abaplint.Token): string | undefined;
|
|
32
32
|
private findReadOrWriteReference;
|
|
33
33
|
buildConstructorContents(scope: abaplint.ISpaghettiScopeNode | undefined, def: abaplint.IClassDefinition, inputName: string): string;
|
|
34
|
+
private dataFromInterfaces;
|
|
34
35
|
determineType(node: abaplint.Nodes.ExpressionNode | abaplint.Nodes.StatementNode, scope: abaplint.ISpaghettiScopeNode | undefined): abaplint.AbstractType | undefined;
|
|
35
|
-
registerClassOrInterface(def: abaplint.IClassDefinition | undefined): string;
|
|
36
|
+
registerClassOrInterface(def: abaplint.IClassDefinition | abaplint.IInterfaceDefinition | undefined): string;
|
|
36
37
|
lookupClassOrInterface(name: string | undefined, token: abaplint.Token | undefined): string;
|
|
37
38
|
private buildPrefix;
|
|
38
39
|
protected traverseStructure(node: abaplint.Nodes.StructureNode): Chunk;
|
package/build/src/traversal.js
CHANGED
|
@@ -75,7 +75,6 @@ class Traversal {
|
|
|
75
75
|
}
|
|
76
76
|
return node;
|
|
77
77
|
}
|
|
78
|
-
// todo, add explicit return type,
|
|
79
78
|
getInterfaceDefinition(token) {
|
|
80
79
|
let scope = this.findCurrentScopeByToken(token);
|
|
81
80
|
while (scope !== undefined) {
|
|
@@ -103,8 +102,12 @@ class Traversal {
|
|
|
103
102
|
throw new Error("isClassAttribute, unable to lookup position");
|
|
104
103
|
}
|
|
105
104
|
const name = token.getStr();
|
|
105
|
+
if (name.toLowerCase() === "me") {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
106
108
|
const found = scope.findScopeForVariable(name);
|
|
107
|
-
if (found && found.stype === abaplint.ScopeType.
|
|
109
|
+
if (found && (found.stype === abaplint.ScopeType.MethodInstance
|
|
110
|
+
|| found.stype === abaplint.ScopeType.ClassImplementation)) {
|
|
108
111
|
return true;
|
|
109
112
|
}
|
|
110
113
|
return false;
|
|
@@ -126,9 +129,9 @@ class Traversal {
|
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
131
|
-
name =
|
|
132
|
+
const className = this.isStaticClassAttribute(t);
|
|
133
|
+
if (className) {
|
|
134
|
+
name = className + "." + name;
|
|
132
135
|
}
|
|
133
136
|
else if (name === "super") {
|
|
134
137
|
return name;
|
|
@@ -142,7 +145,6 @@ class Traversal {
|
|
|
142
145
|
return name;
|
|
143
146
|
}
|
|
144
147
|
isStaticClassAttribute(token) {
|
|
145
|
-
var _a;
|
|
146
148
|
const scope = this.findCurrentScopeByToken(token);
|
|
147
149
|
if (scope === undefined) {
|
|
148
150
|
throw new Error(`isStaticClassAttribute, unable to lookup position, ${token.getStr()},${token.getRow()},${token.getCol()},` +
|
|
@@ -154,7 +156,8 @@ class Traversal {
|
|
|
154
156
|
if (found && id
|
|
155
157
|
&& id.getMeta().includes("static" /* Static */)
|
|
156
158
|
&& found.stype === abaplint.ScopeType.ClassImplementation) {
|
|
157
|
-
|
|
159
|
+
// console.dir(found.sname);
|
|
160
|
+
return found.sname.toLowerCase();
|
|
158
161
|
}
|
|
159
162
|
return undefined;
|
|
160
163
|
}
|
|
@@ -243,35 +246,30 @@ class Traversal {
|
|
|
243
246
|
return undefined;
|
|
244
247
|
}
|
|
245
248
|
buildConstructorContents(scope, def, inputName) {
|
|
246
|
-
|
|
249
|
+
/*
|
|
250
|
+
const vars = scope?.getData().vars;
|
|
247
251
|
if (vars === undefined || Object.keys(vars).length === 0) {
|
|
248
|
-
|
|
252
|
+
return "";
|
|
249
253
|
}
|
|
254
|
+
*/
|
|
250
255
|
let ret = "";
|
|
251
256
|
if (def.getSuperClass() !== undefined) {
|
|
252
257
|
// todo, more here, there might be parameters to pass
|
|
253
258
|
// for now just pass the same input
|
|
254
259
|
ret += `await super.constructor_(${inputName});\n`;
|
|
255
260
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
261
|
+
ret += "this.me = new abap.types.ABAPObject();\n";
|
|
262
|
+
ret += "this.me.set(this);\n";
|
|
263
|
+
for (const a of def.getAttributes().getAll()) {
|
|
264
|
+
if (a.getMeta().includes("static" /* Static */) === true) {
|
|
259
265
|
continue;
|
|
260
266
|
}
|
|
261
|
-
const name =
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
&& name.includes("$") === false
|
|
268
|
-
&& name !== "me") {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
ret += "this." + name + " = " + new types_1.TranspileTypes().toType(identifier.getType()) + ";\n";
|
|
272
|
-
if (name === "me") {
|
|
273
|
-
ret += "this.me.set(this);\n";
|
|
274
|
-
}
|
|
267
|
+
const name = a.getName().toLowerCase();
|
|
268
|
+
ret += "this." + name + " = " + new types_1.TranspileTypes().toType(a.getType()) + ";\n";
|
|
269
|
+
}
|
|
270
|
+
// attributes from directly implemented interfaces(not interfaces implemented in super classes)
|
|
271
|
+
for (const i of def.getImplementing()) {
|
|
272
|
+
ret += this.dataFromInterfaces(i.name, scope);
|
|
275
273
|
}
|
|
276
274
|
// handle aliases after initialization of carrier variables
|
|
277
275
|
for (const a of def.getAliases().getAll()) {
|
|
@@ -283,6 +281,25 @@ class Traversal {
|
|
|
283
281
|
}
|
|
284
282
|
return ret;
|
|
285
283
|
}
|
|
284
|
+
dataFromInterfaces(name, scope) {
|
|
285
|
+
let ret = "";
|
|
286
|
+
let intf = scope === null || scope === void 0 ? void 0 : scope.findInterfaceDefinition(name);
|
|
287
|
+
if (intf === undefined) {
|
|
288
|
+
const iglobal = this.reg.getObject("INTF", name);
|
|
289
|
+
intf = iglobal === null || iglobal === void 0 ? void 0 : iglobal.getDefinition();
|
|
290
|
+
}
|
|
291
|
+
for (const a of (intf === null || intf === void 0 ? void 0 : intf.getAttributes().getAll()) || []) {
|
|
292
|
+
if (a.getMeta().includes("static" /* Static */) === true) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const n = name.toLowerCase() + "$" + a.getName().toLowerCase();
|
|
296
|
+
ret += "this." + n + " = " + new types_1.TranspileTypes().toType(a.getType()) + ";\n";
|
|
297
|
+
}
|
|
298
|
+
for (const i of (intf === null || intf === void 0 ? void 0 : intf.getImplementing()) || []) {
|
|
299
|
+
ret += this.dataFromInterfaces(i.name, scope);
|
|
300
|
+
}
|
|
301
|
+
return ret;
|
|
302
|
+
}
|
|
286
303
|
determineType(node, scope) {
|
|
287
304
|
var _a;
|
|
288
305
|
if (scope === undefined) {
|
package/build/src/unit_test.js
CHANGED
|
@@ -4,28 +4,28 @@ exports.UnitTest = void 0;
|
|
|
4
4
|
const abaplint = require("@abaplint/core");
|
|
5
5
|
class UnitTest {
|
|
6
6
|
initializationScript(reg, dbSetup) {
|
|
7
|
-
return `import runtime from "@abaplint/runtime";
|
|
8
|
-
global.abap = new runtime.ABAP();
|
|
9
|
-
${this.buildImports(reg)}
|
|
10
|
-
export async function initDB() {
|
|
11
|
-
return global.abap.initDB(\`${dbSetup}\`);
|
|
7
|
+
return `import runtime from "@abaplint/runtime";
|
|
8
|
+
global.abap = new runtime.ABAP();
|
|
9
|
+
${this.buildImports(reg)}
|
|
10
|
+
export async function initDB() {
|
|
11
|
+
return global.abap.initDB(\`${dbSetup}\`);
|
|
12
12
|
}`;
|
|
13
13
|
}
|
|
14
14
|
unitTestScript(reg, skip) {
|
|
15
|
-
let ret = `import fs from "fs";
|
|
16
|
-
import path from "path";
|
|
17
|
-
import {dirname} from 'path';
|
|
18
|
-
import {fileURLToPath} from 'url';
|
|
19
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
import {initDB} from "./init.mjs";
|
|
21
|
-
import runtime from "@abaplint/runtime";
|
|
22
|
-
|
|
23
|
-
async function run() {
|
|
24
|
-
await initDB();
|
|
25
|
-
const unit = new runtime.UnitTestResult();
|
|
26
|
-
let clas;
|
|
27
|
-
let locl;
|
|
28
|
-
let meth;
|
|
15
|
+
let ret = `import fs from "fs";
|
|
16
|
+
import path from "path";
|
|
17
|
+
import {dirname} from 'path';
|
|
18
|
+
import {fileURLToPath} from 'url';
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
import {initDB} from "./init.mjs";
|
|
21
|
+
import runtime from "@abaplint/runtime";
|
|
22
|
+
|
|
23
|
+
async function run() {
|
|
24
|
+
await initDB();
|
|
25
|
+
const unit = new runtime.UnitTestResult();
|
|
26
|
+
let clas;
|
|
27
|
+
let locl;
|
|
28
|
+
let meth;
|
|
29
29
|
try {\n`;
|
|
30
30
|
for (const obj of reg.getObjects()) {
|
|
31
31
|
if (reg.isDependency(obj) || !(obj instanceof abaplint.Objects.Class)) {
|
|
@@ -40,8 +40,8 @@ try {\n`;
|
|
|
40
40
|
|| def.methods.length === 0) {
|
|
41
41
|
continue;
|
|
42
42
|
}
|
|
43
|
-
ret += `{
|
|
44
|
-
const {${def.name}} = await import("./${obj.getName().toLowerCase()}.${obj.getType().toLowerCase()}.testclasses.mjs");
|
|
43
|
+
ret += `{
|
|
44
|
+
const {${def.name}} = await import("./${obj.getName().toLowerCase()}.${obj.getType().toLowerCase()}.testclasses.mjs");
|
|
45
45
|
locl = clas.addTestClass("${def.name}");\n`;
|
|
46
46
|
ret += `if (${def.name}.class_setup) await ${def.name}.class_setup();\n`;
|
|
47
47
|
for (const m of def.methods) {
|
|
@@ -69,24 +69,24 @@ locl = clas.addTestClass("${def.name}");\n`;
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
ret += `// -------------------END-------------------
|
|
73
|
-
console.log(abap.console.get());
|
|
74
|
-
fs.writeFileSync(__dirname + path.sep + "output.xml", unit.xUnitXML());
|
|
75
|
-
} catch (e) {
|
|
76
|
-
if (meth) {
|
|
77
|
-
meth.fail();
|
|
78
|
-
}
|
|
79
|
-
console.log(abap.console.get());
|
|
80
|
-
fs.writeFileSync(__dirname + path.sep + "output.xml", unit.xUnitXML());
|
|
81
|
-
throw e;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
run().then(() => {
|
|
86
|
-
process.exit();
|
|
87
|
-
}).catch((err) => {
|
|
88
|
-
console.log(err);
|
|
89
|
-
process.exit(1);
|
|
72
|
+
ret += `// -------------------END-------------------
|
|
73
|
+
console.log(abap.console.get());
|
|
74
|
+
fs.writeFileSync(__dirname + path.sep + "output.xml", unit.xUnitXML());
|
|
75
|
+
} catch (e) {
|
|
76
|
+
if (meth) {
|
|
77
|
+
meth.fail();
|
|
78
|
+
}
|
|
79
|
+
console.log(abap.console.get());
|
|
80
|
+
fs.writeFileSync(__dirname + path.sep + "output.xml", unit.xUnitXML());
|
|
81
|
+
throw e;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
run().then(() => {
|
|
86
|
+
process.exit();
|
|
87
|
+
}).catch((err) => {
|
|
88
|
+
console.log(err);
|
|
89
|
+
process.exit(1);
|
|
90
90
|
});`;
|
|
91
91
|
return ret;
|
|
92
92
|
}
|
package/package.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Transpiler",
|
|
5
|
-
"main": "build/src/index.js",
|
|
6
|
-
"typings": "build/src/index.d.ts",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/abaplint/transpiler.git"
|
|
10
|
-
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"compile": "tsc",
|
|
13
|
-
"publish:
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"@types/
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@abaplint/transpiler",
|
|
3
|
+
"version": "1.7.2",
|
|
4
|
+
"description": "Transpiler",
|
|
5
|
+
"main": "build/src/index.js",
|
|
6
|
+
"typings": "build/src/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/abaplint/transpiler.git"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"compile": "tsc",
|
|
13
|
+
"publish:minor": "npm --no-git-tag-version version minor && rm -rf build && npm install && npm run test && npm publish --access public",
|
|
14
|
+
"publish:patch": "npm --no-git-tag-version version patch && rm -rf build && npm install && npm run test && npm publish --access public",
|
|
15
|
+
"test": "npm run compile && mocha"
|
|
16
|
+
},
|
|
17
|
+
"mocha": {
|
|
18
|
+
"recursive": true,
|
|
19
|
+
"reporter": "progress",
|
|
20
|
+
"spec": "build/test/**/*.js",
|
|
21
|
+
"require": "source-map-support/register"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ABAP",
|
|
25
|
+
"abaplint"
|
|
26
|
+
],
|
|
27
|
+
"author": "abaplint",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@abaplint/core": "^2.83.16",
|
|
31
|
+
"source-map": "^0.7.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/chai": "^4.3.0",
|
|
35
|
+
"@types/mocha": "^9.0.0",
|
|
36
|
+
"chai": "^4.3.4",
|
|
37
|
+
"mocha": "^9.1.3",
|
|
38
|
+
"source-map-support": "^0.5.21",
|
|
39
|
+
"typescript": "^4.5.4"
|
|
40
|
+
}
|
|
41
|
+
}
|