typescript-to-lua 1.1.1 → 1.3.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/CHANGELOG.md +28 -0
- package/dist/LuaAST.d.ts +1 -0
- package/dist/LuaAST.js +10 -2
- package/dist/LuaLib.d.ts +4 -3
- package/dist/LuaLib.js +6 -5
- package/dist/LuaPrinter.d.ts +11 -4
- package/dist/LuaPrinter.js +58 -15
- package/dist/lualib/ArrayFlat.lua +1 -1
- package/dist/lualib/ArrayFlatMap.lua +1 -1
- package/dist/lualib/ArrayIsArray.lua +1 -1
- package/dist/lualib/ArrayReduce.lua +7 -1
- package/dist/lualib/ArrayReduceRight.lua +7 -1
- package/dist/lualib/ArraySetLength.lua +1 -1
- package/dist/lualib/ArraySplice.lua +5 -5
- package/dist/lualib/Await.lua +21 -13
- package/dist/lualib/CloneDescriptor.lua +7 -7
- package/dist/lualib/Decorate.lua +1 -1
- package/dist/lualib/DelegatedYield.lua +1 -3
- package/dist/lualib/Delete.lua +6 -6
- package/dist/lualib/Error.lua +47 -44
- package/dist/lualib/Generator.lua +1 -5
- package/dist/lualib/InstanceOf.lua +1 -1
- package/dist/lualib/InstanceOfObject.lua +1 -1
- package/dist/lualib/Map.lua +130 -134
- package/dist/lualib/MathSign.lua +8 -0
- package/dist/lualib/Number.lua +1 -1
- package/dist/lualib/NumberIsFinite.lua +1 -1
- package/dist/lualib/NumberToString.lua +3 -5
- package/dist/lualib/ObjectDefineProperty.lua +40 -8
- package/dist/lualib/ParseFloat.lua +9 -5
- package/dist/lualib/ParseInt.lua +15 -3
- package/dist/lualib/Promise.lua +28 -24
- package/dist/lualib/Set.lua +119 -123
- package/dist/lualib/SetDescriptor.lua +7 -1
- package/dist/lualib/SourceMapTraceBack.lua +1 -1
- package/dist/lualib/SparseArrayNew.lua +5 -0
- package/dist/lualib/SparseArrayPush.lua +9 -0
- package/dist/lualib/SparseArraySpread.lua +4 -0
- package/dist/lualib/StringAccess.lua +1 -1
- package/dist/lualib/StringCharCodeAt.lua +1 -1
- package/dist/lualib/StringEndsWith.lua +2 -2
- package/dist/lualib/StringPadEnd.lua +2 -2
- package/dist/lualib/StringPadStart.lua +2 -2
- package/dist/lualib/StringReplace.lua +7 -1
- package/dist/lualib/StringSlice.lua +2 -2
- package/dist/lualib/StringSplit.lua +3 -3
- package/dist/lualib/StringStartsWith.lua +1 -1
- package/dist/lualib/StringSubstr.lua +1 -1
- package/dist/lualib/StringSubstring.lua +2 -2
- package/dist/lualib/Symbol.lua +3 -5
- package/dist/lualib/WeakMap.lua +40 -42
- package/dist/lualib/WeakSet.lua +36 -38
- package/dist/lualib/lualib_bundle.lua +804 -735
- package/dist/transformation/builtins/array.js +1 -2
- package/dist/transformation/builtins/function.js +6 -4
- package/dist/transformation/builtins/index.d.ts +1 -1
- package/dist/transformation/builtins/index.js +41 -6
- package/dist/transformation/builtins/math.js +7 -1
- package/dist/transformation/builtins/object.d.ts +2 -1
- package/dist/transformation/builtins/object.js +1 -2
- package/dist/transformation/builtins/string.js +1 -2
- package/dist/transformation/context/context.d.ts +12 -0
- package/dist/transformation/context/context.js +102 -3
- package/dist/transformation/utils/diagnostics.d.ts +9 -6
- package/dist/transformation/utils/diagnostics.js +4 -3
- package/dist/transformation/utils/language-extensions.d.ts +2 -0
- package/dist/transformation/utils/language-extensions.js +7 -1
- package/dist/transformation/utils/lua-ast.d.ts +0 -1
- package/dist/transformation/utils/lua-ast.js +14 -23
- package/dist/transformation/utils/preceding-statements.d.ts +3 -0
- package/dist/transformation/utils/preceding-statements.js +11 -0
- package/dist/transformation/utils/safe-names.d.ts +4 -2
- package/dist/transformation/utils/safe-names.js +11 -5
- package/dist/transformation/utils/scope.d.ts +3 -1
- package/dist/transformation/utils/scope.js +9 -1
- package/dist/transformation/utils/typescript/index.d.ts +1 -0
- package/dist/transformation/utils/typescript/index.js +16 -1
- package/dist/transformation/utils/typescript/types.d.ts +3 -1
- package/dist/transformation/utils/typescript/types.js +40 -13
- package/dist/transformation/visitors/access.d.ts +3 -0
- package/dist/transformation/visitors/access.js +63 -36
- package/dist/transformation/visitors/binary-expression/assignments.d.ts +3 -2
- package/dist/transformation/visitors/binary-expression/assignments.js +66 -57
- package/dist/transformation/visitors/binary-expression/compound.d.ts +5 -4
- package/dist/transformation/visitors/binary-expression/compound.js +66 -68
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.d.ts +2 -2
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +54 -25
- package/dist/transformation/visitors/binary-expression/index.d.ts +3 -1
- package/dist/transformation/visitors/binary-expression/index.js +65 -23
- package/dist/transformation/visitors/call.d.ts +3 -2
- package/dist/transformation/visitors/call.js +95 -141
- package/dist/transformation/visitors/class/index.js +5 -8
- package/dist/transformation/visitors/class/members/constructor.js +3 -1
- package/dist/transformation/visitors/class/new.js +4 -6
- package/dist/transformation/visitors/conditional.js +30 -37
- package/dist/transformation/visitors/delete.js +4 -0
- package/dist/transformation/visitors/errors.js +11 -9
- package/dist/transformation/visitors/expression-list.d.ts +7 -0
- package/dist/transformation/visitors/expression-list.js +120 -0
- package/dist/transformation/visitors/expression-statement.d.ts +3 -1
- package/dist/transformation/visitors/expression-statement.js +21 -19
- package/dist/transformation/visitors/function.d.ts +2 -0
- package/dist/transformation/visitors/function.js +63 -13
- package/dist/transformation/visitors/identifier.js +5 -0
- package/dist/transformation/visitors/language-extensions/index.d.ts +4 -0
- package/dist/transformation/visitors/language-extensions/index.js +17 -0
- package/dist/transformation/visitors/language-extensions/operators.d.ts +1 -1
- package/dist/transformation/visitors/language-extensions/operators.js +7 -2
- package/dist/transformation/visitors/language-extensions/pairsIterable.d.ts +5 -0
- package/dist/transformation/visitors/language-extensions/pairsIterable.js +53 -0
- package/dist/transformation/visitors/language-extensions/table.d.ts +1 -8
- package/dist/transformation/visitors/language-extensions/table.js +55 -53
- package/dist/transformation/visitors/literal.js +69 -16
- package/dist/transformation/visitors/loops/do-while.js +34 -8
- package/dist/transformation/visitors/loops/for-of.js +4 -0
- package/dist/transformation/visitors/loops/for.js +25 -5
- package/dist/transformation/visitors/loops/utils.d.ts +1 -0
- package/dist/transformation/visitors/loops/utils.js +19 -3
- package/dist/transformation/visitors/modules/export.js +1 -1
- package/dist/transformation/visitors/namespace.js +1 -1
- package/dist/transformation/visitors/optional-chaining.d.ts +16 -0
- package/dist/transformation/visitors/optional-chaining.js +172 -0
- package/dist/transformation/visitors/sourceFile.js +4 -1
- package/dist/transformation/visitors/spread.js +14 -7
- package/dist/transformation/visitors/switch.js +29 -9
- package/dist/transformation/visitors/template.js +5 -2
- package/dist/transformation/visitors/typeof.js +3 -1
- package/dist/transformation/visitors/variable-declaration.js +37 -8
- package/dist/transformation/visitors/void.d.ts +1 -4
- package/dist/transformation/visitors/void.js +7 -12
- package/dist/transpilation/transformers.js +4 -1
- package/dist/transpilation/utils.js +2 -1
- package/language-extensions/index.d.ts +11 -1
- package/package.json +5 -5
- package/dist/lualib/OptionalChainAccess.lua +0 -6
- package/dist/lualib/OptionalFunctionCall.lua +0 -6
- package/dist/lualib/OptionalMethodCall.lua +0 -11
- package/dist/transformation/utils/transform.d.ts +0 -8
- package/dist/transformation/utils/transform.js +0 -14
|
@@ -1,35 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = exports.transformCompoundAssignment = exports.unwrapCompoundAssignmentToken = exports.isCompoundAssignmentToken =
|
|
3
|
+
exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = exports.transformCompoundAssignment = exports.unwrapCompoundAssignmentToken = exports.isCompoundAssignmentToken = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
6
|
const utils_1 = require("../../../utils");
|
|
7
|
-
const
|
|
8
|
-
const typescript_1 = require("../../utils/typescript");
|
|
7
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
9
8
|
const binary_expression_1 = require("../binary-expression");
|
|
10
9
|
const assignments_1 = require("./assignments");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const oneLit = ts.factory.createNumericLiteral("1");
|
|
19
|
-
const exp = ts.factory.createParenthesizedExpression(node.argumentExpression);
|
|
20
|
-
const addExp = ts.factory.createBinaryExpression(exp, ts.SyntaxKind.PlusToken, oneLit);
|
|
21
|
-
return [node.expression, addExp];
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
return [node.expression, node.argumentExpression];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
else if (ts.isPropertyAccessExpression(node) && (0, typescript_1.isExpressionWithEvaluationEffect)(node.expression)) {
|
|
28
|
-
return [node.expression, ts.factory.createStringLiteral(node.name.text)];
|
|
29
|
-
}
|
|
30
|
-
return [];
|
|
10
|
+
function isLuaExpressionWithSideEffect(expression) {
|
|
11
|
+
return !(lua.isLiteral(expression) || lua.isIdentifier(expression));
|
|
12
|
+
}
|
|
13
|
+
function shouldCacheTableIndexExpressions(expression, rightPrecedingStatements) {
|
|
14
|
+
return (isLuaExpressionWithSideEffect(expression.table) ||
|
|
15
|
+
isLuaExpressionWithSideEffect(expression.index) ||
|
|
16
|
+
rightPrecedingStatements.length > 0);
|
|
31
17
|
}
|
|
32
|
-
exports.parseAccessExpressionWithEvaluationEffects = parseAccessExpressionWithEvaluationEffects;
|
|
33
18
|
const compoundToAssignmentTokens = {
|
|
34
19
|
[ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken,
|
|
35
20
|
[ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken,
|
|
@@ -53,69 +38,80 @@ const unwrapCompoundAssignmentToken = (token) => compoundToAssignmentTokens[toke
|
|
|
53
38
|
exports.unwrapCompoundAssignmentToken = unwrapCompoundAssignmentToken;
|
|
54
39
|
function transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix) {
|
|
55
40
|
const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
|
|
56
|
-
const right = context.transformExpression(rhs);
|
|
57
|
-
|
|
58
|
-
if (objExpression && indexExpression) {
|
|
41
|
+
const [rightPrecedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
|
|
42
|
+
if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) {
|
|
59
43
|
// Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
|
|
60
44
|
// local __obj, __index = ${objExpression}, ${indexExpression};
|
|
61
|
-
const obj =
|
|
62
|
-
const index =
|
|
63
|
-
const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [
|
|
45
|
+
const obj = context.createTempNameForLuaExpression(left.table);
|
|
46
|
+
const index = context.createTempNameForLuaExpression(left.index);
|
|
47
|
+
const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [left.table, left.index]);
|
|
64
48
|
const accessExpression = lua.createTableIndexExpression(obj, index);
|
|
65
|
-
const tmp =
|
|
66
|
-
let tmpDeclaration;
|
|
67
|
-
let assignStatement;
|
|
49
|
+
const tmp = context.createTempNameForLuaExpression(left);
|
|
68
50
|
if (isPostfix) {
|
|
69
51
|
// local ____tmp = ____obj[____index];
|
|
70
52
|
// ____obj[____index] = ____tmp ${replacementOperator} ${right};
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
53
|
+
// return ____tmp
|
|
54
|
+
const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression);
|
|
55
|
+
const [precedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, tmp, right, rightPrecedingStatements, operator, expression);
|
|
56
|
+
const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
|
|
57
|
+
return {
|
|
58
|
+
statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
|
|
59
|
+
result: tmp,
|
|
60
|
+
};
|
|
74
61
|
}
|
|
75
62
|
else {
|
|
76
63
|
// local ____tmp = ____obj[____index] ${replacementOperator} ${right};
|
|
77
64
|
// ____obj[____index] = ____tmp;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
65
|
+
// return ____tmp
|
|
66
|
+
const [precedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, expression);
|
|
67
|
+
const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression);
|
|
68
|
+
const assignStatement = lua.createAssignmentStatement(accessExpression, tmp);
|
|
69
|
+
return {
|
|
70
|
+
statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
|
|
71
|
+
result: tmp,
|
|
72
|
+
};
|
|
81
73
|
}
|
|
82
|
-
// return ____tmp
|
|
83
|
-
return { statements: [objAndIndexDeclaration, tmpDeclaration, assignStatement], result: tmp };
|
|
84
74
|
}
|
|
85
75
|
else if (isPostfix) {
|
|
86
76
|
// Postfix expressions need to cache original value in temp
|
|
87
77
|
// local ____tmp = ${left};
|
|
88
78
|
// ${left} = ____tmp ${replacementOperator} ${right};
|
|
89
79
|
// return ____tmp
|
|
90
|
-
const tmpIdentifier =
|
|
80
|
+
const tmpIdentifier = context.createTempNameForLuaExpression(left);
|
|
91
81
|
const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left);
|
|
92
|
-
const operatorExpression = (0, binary_expression_1.transformBinaryOperation)(context, tmpIdentifier, right, operator, expression);
|
|
93
|
-
const assignStatements = (0, assignments_1.
|
|
94
|
-
return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier };
|
|
82
|
+
const [precedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, tmpIdentifier, right, rightPrecedingStatements, operator, expression);
|
|
83
|
+
const assignStatements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
|
|
84
|
+
return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier };
|
|
95
85
|
}
|
|
96
86
|
else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) {
|
|
97
87
|
// Simple property/element access expressions need to cache in temp to avoid double-evaluation
|
|
98
88
|
// local ____tmp = ${left} ${replacementOperator} ${right};
|
|
99
89
|
// ${left} = ____tmp;
|
|
100
90
|
// return ____tmp
|
|
101
|
-
const tmpIdentifier =
|
|
102
|
-
const operatorExpression = (0, binary_expression_1.transformBinaryOperation)(context, left, right, operator, expression);
|
|
91
|
+
const tmpIdentifier = context.createTempNameForLuaExpression(left);
|
|
92
|
+
const [precedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, expression);
|
|
103
93
|
const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression);
|
|
104
|
-
const assignStatements = (0, assignments_1.transformAssignment)(context, lhs, tmpIdentifier);
|
|
105
94
|
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
106
95
|
const statements = [
|
|
107
96
|
tmpDeclaration,
|
|
108
|
-
...transformSetterSkippingCompoundAssignment(
|
|
97
|
+
...transformSetterSkippingCompoundAssignment(tmpIdentifier, operator, right, precedingStatements),
|
|
109
98
|
];
|
|
110
99
|
return { statements, result: tmpIdentifier };
|
|
111
100
|
}
|
|
101
|
+
const assignStatements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, tmpIdentifier, precedingStatements);
|
|
112
102
|
return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier };
|
|
113
103
|
}
|
|
114
104
|
else {
|
|
105
|
+
if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
106
|
+
return {
|
|
107
|
+
statements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements),
|
|
108
|
+
result: left,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
115
111
|
// Simple expressions
|
|
116
|
-
// ${left} = ${
|
|
117
|
-
const operatorExpression = (0, binary_expression_1.transformBinaryOperation)(context, left, right, operator, expression);
|
|
118
|
-
const statements = (0, assignments_1.
|
|
112
|
+
// ${left} = ${left} ${operator} ${right}
|
|
113
|
+
const [precedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, expression);
|
|
114
|
+
const statements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, precedingStatements);
|
|
119
115
|
return { statements, result: left };
|
|
120
116
|
}
|
|
121
117
|
}
|
|
@@ -123,40 +119,42 @@ exports.transformCompoundAssignment = transformCompoundAssignment;
|
|
|
123
119
|
function transformCompoundAssignmentExpression(context, expression,
|
|
124
120
|
// TODO: Change type to ts.LeftHandSideExpression?
|
|
125
121
|
lhs, rhs, operator, isPostfix) {
|
|
126
|
-
|
|
122
|
+
const { statements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix);
|
|
123
|
+
context.addPrecedingStatements(statements);
|
|
124
|
+
return result;
|
|
127
125
|
}
|
|
128
126
|
exports.transformCompoundAssignmentExpression = transformCompoundAssignmentExpression;
|
|
129
127
|
function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator) {
|
|
130
128
|
const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (objExpression && indexExpression) {
|
|
129
|
+
let [rightPrecedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
|
|
130
|
+
if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) {
|
|
134
131
|
// Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
|
|
135
132
|
// local __obj, __index = ${objExpression}, ${indexExpression};
|
|
136
133
|
// ____obj[____index] = ____obj[____index] ${replacementOperator} ${right};
|
|
137
|
-
const obj =
|
|
138
|
-
const index =
|
|
139
|
-
const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [
|
|
134
|
+
const obj = context.createTempNameForLuaExpression(left.table);
|
|
135
|
+
const index = context.createTempNameForLuaExpression(left.index);
|
|
136
|
+
const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [left.table, left.index]);
|
|
140
137
|
const accessExpression = lua.createTableIndexExpression(obj, index);
|
|
141
138
|
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
142
139
|
return [
|
|
143
140
|
objAndIndexDeclaration,
|
|
144
|
-
...transformSetterSkippingCompoundAssignment(
|
|
141
|
+
...transformSetterSkippingCompoundAssignment(accessExpression, operator, right, rightPrecedingStatements, node),
|
|
145
142
|
];
|
|
146
143
|
}
|
|
147
|
-
|
|
144
|
+
let operatorExpression;
|
|
145
|
+
[rightPrecedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, node);
|
|
148
146
|
const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
|
|
149
|
-
return [objAndIndexDeclaration, assignStatement];
|
|
147
|
+
return [objAndIndexDeclaration, ...rightPrecedingStatements, assignStatement];
|
|
150
148
|
}
|
|
151
149
|
else {
|
|
152
150
|
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
153
|
-
|
|
154
|
-
return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node);
|
|
151
|
+
return transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements, node);
|
|
155
152
|
}
|
|
156
153
|
// Simple statements
|
|
157
154
|
// ${left} = ${left} ${replacementOperator} ${right}
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
let operatorExpression;
|
|
156
|
+
[rightPrecedingStatements, operatorExpression] = (0, binary_expression_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, node);
|
|
157
|
+
return (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
|
|
160
158
|
}
|
|
161
159
|
}
|
|
162
160
|
exports.transformCompoundAssignmentStatement = transformCompoundAssignmentStatement;
|
|
@@ -165,7 +163,7 @@ function isSetterSkippingCompoundAssignmentOperator(operator) {
|
|
|
165
163
|
operator === ts.SyntaxKind.BarBarToken ||
|
|
166
164
|
operator === ts.SyntaxKind.QuestionQuestionToken);
|
|
167
165
|
}
|
|
168
|
-
function transformSetterSkippingCompoundAssignment(
|
|
166
|
+
function transformSetterSkippingCompoundAssignment(lhs, operator, right, rightPrecedingStatements, node) {
|
|
169
167
|
// These assignments have the form 'if x then y = z', figure out what condition x is first.
|
|
170
168
|
let condition;
|
|
171
169
|
if (operator === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
@@ -182,7 +180,7 @@ function transformSetterSkippingCompoundAssignment(context, lhs, operator, rhs,
|
|
|
182
180
|
}
|
|
183
181
|
// if condition then lhs = rhs end
|
|
184
182
|
return [
|
|
185
|
-
lua.createIfStatement(condition, lua.createBlock([lua.createAssignmentStatement(lhs,
|
|
183
|
+
lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(lhs, right, node)]), undefined, node),
|
|
186
184
|
];
|
|
187
185
|
}
|
|
188
186
|
//# sourceMappingURL=compound.js.map
|
|
@@ -2,5 +2,5 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as lua from "../../../LuaAST";
|
|
3
3
|
import { TransformationContext } from "../../context";
|
|
4
4
|
export declare function isArrayLength(context: TransformationContext, expression: ts.Expression): expression is ts.PropertyAccessExpression | ts.ElementAccessExpression;
|
|
5
|
-
export declare function transformDestructuringAssignment(context: TransformationContext, node: ts.DestructuringAssignment, root: lua.Expression): lua.Statement[];
|
|
6
|
-
export declare function transformAssignmentPattern(context: TransformationContext, node: ts.AssignmentPattern, root: lua.Expression): lua.Statement[];
|
|
5
|
+
export declare function transformDestructuringAssignment(context: TransformationContext, node: ts.DestructuringAssignment, root: lua.Expression, rightHasPrecedingStatements: boolean): lua.Statement[];
|
|
6
|
+
export declare function transformAssignmentPattern(context: TransformationContext, node: ts.AssignmentPattern, root: lua.Expression, rightHasPrecedingStatements: boolean): lua.Statement[];
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.transformAssignmentPattern = exports.transformDestructuringAssignment = exports.isArrayLength = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
|
+
const _1 = require(".");
|
|
5
6
|
const lua = require("../../../LuaAST");
|
|
6
7
|
const utils_1 = require("../../../utils");
|
|
7
8
|
const lualib_1 = require("../../utils/lualib");
|
|
9
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
8
10
|
const typescript_1 = require("../../utils/typescript");
|
|
11
|
+
const expression_list_1 = require("../expression-list");
|
|
9
12
|
const literal_1 = require("../literal");
|
|
10
13
|
const assignments_1 = require("./assignments");
|
|
11
14
|
function isArrayLength(context, expression) {
|
|
@@ -24,32 +27,34 @@ function isArrayLength(context, expression) {
|
|
|
24
27
|
return name === "length";
|
|
25
28
|
}
|
|
26
29
|
exports.isArrayLength = isArrayLength;
|
|
27
|
-
function transformDestructuringAssignment(context, node, root) {
|
|
28
|
-
return transformAssignmentPattern(context, node.left, root);
|
|
30
|
+
function transformDestructuringAssignment(context, node, root, rightHasPrecedingStatements) {
|
|
31
|
+
return transformAssignmentPattern(context, node.left, root, rightHasPrecedingStatements);
|
|
29
32
|
}
|
|
30
33
|
exports.transformDestructuringAssignment = transformDestructuringAssignment;
|
|
31
|
-
function transformAssignmentPattern(context, node, root) {
|
|
34
|
+
function transformAssignmentPattern(context, node, root, rightHasPrecedingStatements) {
|
|
32
35
|
switch (node.kind) {
|
|
33
36
|
case ts.SyntaxKind.ObjectLiteralExpression:
|
|
34
|
-
return transformObjectLiteralAssignmentPattern(context, node, root);
|
|
37
|
+
return transformObjectLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements);
|
|
35
38
|
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
36
|
-
return transformArrayLiteralAssignmentPattern(context, node, root);
|
|
39
|
+
return transformArrayLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements);
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
exports.transformAssignmentPattern = transformAssignmentPattern;
|
|
40
|
-
function transformArrayLiteralAssignmentPattern(context, node, root) {
|
|
43
|
+
function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements) {
|
|
41
44
|
return node.elements.flatMap((element, index) => {
|
|
42
45
|
const indexedRoot = lua.createTableIndexExpression(root, lua.createNumericLiteral(index + 1), element);
|
|
43
46
|
switch (element.kind) {
|
|
44
47
|
case ts.SyntaxKind.ObjectLiteralExpression:
|
|
45
|
-
return transformObjectLiteralAssignmentPattern(context, element, indexedRoot);
|
|
48
|
+
return transformObjectLiteralAssignmentPattern(context, element, indexedRoot, rightHasPrecedingStatements);
|
|
46
49
|
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
47
|
-
return transformArrayLiteralAssignmentPattern(context, element, indexedRoot);
|
|
50
|
+
return transformArrayLiteralAssignmentPattern(context, element, indexedRoot, rightHasPrecedingStatements);
|
|
48
51
|
case ts.SyntaxKind.BinaryExpression:
|
|
49
|
-
const assignedVariable =
|
|
52
|
+
const assignedVariable = context.createTempNameForLuaExpression(indexedRoot);
|
|
50
53
|
const assignedVariableDeclaration = lua.createVariableDeclarationStatement(assignedVariable, indexedRoot);
|
|
51
54
|
const nilCondition = lua.createBinaryExpression(assignedVariable, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
|
|
52
|
-
const defaultAssignmentStatements = (0, assignments_1.transformAssignment)(context, element.left, context.transformExpression(element.right));
|
|
55
|
+
const [defaultPrecedingStatements, defaultAssignmentStatements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.left, context.transformExpression(element.right)));
|
|
56
|
+
// Keep preceding statements inside if block
|
|
57
|
+
defaultAssignmentStatements.unshift(...defaultPrecedingStatements);
|
|
53
58
|
const elseAssignmentStatements = (0, assignments_1.transformAssignment)(context, element.left, assignedVariable);
|
|
54
59
|
const ifBlock = lua.createBlock(defaultAssignmentStatements);
|
|
55
60
|
const elseBlock = lua.createBlock(elseAssignmentStatements);
|
|
@@ -58,14 +63,16 @@ function transformArrayLiteralAssignmentPattern(context, node, root) {
|
|
|
58
63
|
case ts.SyntaxKind.Identifier:
|
|
59
64
|
case ts.SyntaxKind.PropertyAccessExpression:
|
|
60
65
|
case ts.SyntaxKind.ElementAccessExpression:
|
|
61
|
-
|
|
66
|
+
const [precedingStatements, statements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element, indexedRoot, rightHasPrecedingStatements));
|
|
67
|
+
return [...precedingStatements, ...statements]; // Keep preceding statements in order
|
|
62
68
|
case ts.SyntaxKind.SpreadElement:
|
|
63
69
|
if (index !== node.elements.length - 1) {
|
|
64
70
|
// TypeScript error
|
|
65
71
|
return [];
|
|
66
72
|
}
|
|
67
73
|
const restElements = (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySlice, undefined, root, lua.createNumericLiteral(index));
|
|
68
|
-
|
|
74
|
+
const [spreadPrecedingStatements, spreadStatements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.expression, restElements, rightHasPrecedingStatements));
|
|
75
|
+
return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order
|
|
69
76
|
case ts.SyntaxKind.OmittedExpression:
|
|
70
77
|
return [];
|
|
71
78
|
default:
|
|
@@ -74,7 +81,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root) {
|
|
|
74
81
|
}
|
|
75
82
|
});
|
|
76
83
|
}
|
|
77
|
-
function transformObjectLiteralAssignmentPattern(context, node, root) {
|
|
84
|
+
function transformObjectLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements) {
|
|
78
85
|
const result = [];
|
|
79
86
|
for (const property of node.properties) {
|
|
80
87
|
switch (property.kind) {
|
|
@@ -82,7 +89,7 @@ function transformObjectLiteralAssignmentPattern(context, node, root) {
|
|
|
82
89
|
result.push(...transformShorthandPropertyAssignment(context, property, root));
|
|
83
90
|
break;
|
|
84
91
|
case ts.SyntaxKind.PropertyAssignment:
|
|
85
|
-
result.push(...transformPropertyAssignment(context, property, root));
|
|
92
|
+
result.push(...transformPropertyAssignment(context, property, root, rightHasPrecedingStatements));
|
|
86
93
|
break;
|
|
87
94
|
case ts.SyntaxKind.SpreadAssignment:
|
|
88
95
|
result.push(...transformSpreadAssignment(context, property, root, node.properties));
|
|
@@ -115,29 +122,51 @@ function transformShorthandPropertyAssignment(context, node, root) {
|
|
|
115
122
|
}
|
|
116
123
|
return result;
|
|
117
124
|
}
|
|
118
|
-
function transformPropertyAssignment(context, node, root) {
|
|
125
|
+
function transformPropertyAssignment(context, node, root, rightHasPrecedingStatements) {
|
|
119
126
|
const result = [];
|
|
120
127
|
if ((0, typescript_1.isAssignmentPattern)(node.initializer)) {
|
|
121
128
|
const propertyAccessString = (0, literal_1.transformPropertyName)(context, node.name);
|
|
122
129
|
const newRootAccess = lua.createTableIndexExpression(root, propertyAccessString);
|
|
123
130
|
if (ts.isObjectLiteralExpression(node.initializer)) {
|
|
124
|
-
return transformObjectLiteralAssignmentPattern(context, node.initializer, newRootAccess);
|
|
131
|
+
return transformObjectLiteralAssignmentPattern(context, node.initializer, newRootAccess, rightHasPrecedingStatements);
|
|
125
132
|
}
|
|
126
133
|
if (ts.isArrayLiteralExpression(node.initializer)) {
|
|
127
|
-
return transformArrayLiteralAssignmentPattern(context, node.initializer, newRootAccess);
|
|
134
|
+
return transformArrayLiteralAssignmentPattern(context, node.initializer, newRootAccess, rightHasPrecedingStatements);
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
context.pushPrecedingStatements();
|
|
138
|
+
let variableToExtract = (0, literal_1.transformPropertyName)(context, node.name);
|
|
139
|
+
// Must be evaluated before left's preceding statements
|
|
140
|
+
variableToExtract = (0, expression_list_1.moveToPrecedingTemp)(context, variableToExtract, node.name);
|
|
132
141
|
const extractingExpression = lua.createTableIndexExpression(root, variableToExtract);
|
|
133
|
-
|
|
134
|
-
result.push(...destructureAssignmentStatements);
|
|
142
|
+
let destructureAssignmentStatements;
|
|
135
143
|
if (ts.isBinaryExpression(node.initializer)) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
if (ts.isPropertyAccessExpression(node.initializer.left) ||
|
|
145
|
+
ts.isElementAccessExpression(node.initializer.left)) {
|
|
146
|
+
// Access expressions need their table and index expressions cached to preserve execution order
|
|
147
|
+
const left = (0, utils_1.cast)(context.transformExpression(node.initializer.left), lua.isTableIndexExpression);
|
|
148
|
+
const rightExpression = node.initializer.right;
|
|
149
|
+
const [defaultPrecedingStatements, defaultExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rightExpression));
|
|
150
|
+
const tableTemp = context.createTempNameForLuaExpression(left.table);
|
|
151
|
+
const indexTemp = context.createTempNameForLuaExpression(left.index);
|
|
152
|
+
const tempsDeclaration = lua.createVariableDeclarationStatement([tableTemp, indexTemp], [left.table, left.index]);
|
|
153
|
+
// obj[index] = extractingExpression ?? defaultExpression
|
|
154
|
+
const [rightPrecedingStatements, rhs] = (0, _1.transformBinaryOperation)(context, extractingExpression, defaultExpression, defaultPrecedingStatements, ts.SyntaxKind.QuestionQuestionToken, node.initializer);
|
|
155
|
+
const assignStatement = lua.createAssignmentStatement(lua.createTableIndexExpression(tableTemp, indexTemp), rhs);
|
|
156
|
+
destructureAssignmentStatements = [tempsDeclaration, ...rightPrecedingStatements, assignStatement];
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
const assignmentLeftHandSide = context.transformExpression(node.initializer.left);
|
|
160
|
+
const nilCondition = lua.createBinaryExpression(assignmentLeftHandSide, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
|
|
161
|
+
const ifBlock = lua.createBlock((0, assignments_1.transformAssignmentStatement)(context, node.initializer));
|
|
162
|
+
destructureAssignmentStatements = [lua.createIfStatement(nilCondition, ifBlock, undefined, node)];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
destructureAssignmentStatements = (0, assignments_1.transformAssignment)(context, node.initializer, extractingExpression, rightHasPrecedingStatements);
|
|
140
167
|
}
|
|
168
|
+
result.push(...context.popPrecedingStatements());
|
|
169
|
+
result.push(...destructureAssignmentStatements);
|
|
141
170
|
return result;
|
|
142
171
|
}
|
|
143
172
|
function transformSpreadAssignment(context, node, root, properties) {
|
|
@@ -2,8 +2,10 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as lua from "../../../LuaAST";
|
|
3
3
|
import { FunctionVisitor, TransformationContext } from "../../context";
|
|
4
4
|
import { BitOperator } from "./bit";
|
|
5
|
+
declare type ShortCircuitOperator = ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.QuestionQuestionToken;
|
|
5
6
|
declare type SimpleOperator = ts.AdditiveOperatorOrHigher | Exclude<ts.RelationalOperator, ts.SyntaxKind.InstanceOfKeyword | ts.SyntaxKind.InKeyword> | ts.EqualityOperator | ts.LogicalOperator;
|
|
6
|
-
export declare function
|
|
7
|
+
export declare function createShortCircuitBinaryExpressionPrecedingStatements(context: TransformationContext, lhs: lua.Expression, rhs: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression): [lua.Statement[], lua.Expression];
|
|
8
|
+
export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node): [lua.Statement[], lua.Expression];
|
|
7
9
|
export declare const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression>;
|
|
8
10
|
export declare function transformBinaryExpressionStatement(context: TransformationContext, node: ts.ExpressionStatement): lua.Statement[] | lua.Statement | undefined;
|
|
9
11
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformBinaryExpressionStatement = exports.transformBinaryExpression = exports.transformBinaryOperation = void 0;
|
|
3
|
+
exports.transformBinaryExpressionStatement = exports.transformBinaryExpression = exports.transformBinaryOperation = exports.createShortCircuitBinaryExpressionPrecedingStatements = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
6
|
const lua_ast_1 = require("../../utils/lua-ast");
|
|
@@ -11,7 +11,11 @@ const assignments_1 = require("./assignments");
|
|
|
11
11
|
const bit_1 = require("./bit");
|
|
12
12
|
const compound_1 = require("./compound");
|
|
13
13
|
const utils_1 = require("../../../utils");
|
|
14
|
-
const
|
|
14
|
+
const expression_list_1 = require("../expression-list");
|
|
15
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
16
|
+
const isShortCircuitOperator = (value) => value === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
17
|
+
value === ts.SyntaxKind.BarBarToken ||
|
|
18
|
+
value === ts.SyntaxKind.QuestionQuestionToken;
|
|
15
19
|
const simpleOperatorsToLua = {
|
|
16
20
|
[ts.SyntaxKind.AmpersandAmpersandToken]: lua.SyntaxKind.AndOperator,
|
|
17
21
|
[ts.SyntaxKind.BarBarToken]: lua.SyntaxKind.OrOperator,
|
|
@@ -30,13 +34,13 @@ const simpleOperatorsToLua = {
|
|
|
30
34
|
[ts.SyntaxKind.ExclamationEqualsToken]: lua.SyntaxKind.InequalityOperator,
|
|
31
35
|
[ts.SyntaxKind.ExclamationEqualsEqualsToken]: lua.SyntaxKind.InequalityOperator,
|
|
32
36
|
};
|
|
33
|
-
function
|
|
37
|
+
function transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node) {
|
|
34
38
|
if ((0, bit_1.isBitOperator)(operator)) {
|
|
35
39
|
return (0, bit_1.transformBinaryBitOperation)(context, node, left, right, operator);
|
|
36
40
|
}
|
|
37
41
|
if (operator === ts.SyntaxKind.QuestionQuestionToken) {
|
|
38
42
|
(0, utils_1.assert)(ts.isBinaryExpression(node));
|
|
39
|
-
return
|
|
43
|
+
return transformNullishCoalescingOperationNoPrecedingStatements(context, node, left, right);
|
|
40
44
|
}
|
|
41
45
|
let luaOperator = simpleOperatorsToLua[operator];
|
|
42
46
|
// Check if we need to use string concat operator
|
|
@@ -53,6 +57,40 @@ function transformBinaryOperation(context, left, right, operator, node) {
|
|
|
53
57
|
}
|
|
54
58
|
return lua.createBinaryExpression(left, right, luaOperator, node);
|
|
55
59
|
}
|
|
60
|
+
function createShortCircuitBinaryExpressionPrecedingStatements(context, lhs, rhs, rightPrecedingStatements, operator, node) {
|
|
61
|
+
const conditionIdentifier = context.createTempNameForLuaExpression(lhs);
|
|
62
|
+
const assignmentStatement = lua.createVariableDeclarationStatement(conditionIdentifier, lhs, node === null || node === void 0 ? void 0 : node.left);
|
|
63
|
+
let condition;
|
|
64
|
+
switch (operator) {
|
|
65
|
+
case ts.SyntaxKind.BarBarToken:
|
|
66
|
+
condition = lua.createUnaryExpression(lua.cloneIdentifier(conditionIdentifier), lua.SyntaxKind.NotOperator, node);
|
|
67
|
+
break;
|
|
68
|
+
case ts.SyntaxKind.AmpersandAmpersandToken:
|
|
69
|
+
condition = lua.cloneIdentifier(conditionIdentifier);
|
|
70
|
+
break;
|
|
71
|
+
case ts.SyntaxKind.QuestionQuestionToken:
|
|
72
|
+
condition = lua.createBinaryExpression(lua.cloneIdentifier(conditionIdentifier), lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator, node);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const ifStatement = lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(conditionIdentifier, rhs)]), undefined, node === null || node === void 0 ? void 0 : node.left);
|
|
76
|
+
return [[assignmentStatement, ifStatement], conditionIdentifier];
|
|
77
|
+
}
|
|
78
|
+
exports.createShortCircuitBinaryExpressionPrecedingStatements = createShortCircuitBinaryExpressionPrecedingStatements;
|
|
79
|
+
function transformShortCircuitBinaryExpression(context, node, operator) {
|
|
80
|
+
const lhs = context.transformExpression(node.left);
|
|
81
|
+
const [rightPrecedingStatements, rhs] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
|
|
82
|
+
return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node);
|
|
83
|
+
}
|
|
84
|
+
function transformBinaryOperation(context, left, right, rightPrecedingStatements, operator, node) {
|
|
85
|
+
if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) {
|
|
86
|
+
(0, utils_1.assert)(ts.isBinaryExpression(node));
|
|
87
|
+
return createShortCircuitBinaryExpressionPrecedingStatements(context, left, right, rightPrecedingStatements, operator, node);
|
|
88
|
+
}
|
|
89
|
+
return [
|
|
90
|
+
rightPrecedingStatements,
|
|
91
|
+
transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
56
94
|
exports.transformBinaryOperation = transformBinaryOperation;
|
|
57
95
|
const transformBinaryExpression = (node, context) => {
|
|
58
96
|
const operator = node.operatorToken.kind;
|
|
@@ -83,14 +121,25 @@ const transformBinaryExpression = (node, context) => {
|
|
|
83
121
|
return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.InstanceOf, node, lhs, rhs);
|
|
84
122
|
}
|
|
85
123
|
case ts.SyntaxKind.CommaToken: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
124
|
+
const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left));
|
|
125
|
+
const [precedingStatements, result] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
|
|
126
|
+
statements.push(...precedingStatements);
|
|
127
|
+
context.addPrecedingStatements(statements);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
case ts.SyntaxKind.QuestionQuestionToken:
|
|
131
|
+
case ts.SyntaxKind.AmpersandAmpersandToken:
|
|
132
|
+
case ts.SyntaxKind.BarBarToken: {
|
|
133
|
+
const [precedingStatements, result] = transformShortCircuitBinaryExpression(context, node, operator);
|
|
134
|
+
context.addPrecedingStatements(precedingStatements);
|
|
135
|
+
return result;
|
|
90
136
|
}
|
|
91
|
-
default:
|
|
92
|
-
return transformBinaryOperation(context, context.transformExpression(node.left), context.transformExpression(node.right), operator, node);
|
|
93
137
|
}
|
|
138
|
+
let [precedingStatements, [lhs, rhs]] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.transformOrderedExpressions)(context, [node.left, node.right]));
|
|
139
|
+
let result;
|
|
140
|
+
[precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node);
|
|
141
|
+
context.addPrecedingStatements(precedingStatements);
|
|
142
|
+
return result;
|
|
94
143
|
};
|
|
95
144
|
exports.transformBinaryExpression = transformBinaryExpression;
|
|
96
145
|
function transformBinaryExpressionStatement(context, node) {
|
|
@@ -115,21 +164,14 @@ function transformBinaryExpressionStatement(context, node) {
|
|
|
115
164
|
}
|
|
116
165
|
}
|
|
117
166
|
exports.transformBinaryExpressionStatement = transformBinaryExpressionStatement;
|
|
118
|
-
function
|
|
167
|
+
function transformNullishCoalescingOperationNoPrecedingStatements(context, node, transformedLeft, transformedRight) {
|
|
119
168
|
const lhsType = context.checker.getTypeAtLocation(node.left);
|
|
120
169
|
// Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const nilComparison = lua.createBinaryExpression(lua.cloneIdentifier(lhsIdentifier), lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
|
|
127
|
-
// if ____ == nil then return rhs else return ____ end
|
|
128
|
-
const ifStatement = lua.createIfStatement(nilComparison, lua.createBlock([lua.createReturnStatement([transformedRight])]), lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]));
|
|
129
|
-
// (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs)
|
|
130
|
-
return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [
|
|
131
|
-
transformedLeft,
|
|
132
|
-
]);
|
|
170
|
+
if ((0, typescript_1.canBeFalsyWhenNotNull)(context, lhsType)) {
|
|
171
|
+
// reuse logic from case with preceding statements
|
|
172
|
+
const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements(context, transformedLeft, transformedRight, [], ts.SyntaxKind.QuestionQuestionToken, node);
|
|
173
|
+
context.addPrecedingStatements(precedingStatements);
|
|
174
|
+
return result;
|
|
133
175
|
}
|
|
134
176
|
else {
|
|
135
177
|
// lhs or rhs
|
|
@@ -4,7 +4,8 @@ import { FunctionVisitor, TransformationContext } from "../context";
|
|
|
4
4
|
export declare type PropertyCallExpression = ts.CallExpression & {
|
|
5
5
|
expression: ts.PropertyAccessExpression;
|
|
6
6
|
};
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function validateArguments(context: TransformationContext, params: readonly ts.Expression[], signature?: ts.Signature): void;
|
|
8
8
|
export declare function transformArguments(context: TransformationContext, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression): lua.Expression[];
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function transformCallAndArguments(context: TransformationContext, callExpression: ts.Expression, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression): [lua.Expression, lua.Expression[]];
|
|
10
|
+
export declare function transformContextualCallExpression(context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray<ts.Expression>, signature?: ts.Signature): lua.Expression;
|
|
10
11
|
export declare const transformCallExpression: FunctionVisitor<ts.CallExpression>;
|