@ugo-studio/jspp 0.1.4 → 0.1.5
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/dist/analysis/scope.js +17 -0
- package/dist/analysis/typeAnalyzer.js +7 -1
- package/dist/ast/symbols.js +29 -0
- package/dist/ast/types.js +0 -6
- package/dist/cli-utils/args.js +57 -0
- package/dist/cli-utils/colors.js +9 -0
- package/dist/cli-utils/file-utils.js +20 -0
- package/dist/cli-utils/spinner.js +55 -0
- package/dist/cli.js +105 -30
- package/dist/core/codegen/class-handlers.js +10 -6
- package/dist/core/codegen/control-flow-handlers.js +31 -21
- package/dist/core/codegen/declaration-handlers.js +10 -6
- package/dist/core/codegen/expression-handlers.js +202 -60
- package/dist/core/codegen/function-handlers.js +179 -70
- package/dist/core/codegen/helpers.js +107 -17
- package/dist/core/codegen/index.js +9 -8
- package/dist/core/codegen/literal-handlers.js +15 -6
- package/dist/core/codegen/statement-handlers.js +67 -53
- package/dist/core/codegen/visitor.js +3 -1
- package/package.json +1 -1
- package/src/prelude/any_value.hpp +195 -342
- package/src/prelude/any_value_access.hpp +78 -30
- package/src/prelude/any_value_defines.hpp +74 -35
- package/src/prelude/any_value_helpers.hpp +73 -180
- package/src/prelude/exception.hpp +1 -0
- package/src/prelude/exception_helpers.hpp +4 -4
- package/src/prelude/index.hpp +9 -2
- package/src/prelude/library/array.hpp +190 -0
- package/src/prelude/library/console.hpp +6 -5
- package/src/prelude/library/error.hpp +10 -8
- package/src/prelude/library/function.hpp +10 -0
- package/src/prelude/library/global.hpp +20 -0
- package/src/prelude/library/math.hpp +308 -0
- package/src/prelude/library/object.hpp +288 -0
- package/src/prelude/library/performance.hpp +1 -1
- package/src/prelude/library/process.hpp +39 -0
- package/src/prelude/library/promise.hpp +53 -43
- package/src/prelude/library/symbol.hpp +45 -57
- package/src/prelude/library/timer.hpp +6 -6
- package/src/prelude/types.hpp +48 -0
- package/src/prelude/utils/access.hpp +182 -11
- package/src/prelude/utils/assignment_operators.hpp +99 -0
- package/src/prelude/utils/log_any_value/array.hpp +8 -8
- package/src/prelude/utils/log_any_value/function.hpp +6 -4
- package/src/prelude/utils/log_any_value/object.hpp +41 -24
- package/src/prelude/utils/log_any_value/primitives.hpp +3 -1
- package/src/prelude/utils/operators.hpp +750 -274
- package/src/prelude/utils/well_known_symbols.hpp +12 -0
- package/src/prelude/values/array.hpp +8 -6
- package/src/prelude/values/descriptors.hpp +2 -2
- package/src/prelude/values/function.hpp +71 -62
- package/src/prelude/values/helpers/array.hpp +64 -28
- package/src/prelude/values/helpers/function.hpp +77 -92
- package/src/prelude/values/helpers/iterator.hpp +3 -3
- package/src/prelude/values/helpers/object.hpp +54 -9
- package/src/prelude/values/helpers/promise.hpp +3 -3
- package/src/prelude/values/iterator.hpp +1 -1
- package/src/prelude/values/object.hpp +10 -3
- package/src/prelude/values/promise.hpp +3 -3
- package/src/prelude/values/prototypes/array.hpp +851 -12
- package/src/prelude/values/prototypes/function.hpp +2 -2
- package/src/prelude/values/prototypes/iterator.hpp +5 -5
- package/src/prelude/values/prototypes/number.hpp +153 -0
- package/src/prelude/values/prototypes/object.hpp +2 -2
- package/src/prelude/values/prototypes/promise.hpp +40 -30
- package/src/prelude/values/prototypes/string.hpp +28 -28
- package/src/prelude/values/prototypes/symbol.hpp +20 -3
- package/src/prelude/values/shape.hpp +52 -0
|
@@ -11,6 +11,8 @@ export function visitVariableDeclaration(node, context) {
|
|
|
11
11
|
const name = varDecl.name.getText();
|
|
12
12
|
const scope = this.getScopeForNode(varDecl);
|
|
13
13
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(name, scope);
|
|
14
|
+
// Mark the symbol as checked
|
|
15
|
+
this.markSymbolAsChecked(name, context.topLevelScopeSymbols, context.localScopeSymbols);
|
|
14
16
|
let initializer = "";
|
|
15
17
|
if (varDecl.initializer) {
|
|
16
18
|
const initExpr = varDecl.initializer;
|
|
@@ -18,7 +20,9 @@ export function visitVariableDeclaration(node, context) {
|
|
|
18
20
|
...context,
|
|
19
21
|
lambdaName: ts.isArrowFunction(initExpr) ? name : undefined, // Pass the variable name for arrow functions
|
|
20
22
|
};
|
|
21
|
-
let initText =
|
|
23
|
+
let initText = ts.isNumericLiteral(initExpr)
|
|
24
|
+
? initExpr.getText()
|
|
25
|
+
: this.visit(initExpr, initContext);
|
|
22
26
|
if (ts.isIdentifier(initExpr)) {
|
|
23
27
|
const initScope = this.getScopeForNode(initExpr);
|
|
24
28
|
const initTypeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(initExpr.text, initScope);
|
|
@@ -26,21 +30,21 @@ export function visitVariableDeclaration(node, context) {
|
|
|
26
30
|
if (initTypeInfo &&
|
|
27
31
|
!initTypeInfo.isParameter &&
|
|
28
32
|
!initTypeInfo.isBuiltin) {
|
|
29
|
-
initText = this.getDerefCode(initText, varName, initTypeInfo);
|
|
33
|
+
initText = this.getDerefCode(initText, varName, initContext, initTypeInfo);
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
initializer = " = " + initText;
|
|
33
37
|
}
|
|
34
38
|
const isLetOrConst = (varDecl.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0;
|
|
35
39
|
const shouldDeref = context.derefBeforeAssignment &&
|
|
36
|
-
(!context.
|
|
40
|
+
(!context.localScopeSymbols.has(name));
|
|
37
41
|
const assignmentTarget = shouldDeref
|
|
38
|
-
? this.getDerefCode(name, name, typeInfo)
|
|
42
|
+
? this.getDerefCode(name, name, context, typeInfo)
|
|
39
43
|
: (typeInfo.needsHeapAllocation ? `*${name}` : name);
|
|
40
44
|
if (isLetOrConst) {
|
|
41
45
|
// If there's no initializer, it should be assigned undefined.
|
|
42
46
|
if (!initializer) {
|
|
43
|
-
return `${assignmentTarget} = jspp::
|
|
47
|
+
return `${assignmentTarget} = jspp::Constants::UNDEFINED`;
|
|
44
48
|
}
|
|
45
49
|
return `${assignmentTarget}${initializer}`;
|
|
46
50
|
}
|
|
@@ -55,7 +59,7 @@ export function visitVariableDeclaration(node, context) {
|
|
|
55
59
|
// but is kept for safety.
|
|
56
60
|
const initValue = initializer
|
|
57
61
|
? initializer.substring(3)
|
|
58
|
-
: "jspp::
|
|
62
|
+
: "jspp::Constants::UNDEFINED";
|
|
59
63
|
if (typeInfo.needsHeapAllocation) {
|
|
60
64
|
return `auto ${name} = std::make_shared<jspp::AnyValue>(${initValue})`;
|
|
61
65
|
}
|
|
@@ -16,7 +16,7 @@ export function visitObjectPropertyName(node, context) {
|
|
|
16
16
|
if (ts.isIdentifier(compExpr)) {
|
|
17
17
|
const scope = this.getScopeForNode(compExpr);
|
|
18
18
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(compExpr.getText(), scope);
|
|
19
|
-
propName = this.getDerefCode(propName, this.getJsVarName(compExpr), typeInfo);
|
|
19
|
+
propName = this.getDerefCode(propName, this.getJsVarName(compExpr), context, typeInfo);
|
|
20
20
|
}
|
|
21
21
|
return propName;
|
|
22
22
|
}
|
|
@@ -29,7 +29,7 @@ export function visitObjectLiteralExpression(node, context) {
|
|
|
29
29
|
const obj = node;
|
|
30
30
|
const objVar = this.generateUniqueName("__obj_", this.getDeclaredSymbols(node));
|
|
31
31
|
let code = `([&]() {
|
|
32
|
-
${this.indent()} auto ${objVar} = jspp::AnyValue::
|
|
32
|
+
${this.indent()} auto ${objVar} = jspp::AnyValue::make_object_with_proto({}, ::Object.get_own_property("prototype"));\n`;
|
|
33
33
|
this.indentationLevel++;
|
|
34
34
|
for (const prop of obj.properties) {
|
|
35
35
|
if (ts.isPropertyAssignment(prop)) {
|
|
@@ -43,7 +43,7 @@ ${this.indent()} auto ${objVar} = jspp::AnyValue::make_object({});\n`;
|
|
|
43
43
|
const scope = this.getScopeForNode(initializer);
|
|
44
44
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(initializer.text, scope);
|
|
45
45
|
if (typeInfo && !typeInfo.isBuiltin && !typeInfo.isParameter) {
|
|
46
|
-
value = this.getDerefCode(value, this.getJsVarName(initializer), typeInfo);
|
|
46
|
+
value = this.getDerefCode(value, this.getJsVarName(initializer), context, typeInfo);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
code +=
|
|
@@ -58,7 +58,7 @@ ${this.indent()} auto ${objVar} = jspp::AnyValue::make_object({});\n`;
|
|
|
58
58
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(prop.name.text, scope);
|
|
59
59
|
let value = this.visit(prop.name, context);
|
|
60
60
|
if (typeInfo && !typeInfo.isBuiltin && !typeInfo.isParameter) {
|
|
61
|
-
value = this.getDerefCode(value, this.getJsVarName(prop.name), typeInfo);
|
|
61
|
+
value = this.getDerefCode(value, this.getJsVarName(prop.name), context, typeInfo);
|
|
62
62
|
}
|
|
63
63
|
code +=
|
|
64
64
|
`${this.indent()}${objVar}.define_data_property(${key}, ${value});\n`;
|
|
@@ -112,13 +112,16 @@ export function visitArrayLiteralExpression(node, context) {
|
|
|
112
112
|
const scope = this.getScopeForNode(elem);
|
|
113
113
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(elem.text, scope);
|
|
114
114
|
if (typeInfo && !typeInfo.isBuiltin && !typeInfo.isParameter) {
|
|
115
|
-
elemText = this.getDerefCode(elemText, this.getJsVarName(elem), typeInfo);
|
|
115
|
+
elemText = this.getDerefCode(elemText, this.getJsVarName(elem), context, typeInfo);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
return elemText;
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
});
|
|
120
|
+
const elementsJoined = elements.join(", ");
|
|
121
|
+
const elementsSpan = elements.length > 0
|
|
122
|
+
? `std::span<const jspp::AnyValue>((const jspp::AnyValue[]){${elementsJoined}}, ${elements.length})`
|
|
123
|
+
: "std::span<const jspp::AnyValue>{}";
|
|
124
|
+
return `jspp::AnyValue::make_array_with_proto(${elementsSpan}, ::Array.get_own_property("prototype"))`;
|
|
122
125
|
}
|
|
123
126
|
export function visitPrefixUnaryExpression(node, context) {
|
|
124
127
|
const prefixUnaryExpr = node;
|
|
@@ -130,7 +133,7 @@ export function visitPrefixUnaryExpression(node, context) {
|
|
|
130
133
|
const scope = this.getScopeForNode(prefixUnaryExpr.operand);
|
|
131
134
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(prefixUnaryExpr.operand.getText(), scope);
|
|
132
135
|
if (context.derefBeforeAssignment) {
|
|
133
|
-
target = this.getDerefCode(operand, operand, typeInfo);
|
|
136
|
+
target = this.getDerefCode(operand, operand, context, typeInfo);
|
|
134
137
|
}
|
|
135
138
|
else if (typeInfo.needsHeapAllocation) {
|
|
136
139
|
target = `*${operand}`;
|
|
@@ -144,7 +147,7 @@ export function visitPrefixUnaryExpression(node, context) {
|
|
|
144
147
|
const scope = this.getScopeForNode(prefixUnaryExpr.operand);
|
|
145
148
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(prefixUnaryExpr.operand.getText(), scope);
|
|
146
149
|
if (context.derefBeforeAssignment) {
|
|
147
|
-
target = this.getDerefCode(operand, operand, typeInfo);
|
|
150
|
+
target = this.getDerefCode(operand, operand, context, typeInfo);
|
|
148
151
|
}
|
|
149
152
|
else if (typeInfo.needsHeapAllocation) {
|
|
150
153
|
target = `*${operand}`;
|
|
@@ -163,7 +166,7 @@ export function visitPostfixUnaryExpression(node, context) {
|
|
|
163
166
|
const scope = this.getScopeForNode(postfixUnaryExpr.operand);
|
|
164
167
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(postfixUnaryExpr.operand.getText(), scope);
|
|
165
168
|
if (context.derefBeforeAssignment) {
|
|
166
|
-
target = this.getDerefCode(operand, operand, typeInfo);
|
|
169
|
+
target = this.getDerefCode(operand, operand, context, typeInfo);
|
|
167
170
|
}
|
|
168
171
|
else if (typeInfo.needsHeapAllocation) {
|
|
169
172
|
target = `*${operand}`;
|
|
@@ -199,7 +202,10 @@ export function visitPropertyAccessExpression(node, context) {
|
|
|
199
202
|
!typeInfo.isParameter &&
|
|
200
203
|
!typeInfo.isBuiltin &&
|
|
201
204
|
ts.isIdentifier(propAccess.expression)) {
|
|
202
|
-
finalExpr = this.getDerefCode(exprText, this.getJsVarName(propAccess.expression), typeInfo);
|
|
205
|
+
finalExpr = this.getDerefCode(exprText, this.getJsVarName(propAccess.expression), context, typeInfo);
|
|
206
|
+
}
|
|
207
|
+
if (propAccess.questionDotToken) {
|
|
208
|
+
return `jspp::Access::optional_get_property(${finalExpr}, "${propName}")`;
|
|
203
209
|
}
|
|
204
210
|
return `${finalExpr}.get_own_property("${propName}")`;
|
|
205
211
|
}
|
|
@@ -221,7 +227,7 @@ export function visitElementAccessExpression(node, context) {
|
|
|
221
227
|
!exprTypeInfo.isParameter &&
|
|
222
228
|
!exprTypeInfo.isBuiltin &&
|
|
223
229
|
ts.isIdentifier(elemAccess.expression)) {
|
|
224
|
-
finalExpr = this.getDerefCode(exprText, this.getJsVarName(elemAccess.expression), exprTypeInfo);
|
|
230
|
+
finalExpr = this.getDerefCode(exprText, this.getJsVarName(elemAccess.expression), context, exprTypeInfo);
|
|
225
231
|
}
|
|
226
232
|
// Dereference the argument expression if it's an identifier
|
|
227
233
|
if (ts.isIdentifier(elemAccess.argumentExpression)) {
|
|
@@ -233,9 +239,12 @@ export function visitElementAccessExpression(node, context) {
|
|
|
233
239
|
if (argTypeInfo &&
|
|
234
240
|
!argTypeInfo.isParameter &&
|
|
235
241
|
!argTypeInfo.isBuiltin) {
|
|
236
|
-
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), argTypeInfo);
|
|
242
|
+
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), context, argTypeInfo);
|
|
237
243
|
}
|
|
238
244
|
}
|
|
245
|
+
if (elemAccess.questionDotToken) {
|
|
246
|
+
return `jspp::Access::optional_get_element(${finalExpr}, ${argText})`;
|
|
247
|
+
}
|
|
239
248
|
return `${finalExpr}.get_own_property(${argText})`;
|
|
240
249
|
}
|
|
241
250
|
export function visitBinaryExpression(node, context) {
|
|
@@ -248,21 +257,84 @@ export function visitBinaryExpression(node, context) {
|
|
|
248
257
|
ts.SyntaxKind.AsteriskEqualsToken,
|
|
249
258
|
ts.SyntaxKind.SlashEqualsToken,
|
|
250
259
|
ts.SyntaxKind.PercentEqualsToken,
|
|
260
|
+
ts.SyntaxKind.AsteriskAsteriskEqualsToken,
|
|
261
|
+
ts.SyntaxKind.LessThanLessThanEqualsToken,
|
|
262
|
+
ts.SyntaxKind.GreaterThanGreaterThanEqualsToken,
|
|
263
|
+
ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
|
|
264
|
+
ts.SyntaxKind.AmpersandEqualsToken,
|
|
265
|
+
ts.SyntaxKind.BarEqualsToken,
|
|
266
|
+
ts.SyntaxKind.CaretEqualsToken,
|
|
267
|
+
ts.SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
268
|
+
ts.SyntaxKind.BarBarEqualsToken,
|
|
269
|
+
ts.SyntaxKind.QuestionQuestionEqualsToken,
|
|
251
270
|
];
|
|
252
271
|
if (assignmentOperators.includes(opToken.kind)) {
|
|
272
|
+
if (opToken.kind ===
|
|
273
|
+
ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken) {
|
|
274
|
+
const leftText = this.visit(binExpr.left, context);
|
|
275
|
+
const rightText = this.visit(binExpr.right, context);
|
|
276
|
+
let target = leftText;
|
|
277
|
+
if (ts.isIdentifier(binExpr.left)) {
|
|
278
|
+
const scope = this.getScopeForNode(binExpr.left);
|
|
279
|
+
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(binExpr.left.text, scope);
|
|
280
|
+
target = typeInfo.needsHeapAllocation
|
|
281
|
+
? `*${leftText}`
|
|
282
|
+
: leftText;
|
|
283
|
+
return `${target} = jspp::unsigned_right_shift(${target}, ${rightText})`;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (opToken.kind === ts.SyntaxKind.AsteriskAsteriskEqualsToken) {
|
|
287
|
+
const leftText = this.visit(binExpr.left, context);
|
|
288
|
+
const rightText = this.visit(binExpr.right, context);
|
|
289
|
+
let target = leftText;
|
|
290
|
+
if (ts.isIdentifier(binExpr.left)) {
|
|
291
|
+
const scope = this.getScopeForNode(binExpr.left);
|
|
292
|
+
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(binExpr.left.text, scope);
|
|
293
|
+
target = typeInfo.needsHeapAllocation
|
|
294
|
+
? `*${leftText}`
|
|
295
|
+
: leftText;
|
|
296
|
+
return `${target} = jspp::pow(${target}, ${rightText})`;
|
|
297
|
+
}
|
|
298
|
+
// For complex LHS, we need a different approach, but this is a start.
|
|
299
|
+
}
|
|
300
|
+
if (opToken.kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
|
|
301
|
+
opToken.kind === ts.SyntaxKind.BarBarEqualsToken ||
|
|
302
|
+
opToken.kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|
|
303
|
+
const leftText = this.visit(binExpr.left, context);
|
|
304
|
+
const rightText = this.visit(binExpr.right, context);
|
|
305
|
+
let target = leftText;
|
|
306
|
+
if (ts.isIdentifier(binExpr.left)) {
|
|
307
|
+
const scope = this.getScopeForNode(binExpr.left);
|
|
308
|
+
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(binExpr.left.text, scope);
|
|
309
|
+
target = typeInfo.needsHeapAllocation
|
|
310
|
+
? `*${leftText}`
|
|
311
|
+
: leftText;
|
|
312
|
+
if (opToken.kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken) {
|
|
313
|
+
return `jspp::logical_and_assign(${target}, ${rightText})`;
|
|
314
|
+
}
|
|
315
|
+
else if (opToken.kind === ts.SyntaxKind.BarBarEqualsToken) {
|
|
316
|
+
return `jspp::logical_or_assign(${target}, ${rightText})`;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
return `jspp::nullish_coalesce_assign(${target}, ${rightText})`;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
253
323
|
const leftText = this.visit(binExpr.left, context);
|
|
254
|
-
let rightText =
|
|
324
|
+
let rightText = ts.isNumericLiteral(binExpr.right)
|
|
325
|
+
? binExpr.right.getText()
|
|
326
|
+
: this.visit(binExpr.right, context);
|
|
255
327
|
if (ts.isIdentifier(binExpr.right)) {
|
|
256
328
|
const scope = this.getScopeForNode(binExpr.right);
|
|
257
329
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(binExpr.right.getText(), scope);
|
|
258
|
-
rightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), typeInfo);
|
|
330
|
+
rightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), context, typeInfo);
|
|
259
331
|
}
|
|
260
332
|
let target = leftText;
|
|
261
333
|
if (ts.isIdentifier(binExpr.left)) {
|
|
262
334
|
const scope = this.getScopeForNode(binExpr.left);
|
|
263
335
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(binExpr.left.getText(), scope);
|
|
264
336
|
if (context.derefBeforeAssignment) {
|
|
265
|
-
target = this.getDerefCode(leftText, leftText, typeInfo);
|
|
337
|
+
target = this.getDerefCode(leftText, leftText, context, typeInfo);
|
|
266
338
|
}
|
|
267
339
|
else if (typeInfo.needsHeapAllocation) {
|
|
268
340
|
target = `*${leftText}`;
|
|
@@ -271,7 +343,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
271
343
|
return `${target} ${op} ${rightText}`;
|
|
272
344
|
}
|
|
273
345
|
if (opToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
274
|
-
|
|
346
|
+
let rightText = this.visit(binExpr.right, context);
|
|
275
347
|
if (ts.isPropertyAccessExpression(binExpr.left)) {
|
|
276
348
|
const propAccess = binExpr.left;
|
|
277
349
|
if (propAccess.expression.kind === ts.SyntaxKind.SuperKeyword) {
|
|
@@ -285,7 +357,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
285
357
|
if (rightTypeInfo &&
|
|
286
358
|
!rightTypeInfo.isParameter &&
|
|
287
359
|
!rightTypeInfo.isBuiltin) {
|
|
288
|
-
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), rightTypeInfo);
|
|
360
|
+
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), context, rightTypeInfo);
|
|
289
361
|
}
|
|
290
362
|
}
|
|
291
363
|
// Approximate super assignment as setting property on 'this'
|
|
@@ -298,7 +370,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
298
370
|
const scope = this.getScopeForNode(propAccess.expression);
|
|
299
371
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(propAccess.expression.getText(), scope);
|
|
300
372
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
301
|
-
finalObjExpr = this.getDerefCode(objExprText, this.getJsVarName(propAccess.expression), typeInfo);
|
|
373
|
+
finalObjExpr = this.getDerefCode(objExprText, this.getJsVarName(propAccess.expression), context, typeInfo);
|
|
302
374
|
}
|
|
303
375
|
}
|
|
304
376
|
let finalRightText = rightText;
|
|
@@ -309,7 +381,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
309
381
|
if (rightTypeInfo &&
|
|
310
382
|
!rightTypeInfo.isParameter &&
|
|
311
383
|
!rightTypeInfo.isBuiltin) {
|
|
312
|
-
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), rightTypeInfo);
|
|
384
|
+
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), context, rightTypeInfo);
|
|
313
385
|
}
|
|
314
386
|
}
|
|
315
387
|
return `${finalObjExpr}.set_own_property("${propName}", ${finalRightText})`;
|
|
@@ -323,7 +395,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
323
395
|
const scope = this.getScopeForNode(elemAccess.expression);
|
|
324
396
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(elemAccess.expression.getText(), scope);
|
|
325
397
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
326
|
-
finalObjExpr = this.getDerefCode(objExprText, this.getJsVarName(elemAccess.expression), typeInfo);
|
|
398
|
+
finalObjExpr = this.getDerefCode(objExprText, this.getJsVarName(elemAccess.expression), context, typeInfo);
|
|
327
399
|
}
|
|
328
400
|
}
|
|
329
401
|
if (ts.isIdentifier(elemAccess.argumentExpression)) {
|
|
@@ -333,7 +405,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
333
405
|
if (argTypeInfo &&
|
|
334
406
|
!argTypeInfo.isParameter &&
|
|
335
407
|
!argTypeInfo.isBuiltin) {
|
|
336
|
-
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), argTypeInfo);
|
|
408
|
+
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), context, argTypeInfo);
|
|
337
409
|
}
|
|
338
410
|
}
|
|
339
411
|
let finalRightText = rightText;
|
|
@@ -344,7 +416,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
344
416
|
if (rightTypeInfo &&
|
|
345
417
|
!rightTypeInfo.isParameter &&
|
|
346
418
|
!rightTypeInfo.isBuiltin) {
|
|
347
|
-
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), rightTypeInfo);
|
|
419
|
+
finalRightText = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), context, rightTypeInfo);
|
|
348
420
|
}
|
|
349
421
|
}
|
|
350
422
|
return `${finalObjExpr}.set_own_property(${argText}, ${finalRightText})`;
|
|
@@ -358,8 +430,11 @@ export function visitBinaryExpression(node, context) {
|
|
|
358
430
|
if (typeInfo?.isConst) {
|
|
359
431
|
return `jspp::Exception::throw_immutable_assignment()`;
|
|
360
432
|
}
|
|
433
|
+
if (ts.isNumericLiteral(binExpr.right)) {
|
|
434
|
+
rightText = binExpr.right.getText();
|
|
435
|
+
}
|
|
361
436
|
const target = context.derefBeforeAssignment
|
|
362
|
-
? this.getDerefCode(leftText, leftText, typeInfo)
|
|
437
|
+
? this.getDerefCode(leftText, leftText, context, typeInfo)
|
|
363
438
|
: (typeInfo.needsHeapAllocation ? `*${leftText}` : leftText);
|
|
364
439
|
return `${target} ${op} ${rightText}`;
|
|
365
440
|
}
|
|
@@ -373,7 +448,7 @@ export function visitBinaryExpression(node, context) {
|
|
|
373
448
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(binExpr.left)})`;
|
|
374
449
|
}
|
|
375
450
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
376
|
-
finalLeft = this.getDerefCode(leftText, this.getJsVarName(binExpr.left), typeInfo);
|
|
451
|
+
finalLeft = this.getDerefCode(leftText, this.getJsVarName(binExpr.left), context, typeInfo);
|
|
377
452
|
}
|
|
378
453
|
}
|
|
379
454
|
let finalRight = rightText;
|
|
@@ -385,24 +460,53 @@ export function visitBinaryExpression(node, context) {
|
|
|
385
460
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(binExpr.right)})`;
|
|
386
461
|
}
|
|
387
462
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
388
|
-
finalRight = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), typeInfo);
|
|
463
|
+
finalRight = this.getDerefCode(rightText, this.getJsVarName(binExpr.right), context, typeInfo);
|
|
389
464
|
}
|
|
390
465
|
}
|
|
466
|
+
if (opToken.kind === ts.SyntaxKind.InKeyword) {
|
|
467
|
+
return `jspp::Access::in(${finalLeft}, ${finalRight})`;
|
|
468
|
+
}
|
|
469
|
+
if (opToken.kind === ts.SyntaxKind.InstanceOfKeyword) {
|
|
470
|
+
return `jspp::Access::instance_of(${finalLeft}, ${finalRight})`;
|
|
471
|
+
}
|
|
472
|
+
if (opToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
473
|
+
return `jspp::logical_and(${finalLeft}, ${finalRight})`;
|
|
474
|
+
}
|
|
475
|
+
if (opToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
476
|
+
return `jspp::logical_or(${finalLeft}, ${finalRight})`;
|
|
477
|
+
}
|
|
478
|
+
if (opToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
479
|
+
return `jspp::nullish_coalesce(${finalLeft}, ${finalRight})`;
|
|
480
|
+
}
|
|
481
|
+
// Optimizations to prevent calling make_number multiple times
|
|
482
|
+
if (ts.isNumericLiteral(binExpr.left)) {
|
|
483
|
+
finalLeft = binExpr.left.getText();
|
|
484
|
+
}
|
|
485
|
+
if (ts.isNumericLiteral(binExpr.right)) {
|
|
486
|
+
finalRight = binExpr.right.getText();
|
|
487
|
+
}
|
|
391
488
|
if (opToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken) {
|
|
392
|
-
return
|
|
489
|
+
return `jspp::is_strictly_equal_to(${finalLeft}, ${finalRight})`;
|
|
393
490
|
}
|
|
394
491
|
if (opToken.kind === ts.SyntaxKind.EqualsEqualsToken) {
|
|
395
|
-
return
|
|
492
|
+
return `jspp::is_equal_to(${finalLeft}, ${finalRight})`;
|
|
396
493
|
}
|
|
397
494
|
if (opToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
|
|
398
|
-
return
|
|
495
|
+
return `jspp::not_strictly_equal_to(${finalLeft}, ${finalRight})`;
|
|
399
496
|
}
|
|
400
497
|
if (opToken.kind === ts.SyntaxKind.ExclamationEqualsToken) {
|
|
401
|
-
return
|
|
498
|
+
return `jspp::not_equal_to(${finalLeft}, ${finalRight})`;
|
|
402
499
|
}
|
|
403
500
|
if (opToken.kind === ts.SyntaxKind.AsteriskAsteriskToken) {
|
|
404
501
|
return `jspp::pow(${finalLeft}, ${finalRight})`;
|
|
405
502
|
}
|
|
503
|
+
if (opToken.kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken) {
|
|
504
|
+
return `jspp::unsigned_right_shift(${finalLeft}, ${finalRight})`;
|
|
505
|
+
}
|
|
506
|
+
// Optimizations to prevent calling make_number multiple times
|
|
507
|
+
if (ts.isNumericLiteral(binExpr.left) && ts.isNumericLiteral(binExpr.right)) {
|
|
508
|
+
return `jspp::AnyValue::make_number(${finalLeft} ${op} ${finalRight})`;
|
|
509
|
+
}
|
|
406
510
|
if (op === "+" ||
|
|
407
511
|
op === "-" ||
|
|
408
512
|
op === "*" ||
|
|
@@ -410,7 +514,9 @@ export function visitBinaryExpression(node, context) {
|
|
|
410
514
|
op === "%" ||
|
|
411
515
|
op === "^" ||
|
|
412
516
|
op === "&" ||
|
|
413
|
-
op === "|"
|
|
517
|
+
op === "|" ||
|
|
518
|
+
op === "<<" ||
|
|
519
|
+
op === ">>") {
|
|
414
520
|
return `(${finalLeft} ${op} ${finalRight})`;
|
|
415
521
|
}
|
|
416
522
|
return `${finalLeft} ${op} ${finalRight}`;
|
|
@@ -426,7 +532,7 @@ export function visitConditionalExpression(node, context) {
|
|
|
426
532
|
...context,
|
|
427
533
|
isFunctionBody: false,
|
|
428
534
|
});
|
|
429
|
-
return `(${condition})
|
|
535
|
+
return `is_truthy(${condition}) ? ${whenTrueStmt} : ${whenFalseStmt}`;
|
|
430
536
|
}
|
|
431
537
|
export function visitCallExpression(node, context) {
|
|
432
538
|
const callExpr = node;
|
|
@@ -437,9 +543,9 @@ export function visitCallExpression(node, context) {
|
|
|
437
543
|
}
|
|
438
544
|
const args = callExpr.arguments.map((arg) => this.visit(arg, context))
|
|
439
545
|
.join(", ");
|
|
440
|
-
return `(${context.superClassVar}).
|
|
546
|
+
return `(${context.superClassVar}).call(${this.globalThisVar}, (const jspp::AnyValue[]){${args}}, "super")`;
|
|
441
547
|
}
|
|
442
|
-
const
|
|
548
|
+
const argsArray = callExpr.arguments
|
|
443
549
|
.map((arg) => {
|
|
444
550
|
const argText = this.visit(arg, context);
|
|
445
551
|
if (ts.isIdentifier(arg)) {
|
|
@@ -448,13 +554,17 @@ export function visitCallExpression(node, context) {
|
|
|
448
554
|
if (!typeInfo) {
|
|
449
555
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(arg)})`;
|
|
450
556
|
}
|
|
451
|
-
if (typeInfo && !typeInfo.
|
|
452
|
-
return this.getDerefCode(argText, this.getJsVarName(arg), typeInfo);
|
|
557
|
+
if (typeInfo && !typeInfo.isBuiltin) {
|
|
558
|
+
return this.getDerefCode(argText, this.getJsVarName(arg), context, typeInfo);
|
|
453
559
|
}
|
|
454
560
|
}
|
|
455
561
|
return argText;
|
|
456
|
-
})
|
|
457
|
-
|
|
562
|
+
});
|
|
563
|
+
const args = argsArray.join(", ");
|
|
564
|
+
const argsCount = argsArray.length;
|
|
565
|
+
const argsSpan = argsCount > 0
|
|
566
|
+
? `std::span<const jspp::AnyValue>((const jspp::AnyValue[]){${args}}, ${argsCount})`
|
|
567
|
+
: "std::span<const jspp::AnyValue>{}";
|
|
458
568
|
// Handle obj.method() -> pass obj as 'this'
|
|
459
569
|
if (ts.isPropertyAccessExpression(callee)) {
|
|
460
570
|
const propAccess = callee;
|
|
@@ -463,7 +573,7 @@ export function visitCallExpression(node, context) {
|
|
|
463
573
|
throw new Error("super.method() called but no super class variable found in context");
|
|
464
574
|
}
|
|
465
575
|
const propName = propAccess.name.getText();
|
|
466
|
-
return `(${context.superClassVar}).get_own_property("prototype").get_own_property("${propName}").
|
|
576
|
+
return `(${context.superClassVar}).get_own_property("prototype").get_own_property("${propName}").call(${this.globalThisVar}, ${argsSpan}, "${this.escapeString(propName)}")`;
|
|
467
577
|
}
|
|
468
578
|
const objExpr = propAccess.expression;
|
|
469
579
|
const propName = propAccess.name.getText();
|
|
@@ -477,10 +587,13 @@ export function visitCallExpression(node, context) {
|
|
|
477
587
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(objExpr)})`;
|
|
478
588
|
}
|
|
479
589
|
if (typeInfo && !typeInfo.isBuiltin && !typeInfo.isParameter) {
|
|
480
|
-
derefObj = this.getDerefCode(objCode, this.getJsVarName(objExpr), typeInfo);
|
|
590
|
+
derefObj = this.getDerefCode(objCode, this.getJsVarName(objExpr), context, typeInfo);
|
|
481
591
|
}
|
|
482
592
|
}
|
|
483
|
-
|
|
593
|
+
if (callExpr.questionDotToken) {
|
|
594
|
+
return `jspp::Access::optional_call(${derefObj}.get_own_property("${propName}"), ${derefObj}, ${argsSpan}, "${this.escapeString(propName)}")`;
|
|
595
|
+
}
|
|
596
|
+
return `([&](){ auto __obj = ${derefObj}; return __obj.get_own_property("${propName}").call(__obj, ${argsSpan}, "${this.escapeString(propName)}"); })()`;
|
|
484
597
|
}
|
|
485
598
|
// Handle obj[method]() -> pass obj as 'this'
|
|
486
599
|
if (ts.isElementAccessExpression(callee)) {
|
|
@@ -495,7 +608,7 @@ export function visitCallExpression(node, context) {
|
|
|
495
608
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(objExpr)})`;
|
|
496
609
|
}
|
|
497
610
|
if (typeInfo && !typeInfo.isBuiltin && !typeInfo.isParameter) {
|
|
498
|
-
derefObj = this.getDerefCode(objCode, this.getJsVarName(objExpr), typeInfo);
|
|
611
|
+
derefObj = this.getDerefCode(objCode, this.getJsVarName(objExpr), context, typeInfo);
|
|
499
612
|
}
|
|
500
613
|
}
|
|
501
614
|
let argText = visitObjectPropertyName.call(this, elemAccess.argumentExpression, { ...context, isBracketNotationPropertyAccess: true });
|
|
@@ -509,10 +622,13 @@ export function visitCallExpression(node, context) {
|
|
|
509
622
|
}
|
|
510
623
|
if (argTypeInfo && !argTypeInfo.isParameter &&
|
|
511
624
|
!argTypeInfo.isBuiltin) {
|
|
512
|
-
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), argTypeInfo);
|
|
625
|
+
argText = this.getDerefCode(argText, this.getJsVarName(elemAccess.argumentExpression), context, argTypeInfo);
|
|
513
626
|
}
|
|
514
627
|
}
|
|
515
|
-
|
|
628
|
+
if (callExpr.questionDotToken) {
|
|
629
|
+
return `jspp::Access::optional_call(${derefObj}.get_own_property(${argText}), ${derefObj}, ${argsSpan})`;
|
|
630
|
+
}
|
|
631
|
+
return `([&](){ auto __obj = ${derefObj}; return __obj.get_own_property(${argText}).call(__obj, ${argsSpan}); })()`;
|
|
516
632
|
}
|
|
517
633
|
const calleeCode = this.visit(callee, context);
|
|
518
634
|
let derefCallee = calleeCode;
|
|
@@ -526,7 +642,7 @@ export function visitCallExpression(node, context) {
|
|
|
526
642
|
derefCallee = calleeCode;
|
|
527
643
|
}
|
|
528
644
|
else if (typeInfo) {
|
|
529
|
-
derefCallee = this.getDerefCode(calleeCode, this.getJsVarName(callee), typeInfo);
|
|
645
|
+
derefCallee = this.getDerefCode(calleeCode, this.getJsVarName(callee), context, typeInfo);
|
|
530
646
|
}
|
|
531
647
|
}
|
|
532
648
|
let calleeName = "";
|
|
@@ -539,12 +655,18 @@ export function visitCallExpression(node, context) {
|
|
|
539
655
|
calleeName = this.escapeString(funcExpr.name?.getText() || "");
|
|
540
656
|
}
|
|
541
657
|
// Pass undefined as 'this' for normal function calls
|
|
542
|
-
|
|
658
|
+
const calleeNamePart = calleeName && calleeName.length > 0
|
|
659
|
+
? `, "${calleeName}"`
|
|
660
|
+
: "";
|
|
661
|
+
if (callExpr.questionDotToken) {
|
|
662
|
+
return `jspp::Access::optional_call(${derefCallee}, jspp::Constants::UNDEFINED, ${argsSpan}${calleeNamePart})`;
|
|
663
|
+
}
|
|
664
|
+
return `${derefCallee}.call(jspp::Constants::UNDEFINED, ${argsSpan}${calleeNamePart})`;
|
|
543
665
|
}
|
|
544
666
|
export function visitVoidExpression(node, context) {
|
|
545
667
|
const voidExpr = node;
|
|
546
668
|
const exprText = this.visit(voidExpr.expression, context);
|
|
547
|
-
return `(${exprText}, jspp::
|
|
669
|
+
return `(${exprText}, jspp::Constants::UNDEFINED)`;
|
|
548
670
|
}
|
|
549
671
|
export function visitTemplateExpression(node, context) {
|
|
550
672
|
const templateExpr = node;
|
|
@@ -562,7 +684,7 @@ export function visitTemplateExpression(node, context) {
|
|
|
562
684
|
else if (typeInfo &&
|
|
563
685
|
!typeInfo.isParameter &&
|
|
564
686
|
!typeInfo.isBuiltin) {
|
|
565
|
-
finalExpr = this.getDerefCode(exprText, this.getJsVarName(expr), typeInfo);
|
|
687
|
+
finalExpr = this.getDerefCode(exprText, this.getJsVarName(expr), context, typeInfo);
|
|
566
688
|
}
|
|
567
689
|
}
|
|
568
690
|
result += ` + (${finalExpr})`;
|
|
@@ -576,18 +698,20 @@ export function visitNewExpression(node, context) {
|
|
|
576
698
|
const newExpr = node;
|
|
577
699
|
const exprText = this.visit(newExpr.expression, context);
|
|
578
700
|
let derefExpr = exprText;
|
|
701
|
+
let name = `"${exprText}"`;
|
|
579
702
|
if (ts.isIdentifier(newExpr.expression)) {
|
|
703
|
+
name = this.getJsVarName(newExpr.expression);
|
|
580
704
|
const scope = this.getScopeForNode(newExpr.expression);
|
|
581
705
|
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(newExpr.expression.getText(), scope);
|
|
582
706
|
if (!typeInfo &&
|
|
583
707
|
!this.isBuiltinObject(newExpr.expression)) {
|
|
584
|
-
return `jspp::Exception::throw_unresolved_reference(${
|
|
708
|
+
return `jspp::Exception::throw_unresolved_reference(${name})`;
|
|
585
709
|
}
|
|
586
710
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
587
|
-
derefExpr = this.getDerefCode(exprText,
|
|
711
|
+
derefExpr = this.getDerefCode(exprText, name, context, typeInfo);
|
|
588
712
|
}
|
|
589
713
|
}
|
|
590
|
-
const
|
|
714
|
+
const argsArray = newExpr.arguments
|
|
591
715
|
? newExpr.arguments
|
|
592
716
|
.map((arg) => {
|
|
593
717
|
const argText = this.visit(arg, context);
|
|
@@ -599,14 +723,18 @@ export function visitNewExpression(node, context) {
|
|
|
599
723
|
return `jspp::Exception::throw_unresolved_reference(${this.getJsVarName(arg)})`;
|
|
600
724
|
}
|
|
601
725
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
602
|
-
return this.getDerefCode(argText, this.getJsVarName(arg), typeInfo);
|
|
726
|
+
return this.getDerefCode(argText, this.getJsVarName(arg), context, typeInfo);
|
|
603
727
|
}
|
|
604
728
|
}
|
|
605
729
|
return argText;
|
|
606
730
|
})
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
731
|
+
: [];
|
|
732
|
+
const args = argsArray.join(", ");
|
|
733
|
+
const argsCount = argsArray.length;
|
|
734
|
+
const argsSpan = argsCount > 0
|
|
735
|
+
? `std::span<const jspp::AnyValue>((const jspp::AnyValue[]){${args}}, ${argsCount})`
|
|
736
|
+
: "std::span<const jspp::AnyValue>{}";
|
|
737
|
+
return `${derefExpr}.construct(${argsSpan}, ${name})`;
|
|
610
738
|
}
|
|
611
739
|
export function visitTypeOfExpression(node, context) {
|
|
612
740
|
const typeOfExpr = node;
|
|
@@ -620,10 +748,10 @@ export function visitTypeOfExpression(node, context) {
|
|
|
620
748
|
derefExpr = `/* undeclared variable: ${this.getJsVarName(typeOfExpr.expression)} */`; // typeof undeclared variable is 'undefined'
|
|
621
749
|
}
|
|
622
750
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
623
|
-
derefExpr = this.getDerefCode(exprText, this.getJsVarName(typeOfExpr.expression), typeInfo);
|
|
751
|
+
derefExpr = this.getDerefCode(exprText, this.getJsVarName(typeOfExpr.expression), context, typeInfo);
|
|
624
752
|
}
|
|
625
753
|
}
|
|
626
|
-
return `jspp::Access::
|
|
754
|
+
return `jspp::Access::type_of(${derefExpr})`;
|
|
627
755
|
}
|
|
628
756
|
export function visitAwaitExpression(node, context) {
|
|
629
757
|
const awaitExpr = node;
|
|
@@ -639,11 +767,25 @@ export function visitAwaitExpression(node, context) {
|
|
|
639
767
|
// We can just throw before co_await.
|
|
640
768
|
// But we need to return a string expression.
|
|
641
769
|
// Using comma operator: (throw..., AnyValue())
|
|
642
|
-
return `(jspp::Exception::throw_unresolved_reference(${this.getJsVarName(awaitExpr.expression)}), co_await jspp::
|
|
770
|
+
return `(jspp::Exception::throw_unresolved_reference(${this.getJsVarName(awaitExpr.expression)}), co_await jspp::Constants::UNDEFINED)`;
|
|
643
771
|
}
|
|
644
772
|
if (typeInfo && !typeInfo.isParameter && !typeInfo.isBuiltin) {
|
|
645
|
-
derefExpr = this.getDerefCode(exprText, this.getJsVarName(awaitExpr.expression), typeInfo);
|
|
773
|
+
derefExpr = this.getDerefCode(exprText, this.getJsVarName(awaitExpr.expression), context, typeInfo);
|
|
646
774
|
}
|
|
647
775
|
}
|
|
648
776
|
return `co_await ${derefExpr}`;
|
|
649
777
|
}
|
|
778
|
+
export function visitDeleteExpression(node, context) {
|
|
779
|
+
const expr = node.expression;
|
|
780
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
781
|
+
const obj = this.visit(expr.expression, context);
|
|
782
|
+
const prop = `jspp::AnyValue::make_string("${expr.name.getText()}")`;
|
|
783
|
+
return `jspp::Access::delete_property(${obj}, ${prop})`;
|
|
784
|
+
}
|
|
785
|
+
else if (ts.isElementAccessExpression(expr)) {
|
|
786
|
+
const obj = this.visit(expr.expression, context);
|
|
787
|
+
const prop = this.visit(expr.argumentExpression, context);
|
|
788
|
+
return `jspp::Access::delete_property(${obj}, ${prop})`;
|
|
789
|
+
}
|
|
790
|
+
return "jspp::Constants::TRUE"; // delete on non-property is true in JS
|
|
791
|
+
}
|