@abaplint/transpiler 2.7.4 → 2.7.6
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/expressions/sql_cond.d.ts +2 -1
- package/build/src/expressions/sql_cond.js +17 -11
- package/build/src/expressions/sql_from.js +9 -3
- package/build/src/expressions/sql_from_source.js +5 -1
- package/build/src/statements/insert_database.js +1 -1
- package/build/src/statements/select.d.ts +1 -1
- package/build/src/statements/select.js +6 -5
- package/build/src/statements/update_database.js +1 -1
- package/build/src/traversal.d.ts +1 -0
- package/build/src/traversal.js +9 -0
- package/package.json +2 -2
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Nodes } from "@abaplint/core";
|
|
2
|
+
import * as abaplint from "@abaplint/core";
|
|
2
3
|
import { IExpressionTranspiler } from "./_expression_transpiler";
|
|
3
4
|
import { Traversal } from "../traversal";
|
|
4
5
|
import { Chunk } from "../chunk";
|
|
5
6
|
export declare class SQLCondTranspiler implements IExpressionTranspiler {
|
|
6
|
-
transpile(node: Nodes.ExpressionNode, traversal: Traversal): Chunk;
|
|
7
|
+
transpile(node: Nodes.ExpressionNode, traversal: Traversal, table?: abaplint.Objects.Table | undefined): Chunk;
|
|
7
8
|
private sqlIn;
|
|
8
9
|
private basicCondition;
|
|
9
10
|
private sqlSource;
|
|
@@ -7,8 +7,9 @@ const chunk_1 = require("../chunk");
|
|
|
7
7
|
const simple_source3_1 = require("./simple_source3");
|
|
8
8
|
const field_chain_1 = require("./field_chain");
|
|
9
9
|
const sql_field_name_1 = require("./sql_field_name");
|
|
10
|
+
const transpile_types_1 = require("../transpile_types");
|
|
10
11
|
class SQLCondTranspiler {
|
|
11
|
-
transpile(node, traversal) {
|
|
12
|
+
transpile(node, traversal, table) {
|
|
12
13
|
var _a;
|
|
13
14
|
let ret = "";
|
|
14
15
|
for (const c of node.getChildren()) {
|
|
@@ -31,11 +32,11 @@ class SQLCondTranspiler {
|
|
|
31
32
|
ret += this.sqlIn(c, traversal);
|
|
32
33
|
}
|
|
33
34
|
else {
|
|
34
|
-
ret += this.basicCondition(c, traversal, traversal.getFilename());
|
|
35
|
+
ret += this.basicCondition(c, traversal, traversal.getFilename(), table);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
else if (c instanceof abaplint.Nodes.ExpressionNode) {
|
|
38
|
-
ret += " " + this.transpile(c, traversal).getCode();
|
|
39
|
+
ret += " " + this.transpile(c, traversal, table).getCode();
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
42
|
ret += " " + c.concatTokens();
|
|
@@ -54,10 +55,10 @@ class SQLCondTranspiler {
|
|
|
54
55
|
const ret = `" + abap.expandIN("${fieldName.concatTokens()}", ${source.concatTokens()}) + "`;
|
|
55
56
|
return ret;
|
|
56
57
|
}
|
|
57
|
-
basicCondition(c, traversal, filename) {
|
|
58
|
+
basicCondition(c, traversal, filename, table) {
|
|
58
59
|
let ret = "";
|
|
59
60
|
if (c.getChildren().length !== 3) {
|
|
60
|
-
return this.basicConditionNew(c, traversal, filename);
|
|
61
|
+
return this.basicConditionNew(c, traversal, filename, table);
|
|
61
62
|
}
|
|
62
63
|
let fieldName = undefined;
|
|
63
64
|
const fieldNameExpression = c.findDirectExpression(abaplint.Expressions.SQLFieldName);
|
|
@@ -68,7 +69,7 @@ class SQLCondTranspiler {
|
|
|
68
69
|
const source = c.findDirectExpression(abaplint.Expressions.SQLSource);
|
|
69
70
|
if (fieldName && source && operator === undefined && c.findDirectTokenByText("LIKE")) {
|
|
70
71
|
ret += fieldName + " LIKE ";
|
|
71
|
-
ret += this.sqlSource(source, traversal, filename);
|
|
72
|
+
ret += this.sqlSource(source, traversal, filename, table);
|
|
72
73
|
return ret;
|
|
73
74
|
}
|
|
74
75
|
if (fieldName === undefined || operator === undefined || source === undefined) {
|
|
@@ -82,10 +83,10 @@ class SQLCondTranspiler {
|
|
|
82
83
|
op = "<>";
|
|
83
84
|
}
|
|
84
85
|
ret += fieldName + " " + op + " ";
|
|
85
|
-
ret += this.sqlSource(source, traversal, filename);
|
|
86
|
+
ret += this.sqlSource(source, traversal, filename, table);
|
|
86
87
|
return ret;
|
|
87
88
|
}
|
|
88
|
-
sqlSource(source, traversal, filename) {
|
|
89
|
+
sqlSource(source, traversal, filename, table) {
|
|
89
90
|
let ret = "";
|
|
90
91
|
const simple = source.findDirectExpression(abaplint.Expressions.SimpleSource3);
|
|
91
92
|
const alias = source.findDirectExpression(abaplint.Expressions.SQLAliasField);
|
|
@@ -111,7 +112,12 @@ class SQLCondTranspiler {
|
|
|
111
112
|
}
|
|
112
113
|
else {
|
|
113
114
|
const concat = source.concatTokens();
|
|
114
|
-
|
|
115
|
+
const conversionField = traversal.isSQLConversion(source.getFirstToken());
|
|
116
|
+
if (conversionField) {
|
|
117
|
+
const field = (table === null || table === void 0 ? void 0 : table.parseType(traversal.reg)).getComponentByName(conversionField);
|
|
118
|
+
ret += "'\" + " + new transpile_types_1.TranspileTypes().toType(field) + ".set(" + concat + ").get() + \"'";
|
|
119
|
+
}
|
|
120
|
+
else if (concat.startsWith("`")) {
|
|
115
121
|
ret += "'" + concat.substring(1, concat.length - 1) + "'";
|
|
116
122
|
}
|
|
117
123
|
else {
|
|
@@ -120,7 +126,7 @@ class SQLCondTranspiler {
|
|
|
120
126
|
}
|
|
121
127
|
return ret;
|
|
122
128
|
}
|
|
123
|
-
basicConditionNew(node, traversal, filename) {
|
|
129
|
+
basicConditionNew(node, traversal, filename, table) {
|
|
124
130
|
let ret = "";
|
|
125
131
|
for (const child of node.getChildren()) {
|
|
126
132
|
if (ret !== "") {
|
|
@@ -132,7 +138,7 @@ class SQLCondTranspiler {
|
|
|
132
138
|
}
|
|
133
139
|
else if (child.get() instanceof abaplint.Expressions.SQLSource
|
|
134
140
|
&& child instanceof abaplint.Nodes.ExpressionNode) {
|
|
135
|
-
ret += this.sqlSource(child, traversal, filename);
|
|
141
|
+
ret += this.sqlSource(child, traversal, filename, table);
|
|
136
142
|
}
|
|
137
143
|
else {
|
|
138
144
|
ret += child.concatTokens();
|
|
@@ -22,13 +22,19 @@ class SQLFromTranspiler {
|
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
24
|
if (c.findFirstExpression(abaplint.Expressions.Dynamic)) {
|
|
25
|
-
|
|
25
|
+
let concat = c.concatTokens();
|
|
26
|
+
if (concat.startsWith("'")) {
|
|
27
|
+
// no escaping needed, guess its not possible to have table names with single or double quote part of name
|
|
28
|
+
concat = "\\\"" + concat.substring(1, concat.length - 1) + "\\\"";
|
|
29
|
+
}
|
|
30
|
+
chunk.appendString(concat + " ");
|
|
26
31
|
}
|
|
27
32
|
else if (c.concatTokens().includes("/")) {
|
|
28
|
-
chunk.appendString("
|
|
33
|
+
chunk.appendString("\\\"" + c.concatTokens() + "\\\" ");
|
|
29
34
|
}
|
|
30
35
|
else {
|
|
31
|
-
|
|
36
|
+
const concat = c.concatTokens();
|
|
37
|
+
chunk.appendString(concat + " ");
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
}
|
|
@@ -12,7 +12,11 @@ class SQLFromSourceTranspiler {
|
|
|
12
12
|
chunk.appendString(c.concatTokens() + " ");
|
|
13
13
|
}
|
|
14
14
|
else if (c.get() instanceof abaplint.Expressions.DatabaseTable && c.concatTokens().includes("/")) {
|
|
15
|
-
chunk.appendString("
|
|
15
|
+
chunk.appendString("\"" + c.concatTokens() + "\" ");
|
|
16
|
+
}
|
|
17
|
+
else if (c.get() instanceof abaplint.Expressions.DatabaseTable && c.concatTokens().startsWith("('")) {
|
|
18
|
+
const concat = c.concatTokens();
|
|
19
|
+
chunk.appendString("\\\"" + concat.substring(2, concat.length - 2).toLowerCase() + "\\\" ");
|
|
16
20
|
}
|
|
17
21
|
else {
|
|
18
22
|
chunk.appendString(c.concatTokens() + " ");
|
|
@@ -22,7 +22,7 @@ class InsertDatabaseTranspiler {
|
|
|
22
22
|
const tvalues = traversal.traverse(fromTable);
|
|
23
23
|
options.push(`"table": ` + tvalues.getCode());
|
|
24
24
|
}
|
|
25
|
-
return new chunk_1.Chunk(`await abap.statements.insertDatabase(${table.getCode()}, {${options.join(", ")}});`);
|
|
25
|
+
return new chunk_1.Chunk(`await abap.statements.insertDatabase(${table.getCode().toLowerCase()}, {${options.join(", ")}});`);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
exports.InsertDatabaseTranspiler = InsertDatabaseTranspiler;
|
|
@@ -4,6 +4,6 @@ import { Traversal } from "../traversal";
|
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class SelectTranspiler implements IStatementTranspiler {
|
|
6
6
|
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal, targetOverride?: string): Chunk;
|
|
7
|
-
private
|
|
7
|
+
private findTable;
|
|
8
8
|
private isWhereExpression;
|
|
9
9
|
}
|
|
@@ -42,6 +42,7 @@ class SelectTranspiler {
|
|
|
42
42
|
if (from) {
|
|
43
43
|
select += new sql_from_1.SQLFromTranspiler().transpile(from, traversal).getCode();
|
|
44
44
|
}
|
|
45
|
+
const { table, keys } = this.findTable(node, traversal);
|
|
45
46
|
let where = undefined;
|
|
46
47
|
for (const sqlCond of node.findAllExpressions(abaplint.Expressions.SQLCond)) {
|
|
47
48
|
if (this.isWhereExpression(node, sqlCond)) {
|
|
@@ -49,7 +50,7 @@ class SelectTranspiler {
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
if (where) {
|
|
52
|
-
select += "WHERE " +
|
|
53
|
+
select += "WHERE " + new expressions_1.SQLCondTranspiler().transpile(where, traversal, table).getCode() + " ";
|
|
53
54
|
}
|
|
54
55
|
const upTo = node.findFirstExpression(abaplint.Expressions.SQLUpTo);
|
|
55
56
|
if (upTo) {
|
|
@@ -85,7 +86,6 @@ class SelectTranspiler {
|
|
|
85
86
|
runtimeOptions = `, {` + runtimeOptionsList.join(", ") + `}`;
|
|
86
87
|
}
|
|
87
88
|
let extra = "";
|
|
88
|
-
const keys = this.findKeys(node, traversal);
|
|
89
89
|
if (keys.length > 0) {
|
|
90
90
|
extra = `, primaryKey: ${JSON.stringify(keys)}`;
|
|
91
91
|
}
|
|
@@ -118,16 +118,17 @@ class SelectTranspiler {
|
|
|
118
118
|
return new chunk_1.Chunk().append(`await abap.statements.select(${target}, {select: "${select.trim()}"${extra}}${runtimeOptions});`, node, traversal);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
findTable(node, traversal) {
|
|
122
122
|
let keys = [];
|
|
123
|
+
let tabl = undefined;
|
|
123
124
|
const from = node.findAllExpressions(abaplint.Expressions.SQLFromSource).map(e => e.concatTokens());
|
|
124
125
|
if (from.length === 1) {
|
|
125
|
-
|
|
126
|
+
tabl = traversal.findTable(from[0]);
|
|
126
127
|
if (tabl) {
|
|
127
128
|
keys = tabl.listKeys(traversal.reg).map(k => k.toLowerCase());
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
|
-
return keys;
|
|
131
|
+
return { table: tabl, keys };
|
|
131
132
|
}
|
|
132
133
|
isWhereExpression(node, expression) {
|
|
133
134
|
// check if previous token before sqlCond is "WHERE". It could also be "ON" in case of join condition
|
|
@@ -19,7 +19,7 @@ class UpdateDatabaseTranspiler {
|
|
|
19
19
|
for (const set of sets) {
|
|
20
20
|
const name = (_a = set.findDirectExpression(abaplint.Expressions.SQLFieldName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
21
21
|
const source = traversal.traverse(set.findDirectExpression(abaplint.Expressions.SQLSource));
|
|
22
|
-
s.push("\"
|
|
22
|
+
s.push("\"\\\"" + name + "\\\" = '\" + " + source.getCode() + ".get() + \"'\"");
|
|
23
23
|
}
|
|
24
24
|
options.push(`"set": [${s.join(",")}]`);
|
|
25
25
|
}
|
package/build/src/traversal.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare class Traversal {
|
|
|
28
28
|
private mapVisibility;
|
|
29
29
|
buildAttributes(def: abaplint.IClassDefinition | abaplint.IInterfaceDefinition | undefined, scope: abaplint.ISpaghettiScopeNode | undefined, prefix?: string): string[];
|
|
30
30
|
isBuiltinMethod(token: abaplint.Token): boolean;
|
|
31
|
+
isSQLConversion(token: abaplint.Token): string | undefined;
|
|
31
32
|
findMethodReference(token: abaplint.Token, scope: ISpaghettiScopeNode | undefined): undefined | {
|
|
32
33
|
def: abaplint.Types.MethodDefinition;
|
|
33
34
|
name: string;
|
package/build/src/traversal.js
CHANGED
|
@@ -241,6 +241,15 @@ class Traversal {
|
|
|
241
241
|
}
|
|
242
242
|
return false;
|
|
243
243
|
}
|
|
244
|
+
isSQLConversion(token) {
|
|
245
|
+
const scope = this.findCurrentScopeByToken(token);
|
|
246
|
+
for (const s of (scope === null || scope === void 0 ? void 0 : scope.getData().sqlConversion) || []) {
|
|
247
|
+
if (s.token.getStart().equals(token.getStart())) {
|
|
248
|
+
return s.fieldName;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
244
253
|
findMethodReference(token, scope) {
|
|
245
254
|
var _a, _b;
|
|
246
255
|
let candidate = undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.6",
|
|
4
4
|
"description": "Transpiler",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/src/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"author": "abaplint",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@abaplint/core": "^2.
|
|
32
|
+
"@abaplint/core": "^2.101.0",
|
|
33
33
|
"source-map": "^0.7.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|