@abaplint/transpiler 2.7.5 → 2.7.7

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.
@@ -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
- if (concat.startsWith("`")) {
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
- chunk.appendString(c.concatTokens() + " ");
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("'" + c.concatTokens() + "' ");
33
+ chunk.appendString("\\\"" + c.concatTokens() + "\\\" ");
29
34
  }
30
35
  else {
31
- chunk.appendString(c.concatTokens() + " ");
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("'" + c.concatTokens() + "' ");
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 findKeys;
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 " + traversal.traverse(where).getCode() + " ";
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
- findKeys(node, traversal) {
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
- const tabl = traversal.findTable(from[0]);
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("\"'" + name + "' = '\" + " + source.getCode() + ".get() + \"'\"");
22
+ s.push("\"\\\"" + name + "\\\" = '\" + " + source.getCode() + ".get() + \"'\"");
23
23
  }
24
24
  options.push(`"set": [${s.join(",")}]`);
25
25
  }
@@ -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;
@@ -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.5",
3
+ "version": "2.7.7",
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.100.4",
32
+ "@abaplint/core": "^2.101.0",
33
33
  "source-map": "^0.7.4"
34
34
  },
35
35
  "devDependencies": {