@abaplint/transpiler 2.7.1 → 2.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.
- package/build/src/db/index.js +9 -3
- package/build/src/db/pg_database_schema.d.ts +9 -0
- package/build/src/db/pg_database_schema.js +121 -0
- package/build/src/index.d.ts +1 -1
- package/build/src/statements/class_implementation.js +2 -1
- package/build/src/structures/interface.js +1 -0
- package/build/src/traversal.d.ts +2 -0
- package/build/src/traversal.js +27 -11
- package/package.json +1 -1
package/build/src/db/index.js
CHANGED
|
@@ -4,6 +4,12 @@ exports.DatabaseSetup = void 0;
|
|
|
4
4
|
/* eslint-disable max-len */
|
|
5
5
|
const abaplint = require("@abaplint/core");
|
|
6
6
|
const sqlite_database_schema_1 = require("./sqlite_database_schema");
|
|
7
|
+
const pg_database_schema_1 = require("./pg_database_schema");
|
|
8
|
+
/////////////////////////
|
|
9
|
+
// NOTES
|
|
10
|
+
/////////////////////////
|
|
11
|
+
// Postgres is case sensitive, so all column names should be lower case
|
|
12
|
+
// Sqlite escapes field names with single qoute, postgres with double
|
|
7
13
|
class DatabaseSetup {
|
|
8
14
|
constructor(reg) {
|
|
9
15
|
this.reg = reg;
|
|
@@ -13,7 +19,7 @@ class DatabaseSetup {
|
|
|
13
19
|
schemas: {
|
|
14
20
|
sqlite: new sqlite_database_schema_1.SQLiteDatabaseSchema(this.reg).run(),
|
|
15
21
|
hdb: ["todo"],
|
|
16
|
-
pg:
|
|
22
|
+
pg: new pg_database_schema_1.PGDatabaseSchema(this.reg).run(),
|
|
17
23
|
},
|
|
18
24
|
insert: this.buildInsert(options),
|
|
19
25
|
};
|
|
@@ -57,7 +63,7 @@ class DatabaseSetup {
|
|
|
57
63
|
const type = tabl.parseType(this.reg);
|
|
58
64
|
if (type instanceof abaplint.BasicTypes.StructureType && type.getComponents().length >= 3) {
|
|
59
65
|
// todo, this should take the client number from the settings
|
|
60
|
-
return `INSERT INTO t000 ('
|
|
66
|
+
return `INSERT INTO t000 ('mandt', 'cccategory', 'ccnocliind') VALUES ('123', '', '');`;
|
|
61
67
|
}
|
|
62
68
|
else {
|
|
63
69
|
return "";
|
|
@@ -71,7 +77,7 @@ class DatabaseSetup {
|
|
|
71
77
|
}
|
|
72
78
|
let ret = "";
|
|
73
79
|
for (const m of msag.getMessages()) {
|
|
74
|
-
ret += `INSERT INTO t100 (
|
|
80
|
+
ret += `INSERT INTO t100 ("sprsl", "arbgb", "msgnr", "text") VALUES ('E', '${msag.getName().padEnd(20, " ")}', '${m.getNumber()}', '${this.escape(m.getMessage().padEnd(73, " "))}');\n`;
|
|
75
81
|
}
|
|
76
82
|
return ret;
|
|
77
83
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PGDatabaseSchema = void 0;
|
|
4
|
+
const abaplint = require("@abaplint/core");
|
|
5
|
+
class PGDatabaseSchema {
|
|
6
|
+
constructor(reg) {
|
|
7
|
+
this.reg = reg;
|
|
8
|
+
}
|
|
9
|
+
run() {
|
|
10
|
+
const statements = [];
|
|
11
|
+
// CREATE TABLEs
|
|
12
|
+
for (const obj of this.reg.getObjects()) {
|
|
13
|
+
if (obj instanceof abaplint.Objects.Table
|
|
14
|
+
&& obj.getTableCategory() === abaplint.Objects.TableCategory.Transparent) {
|
|
15
|
+
statements.push(this.buildTABL(obj).trim());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// CREATE VIEWs after TABLEs
|
|
19
|
+
// todo: what if the view is based on another view?
|
|
20
|
+
for (const obj of this.reg.getObjects()) {
|
|
21
|
+
if (obj instanceof abaplint.Objects.View) {
|
|
22
|
+
statements.push(this.buildVIEW(obj).trim());
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return statements;
|
|
26
|
+
}
|
|
27
|
+
//////////////////
|
|
28
|
+
// https://www.sqlite.org/lang_createview.html
|
|
29
|
+
buildVIEW(view) {
|
|
30
|
+
const fields = view.getFields();
|
|
31
|
+
let firstTabname = "";
|
|
32
|
+
const columns = fields === null || fields === void 0 ? void 0 : fields.map((f) => {
|
|
33
|
+
firstTabname = "'" + f.TABNAME.toLowerCase() + "'";
|
|
34
|
+
return firstTabname + "." + f.FIELDNAME.toLowerCase() + " AS " + f.VIEWFIELD.toLowerCase();
|
|
35
|
+
}).join(", ");
|
|
36
|
+
let from = "";
|
|
37
|
+
let previous = "";
|
|
38
|
+
for (const j of view.getJoin() || []) {
|
|
39
|
+
if (previous === "") {
|
|
40
|
+
from += "'" + j.LTAB.toLowerCase() + "' INNER JOIN '" + j.RTAB.toLowerCase() + "' ON '" + j.LTAB.toLowerCase() + "'." + j.LFIELD.toLowerCase() + " = '" + j.RTAB.toLowerCase() + "'." + j.RFIELD.toLowerCase();
|
|
41
|
+
}
|
|
42
|
+
else if (previous === j.LTAB + "," + j.RTAB) {
|
|
43
|
+
from += " AND '" + j.LTAB.toLowerCase() + "'." + j.LFIELD.toLowerCase() + " = '" + j.RTAB.toLowerCase() + "'." + j.RFIELD.toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
from += " INNER JOIN '" + j.RTAB.toLowerCase() + "' ON '" + j.LTAB.toLowerCase() + "'." + j.LFIELD.toLowerCase() + " = '" + j.RTAB.toLowerCase() + "'." + j.RFIELD.toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
previous = j.LTAB + "," + j.RTAB;
|
|
49
|
+
}
|
|
50
|
+
from = from.trim();
|
|
51
|
+
if (from === "") {
|
|
52
|
+
from = firstTabname;
|
|
53
|
+
}
|
|
54
|
+
return `CREATE VIEW '${view.getName().toLowerCase()}' AS SELECT ${columns} FROM ${from};\n`;
|
|
55
|
+
}
|
|
56
|
+
buildTABL(tabl) {
|
|
57
|
+
const type = tabl.parseType(this.reg);
|
|
58
|
+
if (!(type instanceof abaplint.BasicTypes.StructureType)) {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
const fields = [];
|
|
62
|
+
const fieldsRaw = [];
|
|
63
|
+
for (const field of type.getComponents()) {
|
|
64
|
+
if (field.type instanceof abaplint.BasicTypes.StructureType) {
|
|
65
|
+
// is a GROUP NAME
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
fieldsRaw.push(field.name.toLowerCase());
|
|
69
|
+
fields.push("\"" + field.name.toLowerCase() + "\" " + this.toType(field.type, field.name, tabl.getName()));
|
|
70
|
+
}
|
|
71
|
+
// assumption: all transparent tables have primary keys
|
|
72
|
+
// add single quotes to field names to allow for keywords as field names
|
|
73
|
+
const key = ", PRIMARY KEY(" + tabl.listKeys(this.reg)
|
|
74
|
+
.filter(e => fieldsRaw.includes(e.toLowerCase()))
|
|
75
|
+
.map(e => "\"" + e.toLowerCase() + "\"").join(",") + ")";
|
|
76
|
+
return `CREATE TABLE "${tabl.getName().toLowerCase()}" (${fields.join(", ")}${key});\n`;
|
|
77
|
+
}
|
|
78
|
+
toType(type, fieldname, errorInfo) {
|
|
79
|
+
if (type instanceof abaplint.BasicTypes.CharacterType) {
|
|
80
|
+
return `NCHAR(${type.getLength()})`;
|
|
81
|
+
}
|
|
82
|
+
else if (type instanceof abaplint.BasicTypes.TimeType) {
|
|
83
|
+
return `NCHAR(6)`;
|
|
84
|
+
}
|
|
85
|
+
else if (type instanceof abaplint.BasicTypes.DateType) {
|
|
86
|
+
return `NCHAR(8)`;
|
|
87
|
+
}
|
|
88
|
+
else if (type instanceof abaplint.BasicTypes.NumericType) {
|
|
89
|
+
// it will be fine, the runtime representation of numc is also text
|
|
90
|
+
return `NCHAR(${type.getLength()})`;
|
|
91
|
+
}
|
|
92
|
+
else if (type instanceof abaplint.BasicTypes.StringType) {
|
|
93
|
+
return `TEXT`;
|
|
94
|
+
}
|
|
95
|
+
else if (type instanceof abaplint.BasicTypes.XStringType) {
|
|
96
|
+
// it will be fine, the runtime representation of xstring is also text
|
|
97
|
+
return `TEXT`;
|
|
98
|
+
}
|
|
99
|
+
else if (type instanceof abaplint.BasicTypes.HexType) {
|
|
100
|
+
return `NCHAR(${type.getLength() * 2})`;
|
|
101
|
+
}
|
|
102
|
+
else if (type instanceof abaplint.BasicTypes.IntegerType) {
|
|
103
|
+
return `INT`;
|
|
104
|
+
}
|
|
105
|
+
else if (type instanceof abaplint.BasicTypes.FloatType
|
|
106
|
+
|| type instanceof abaplint.BasicTypes.FloatingPointType) {
|
|
107
|
+
return `REAL`;
|
|
108
|
+
}
|
|
109
|
+
else if (type instanceof abaplint.BasicTypes.PackedType) {
|
|
110
|
+
return `DECIMAL(${type.getLength()},${type.getDecimals()})`;
|
|
111
|
+
}
|
|
112
|
+
else if (type instanceof abaplint.BasicTypes.VoidType) {
|
|
113
|
+
throw `Type of ${errorInfo}-${fieldname} is VoidType(${type.getVoided()}), make sure the type is known, enable strict syntax checking`;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
throw "database_setup: " + errorInfo + "-" + fieldname + ", todo toType handle: " + type.constructor.name;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.PGDatabaseSchema = PGDatabaseSchema;
|
|
121
|
+
//# sourceMappingURL=pg_database_schema.js.map
|
package/build/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as abaplint from "@abaplint/core";
|
|
2
2
|
import { config } from "./validation";
|
|
3
3
|
import { IFile, IOutput, IProgress, ITranspilerOptions, IOutputFile } from "./types";
|
|
4
|
-
export { config, ITranspilerOptions, IFile, IProgress, IOutputFile };
|
|
4
|
+
export { config, ITranspilerOptions, IFile, IProgress, IOutputFile, IOutput };
|
|
5
5
|
export declare class Transpiler {
|
|
6
6
|
private readonly options;
|
|
7
7
|
constructor(options?: ITranspilerOptions);
|
|
@@ -23,7 +23,8 @@ class ClassImplementationTranspiler {
|
|
|
23
23
|
static INTERNAL_TYPE = 'CLAS';
|
|
24
24
|
static INTERNAL_NAME = '${traversal.buildInternalName(token.getStr(), def)}';
|
|
25
25
|
static IMPLEMENTED_INTERFACES = [${this.findImplementedByClass(traversal, def, scope).map(e => `"` + e.toUpperCase() + `"`).join(",")}];
|
|
26
|
-
static ATTRIBUTES = {${traversal.buildAttributes(def, scope).join(",\n")}}
|
|
26
|
+
static ATTRIBUTES = {${traversal.buildAttributes(def, scope).join(",\n")}};
|
|
27
|
+
static METHODS = {${traversal.buildMethods(def, scope).join(",\n")}};`, node, traversal);
|
|
27
28
|
}
|
|
28
29
|
findImplementedInterface(traversal, def, scope) {
|
|
29
30
|
if (def === undefined || scope === undefined) {
|
|
@@ -20,6 +20,7 @@ class InterfaceTranspiler {
|
|
|
20
20
|
ret += `class ${name} {\n`;
|
|
21
21
|
ret += `static INTERNAL_TYPE = 'INTF';\n`;
|
|
22
22
|
ret += `static ATTRIBUTES = {${traversal.buildAttributes(def, scope).join(",\n")}};\n`;
|
|
23
|
+
ret += `static METHODS = {${traversal.buildMethods(def, scope).join(",\n")}};\n`;
|
|
23
24
|
}
|
|
24
25
|
else if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.EndInterface) {
|
|
25
26
|
ret += "}\n";
|
package/build/src/traversal.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export declare class Traversal {
|
|
|
24
24
|
private isClassAttribute;
|
|
25
25
|
prefixAndName(t: abaplint.Token, filename?: string): string;
|
|
26
26
|
private isStaticClassAttribute;
|
|
27
|
+
buildMethods(def: abaplint.IClassDefinition | abaplint.IInterfaceDefinition | undefined, _scope: abaplint.ISpaghettiScopeNode | undefined): string[];
|
|
28
|
+
private mapVisibility;
|
|
27
29
|
buildAttributes(def: abaplint.IClassDefinition | abaplint.IInterfaceDefinition | undefined, scope: abaplint.ISpaghettiScopeNode | undefined, prefix?: string): string[];
|
|
28
30
|
isBuiltinMethod(token: abaplint.Token): boolean;
|
|
29
31
|
findMethodReference(token: abaplint.Token, scope: ISpaghettiScopeNode | undefined): undefined | {
|
package/build/src/traversal.js
CHANGED
|
@@ -169,6 +169,32 @@ class Traversal {
|
|
|
169
169
|
}
|
|
170
170
|
return undefined;
|
|
171
171
|
}
|
|
172
|
+
buildMethods(def, _scope) {
|
|
173
|
+
const methods = [];
|
|
174
|
+
if (def === undefined) {
|
|
175
|
+
return methods;
|
|
176
|
+
}
|
|
177
|
+
for (const m of def.getMethodDefinitions().getAll()) {
|
|
178
|
+
const parameters = [];
|
|
179
|
+
for (const p of m.getParameters().getAll()) {
|
|
180
|
+
const type = new transpile_types_1.TranspileTypes().toType(p.getType());
|
|
181
|
+
const optional = m.getParameters().getOptional().includes(p.getName()) ? "X" : " ";
|
|
182
|
+
parameters.push(`"${p.getName().toUpperCase()}": {"type": () => {return ${type};}, "is_optional": "${optional}"}`);
|
|
183
|
+
}
|
|
184
|
+
methods.push(`"${m.getName().toUpperCase()}": {"visibility": "${this.mapVisibility(m.getVisibility())}", "parameters": {${parameters.join(", ")}}}`);
|
|
185
|
+
}
|
|
186
|
+
return methods;
|
|
187
|
+
}
|
|
188
|
+
mapVisibility(vis) {
|
|
189
|
+
switch (vis) {
|
|
190
|
+
case abaplint.Visibility.Private:
|
|
191
|
+
return "I";
|
|
192
|
+
case abaplint.Visibility.Protected:
|
|
193
|
+
return "O";
|
|
194
|
+
default:
|
|
195
|
+
return "U";
|
|
196
|
+
}
|
|
197
|
+
}
|
|
172
198
|
buildAttributes(def, scope, prefix = "") {
|
|
173
199
|
var _a, _b;
|
|
174
200
|
const attr = [];
|
|
@@ -177,17 +203,7 @@ class Traversal {
|
|
|
177
203
|
}
|
|
178
204
|
for (const a of ((_a = def.getAttributes()) === null || _a === void 0 ? void 0 : _a.getAll()) || []) {
|
|
179
205
|
const type = new transpile_types_1.TranspileTypes().toType(a.getType());
|
|
180
|
-
|
|
181
|
-
switch (a.getVisibility()) {
|
|
182
|
-
case abaplint.Visibility.Private:
|
|
183
|
-
runtime = "I";
|
|
184
|
-
break;
|
|
185
|
-
case abaplint.Visibility.Protected:
|
|
186
|
-
runtime = "O";
|
|
187
|
-
break;
|
|
188
|
-
default:
|
|
189
|
-
runtime = "U";
|
|
190
|
-
}
|
|
206
|
+
const runtime = this.mapVisibility(a.getVisibility());
|
|
191
207
|
const isClass = a.getMeta().includes("static" /* abaplint.IdentifierMeta.Static */) ? "X" : " ";
|
|
192
208
|
attr.push(`"${prefix + a.getName().toUpperCase()}": {"type": () => {return ${type};}, "visibility": "${runtime}", "is_constant": " ", "is_class": "${isClass}"}`);
|
|
193
209
|
}
|