typescript-to-lua 1.12.1 → 1.13.0
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/transformation/utils/preceding-statements.d.ts +5 -1
- package/dist/transformation/utils/preceding-statements.js +1 -1
- package/dist/transformation/visitors/binary-expression/assignments.js +3 -3
- package/dist/transformation/visitors/binary-expression/compound.d.ts +0 -7
- package/dist/transformation/visitors/binary-expression/compound.js +40 -22
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +5 -5
- package/dist/transformation/visitors/binary-expression/index.d.ts +3 -2
- package/dist/transformation/visitors/binary-expression/index.js +12 -13
- package/dist/transformation/visitors/call.js +2 -2
- package/dist/transformation/visitors/class/index.js +1 -1
- package/dist/transformation/visitors/class/members/fields.js +1 -1
- package/dist/transformation/visitors/conditional.js +10 -10
- package/dist/transformation/visitors/expression-list.js +1 -1
- package/dist/transformation/visitors/function.js +2 -2
- package/dist/transformation/visitors/loops/do-while.js +2 -2
- package/dist/transformation/visitors/loops/for.js +2 -2
- package/dist/transformation/visitors/loops/utils.js +1 -1
- package/dist/transformation/visitors/optional-chaining.js +2 -2
- package/dist/transformation/visitors/sourceFile.js +1 -1
- package/dist/transformation/visitors/switch.js +15 -6
- package/dist/transformation/visitors/typeof.js +1 -1
- package/dist/transformation/visitors/variable-declaration.js +3 -3
- package/dist/transpilation/output-collector.d.ts +1 -1
- package/dist/transpilation/output-collector.js +3 -3
- package/dist/transpilation/resolve.js +19 -10
- package/package.json +1 -1
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import * as lua from "../../LuaAST";
|
|
2
2
|
import { TransformationContext } from "../context";
|
|
3
|
-
export
|
|
3
|
+
export interface WithPrecedingStatements<T extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[]> {
|
|
4
|
+
precedingStatements: lua.Statement[];
|
|
5
|
+
result: T;
|
|
6
|
+
}
|
|
7
|
+
export declare function transformInPrecedingStatementScope<TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[]>(context: TransformationContext, transformer: () => TReturn): WithPrecedingStatements<TReturn>;
|
|
@@ -5,7 +5,7 @@ function transformInPrecedingStatementScope(context, transformer) {
|
|
|
5
5
|
context.pushPrecedingStatements();
|
|
6
6
|
const statementOrStatements = transformer();
|
|
7
7
|
const precedingStatements = context.popPrecedingStatements();
|
|
8
|
-
return
|
|
8
|
+
return { precedingStatements, result: statementOrStatements };
|
|
9
9
|
}
|
|
10
10
|
exports.transformInPrecedingStatementScope = transformInPrecedingStatementScope;
|
|
11
11
|
//# sourceMappingURL=preceding-statements.js.map
|
|
@@ -72,7 +72,7 @@ function transformAssignmentWithRightPrecedingStatements(context, lhs, right, ri
|
|
|
72
72
|
}
|
|
73
73
|
exports.transformAssignmentWithRightPrecedingStatements = transformAssignmentWithRightPrecedingStatements;
|
|
74
74
|
function transformDestructuredAssignmentExpression(context, expression) {
|
|
75
|
-
let
|
|
75
|
+
let { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
|
|
76
76
|
context.addPrecedingStatements(rightPrecedingStatements);
|
|
77
77
|
if ((0, multi_1.isMultiReturnCall)(context, expression.right)) {
|
|
78
78
|
right = (0, lua_ast_1.wrapInTable)(right);
|
|
@@ -96,7 +96,7 @@ function transformAssignmentExpression(context, expression) {
|
|
|
96
96
|
return result;
|
|
97
97
|
}
|
|
98
98
|
if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) {
|
|
99
|
-
const
|
|
99
|
+
const { precedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
|
|
100
100
|
const left = transformAssignmentLeftHandSideExpression(context, expression.left, precedingStatements.length > 0);
|
|
101
101
|
context.addPrecedingStatements(precedingStatements);
|
|
102
102
|
const rightExpr = (0, expression_list_1.moveToPrecedingTemp)(context, right, expression.right);
|
|
@@ -156,7 +156,7 @@ function transformAssignmentStatement(context, expression) {
|
|
|
156
156
|
return statements;
|
|
157
157
|
}
|
|
158
158
|
else {
|
|
159
|
-
const
|
|
159
|
+
const { precedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
|
|
160
160
|
return transformAssignmentWithRightPrecedingStatements(context, expression.left, right, precedingStatements);
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -4,13 +4,6 @@ import { TransformationContext } from "../../context";
|
|
|
4
4
|
type CompoundAssignmentToken = ts.SyntaxKind.BarToken | ts.SyntaxKind.PlusToken | ts.SyntaxKind.CaretToken | ts.SyntaxKind.MinusToken | ts.SyntaxKind.SlashToken | ts.SyntaxKind.PercentToken | ts.SyntaxKind.AsteriskToken | ts.SyntaxKind.AmpersandToken | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.QuestionQuestionToken;
|
|
5
5
|
export declare const isCompoundAssignmentToken: (token: ts.BinaryOperator) => token is ts.CompoundAssignmentOperator;
|
|
6
6
|
export declare const unwrapCompoundAssignmentToken: (token: ts.CompoundAssignmentOperator) => CompoundAssignmentToken;
|
|
7
|
-
export declare function transformCompoundAssignment(context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean): {
|
|
8
|
-
statements: lua.Statement[];
|
|
9
|
-
result: lua.Identifier;
|
|
10
|
-
} | {
|
|
11
|
-
statements: lua.Statement[];
|
|
12
|
-
result: lua.TableIndexExpression;
|
|
13
|
-
};
|
|
14
7
|
export declare function transformCompoundAssignmentExpression(context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean): lua.Expression;
|
|
15
8
|
export declare function transformCompoundAssignmentStatement(context: TransformationContext, node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken): lua.Statement[];
|
|
16
9
|
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = exports.
|
|
3
|
+
exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = 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
7
|
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
8
8
|
const index_1 = require("./index");
|
|
9
9
|
const assignments_1 = require("./assignments");
|
|
10
|
+
const destructuring_assignments_1 = require("./destructuring-assignments");
|
|
11
|
+
const lualib_1 = require("../../utils/lualib");
|
|
10
12
|
function isLuaExpressionWithSideEffect(expression) {
|
|
11
13
|
return !(lua.isLiteral(expression) || lua.isIdentifier(expression));
|
|
12
14
|
}
|
|
@@ -37,8 +39,12 @@ exports.isCompoundAssignmentToken = isCompoundAssignmentToken;
|
|
|
37
39
|
const unwrapCompoundAssignmentToken = (token) => compoundToAssignmentTokens[token];
|
|
38
40
|
exports.unwrapCompoundAssignmentToken = unwrapCompoundAssignmentToken;
|
|
39
41
|
function transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix) {
|
|
42
|
+
if ((0, destructuring_assignments_1.isArrayLength)(context, lhs)) {
|
|
43
|
+
const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter(context, expression, lhs, rhs, operator);
|
|
44
|
+
return { precedingStatements, result: lengthSetterStatement.expression };
|
|
45
|
+
}
|
|
40
46
|
const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
|
|
41
|
-
const
|
|
47
|
+
const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
|
|
42
48
|
if (lua.isTableIndexExpression(left)) {
|
|
43
49
|
// Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
|
|
44
50
|
// local __obj, __index = ${objExpression}, ${indexExpression};
|
|
@@ -52,17 +58,17 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
|
|
|
52
58
|
// ____obj[____index] = ____tmp ${replacementOperator} ${right};
|
|
53
59
|
// return ____tmp
|
|
54
60
|
const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression);
|
|
55
|
-
const
|
|
61
|
+
const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, tmp, right, rightPrecedingStatements, operator, expression);
|
|
56
62
|
const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
|
|
57
63
|
return {
|
|
58
|
-
|
|
64
|
+
precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
|
|
59
65
|
result: tmp,
|
|
60
66
|
};
|
|
61
67
|
}
|
|
62
68
|
else {
|
|
63
69
|
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
64
70
|
return {
|
|
65
|
-
|
|
71
|
+
precedingStatements: [
|
|
66
72
|
objAndIndexDeclaration,
|
|
67
73
|
...transformSetterSkippingCompoundAssignment(accessExpression, operator, right, rightPrecedingStatements),
|
|
68
74
|
],
|
|
@@ -72,11 +78,11 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
|
|
|
72
78
|
// local ____tmp = ____obj[____index] ${replacementOperator} ${right};
|
|
73
79
|
// ____obj[____index] = ____tmp;
|
|
74
80
|
// return ____tmp
|
|
75
|
-
const
|
|
81
|
+
const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, expression);
|
|
76
82
|
const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression);
|
|
77
83
|
const assignStatement = lua.createAssignmentStatement(accessExpression, tmp);
|
|
78
84
|
return {
|
|
79
|
-
|
|
85
|
+
precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
|
|
80
86
|
result: tmp,
|
|
81
87
|
};
|
|
82
88
|
}
|
|
@@ -88,36 +94,42 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
|
|
|
88
94
|
// return ____tmp
|
|
89
95
|
const tmpIdentifier = context.createTempNameForLuaExpression(left);
|
|
90
96
|
const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left);
|
|
91
|
-
const
|
|
97
|
+
const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, tmpIdentifier, right, rightPrecedingStatements, operator, expression);
|
|
92
98
|
const assignStatements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
|
|
93
|
-
return {
|
|
99
|
+
return {
|
|
100
|
+
precedingStatements: [tmpDeclaration, ...precedingStatements, ...assignStatements],
|
|
101
|
+
result: tmpIdentifier,
|
|
102
|
+
};
|
|
94
103
|
}
|
|
95
104
|
else {
|
|
96
105
|
if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
97
106
|
return {
|
|
98
|
-
|
|
107
|
+
precedingStatements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements),
|
|
99
108
|
result: left,
|
|
100
109
|
};
|
|
101
110
|
}
|
|
102
111
|
// Simple expressions
|
|
103
112
|
// ${left} = ${left} ${operator} ${right}
|
|
104
|
-
const
|
|
113
|
+
const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, expression);
|
|
105
114
|
const statements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, precedingStatements);
|
|
106
|
-
return { statements, result: left };
|
|
115
|
+
return { precedingStatements: statements, result: left };
|
|
107
116
|
}
|
|
108
117
|
}
|
|
109
|
-
exports.transformCompoundAssignment = transformCompoundAssignment;
|
|
110
118
|
function transformCompoundAssignmentExpression(context, expression,
|
|
111
119
|
// TODO: Change type to ts.LeftHandSideExpression?
|
|
112
120
|
lhs, rhs, operator, isPostfix) {
|
|
113
|
-
const {
|
|
114
|
-
context.addPrecedingStatements(
|
|
121
|
+
const { precedingStatements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix);
|
|
122
|
+
context.addPrecedingStatements(precedingStatements);
|
|
115
123
|
return result;
|
|
116
124
|
}
|
|
117
125
|
exports.transformCompoundAssignmentExpression = transformCompoundAssignmentExpression;
|
|
118
126
|
function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator) {
|
|
127
|
+
if ((0, destructuring_assignments_1.isArrayLength)(context, lhs)) {
|
|
128
|
+
const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter(context, node, lhs, rhs, operator);
|
|
129
|
+
return [...precedingStatements, lengthSetterStatement];
|
|
130
|
+
}
|
|
119
131
|
const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
|
|
120
|
-
|
|
132
|
+
const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
|
|
121
133
|
if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) {
|
|
122
134
|
// Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
|
|
123
135
|
// local __obj, __index = ${objExpression}, ${indexExpression};
|
|
@@ -132,10 +144,9 @@ function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator)
|
|
|
132
144
|
...transformSetterSkippingCompoundAssignment(accessExpression, operator, right, rightPrecedingStatements, node),
|
|
133
145
|
];
|
|
134
146
|
}
|
|
135
|
-
|
|
136
|
-
[rightPrecedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, node);
|
|
147
|
+
const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, node);
|
|
137
148
|
const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
|
|
138
|
-
return [objAndIndexDeclaration, ...
|
|
149
|
+
return [objAndIndexDeclaration, ...rightPrecedingStatements2, assignStatement];
|
|
139
150
|
}
|
|
140
151
|
else {
|
|
141
152
|
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
|
|
@@ -143,9 +154,8 @@ function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator)
|
|
|
143
154
|
}
|
|
144
155
|
// Simple statements
|
|
145
156
|
// ${left} = ${left} ${replacementOperator} ${right}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
|
|
157
|
+
const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, node);
|
|
158
|
+
return (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements2);
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
exports.transformCompoundAssignmentStatement = transformCompoundAssignmentStatement;
|
|
@@ -174,4 +184,12 @@ function transformSetterSkippingCompoundAssignment(lhs, operator, right, rightPr
|
|
|
174
184
|
lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(lhs, right, node)]), undefined, node),
|
|
175
185
|
];
|
|
176
186
|
}
|
|
187
|
+
function transformCompoundLengthSetter(context, node, lhs, rhs, operator) {
|
|
188
|
+
const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
|
|
189
|
+
const table = context.transformExpression(lhs.expression);
|
|
190
|
+
const lengthExpression = lua.createUnaryExpression(table, lua.SyntaxKind.LengthOperator, lhs);
|
|
191
|
+
const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, lengthExpression, right, rightPrecedingStatements, operator, node);
|
|
192
|
+
const arrayLengthAssignment = lua.createExpressionStatement((0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySetLength, node, table, operatorExpression));
|
|
193
|
+
return { precedingStatements, result: arrayLengthAssignment };
|
|
194
|
+
}
|
|
177
195
|
//# sourceMappingURL=compound.js.map
|
|
@@ -52,7 +52,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
|
|
|
52
52
|
const assignedVariable = context.createTempNameForLuaExpression(indexedRoot);
|
|
53
53
|
const assignedVariableDeclaration = lua.createVariableDeclarationStatement(assignedVariable, indexedRoot);
|
|
54
54
|
const nilCondition = lua.createBinaryExpression(assignedVariable, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
|
|
55
|
-
const
|
|
55
|
+
const { precedingStatements: defaultPrecedingStatements, result: defaultAssignmentStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.left, context.transformExpression(element.right)));
|
|
56
56
|
// Keep preceding statements inside if block
|
|
57
57
|
defaultAssignmentStatements.unshift(...defaultPrecedingStatements);
|
|
58
58
|
const elseAssignmentStatements = (0, assignments_1.transformAssignment)(context, element.left, assignedVariable);
|
|
@@ -63,7 +63,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
|
|
|
63
63
|
case ts.SyntaxKind.Identifier:
|
|
64
64
|
case ts.SyntaxKind.PropertyAccessExpression:
|
|
65
65
|
case ts.SyntaxKind.ElementAccessExpression:
|
|
66
|
-
const
|
|
66
|
+
const { precedingStatements, result: statements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element, indexedRoot, rightHasPrecedingStatements));
|
|
67
67
|
return [...precedingStatements, ...statements]; // Keep preceding statements in order
|
|
68
68
|
case ts.SyntaxKind.SpreadElement:
|
|
69
69
|
if (index !== node.elements.length - 1) {
|
|
@@ -71,7 +71,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
|
|
|
71
71
|
return [];
|
|
72
72
|
}
|
|
73
73
|
const restElements = (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySlice, undefined, root, lua.createNumericLiteral(index));
|
|
74
|
-
const
|
|
74
|
+
const { precedingStatements: spreadPrecedingStatements, result: spreadStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.expression, restElements, rightHasPrecedingStatements));
|
|
75
75
|
return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order
|
|
76
76
|
case ts.SyntaxKind.OmittedExpression:
|
|
77
77
|
return [];
|
|
@@ -146,12 +146,12 @@ function transformPropertyAssignment(context, node, root, rightHasPrecedingState
|
|
|
146
146
|
// Access expressions need their table and index expressions cached to preserve execution order
|
|
147
147
|
const left = (0, utils_1.cast)(context.transformExpression(node.initializer.left), lua.isTableIndexExpression);
|
|
148
148
|
const rightExpression = node.initializer.right;
|
|
149
|
-
const
|
|
149
|
+
const { precedingStatements: defaultPrecedingStatements, result: defaultExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rightExpression));
|
|
150
150
|
const tableTemp = context.createTempNameForLuaExpression(left.table);
|
|
151
151
|
const indexTemp = context.createTempNameForLuaExpression(left.index);
|
|
152
152
|
const tempsDeclaration = lua.createVariableDeclarationStatement([tableTemp, indexTemp], [left.table, left.index]);
|
|
153
153
|
// obj[index] = extractingExpression ?? defaultExpression
|
|
154
|
-
const
|
|
154
|
+
const { precedingStatements: rightPrecedingStatements, result: rhs } = (0, _1.transformBinaryOperation)(context, extractingExpression, defaultExpression, defaultPrecedingStatements, ts.SyntaxKind.QuestionQuestionToken, node.initializer);
|
|
155
155
|
const assignStatement = lua.createAssignmentStatement(lua.createTableIndexExpression(tableTemp, indexTemp), rhs);
|
|
156
156
|
destructureAssignmentStatements = [tempsDeclaration, ...rightPrecedingStatements, assignStatement];
|
|
157
157
|
}
|
|
@@ -2,10 +2,11 @@ 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
|
+
import { WithPrecedingStatements } from "../../utils/preceding-statements";
|
|
5
6
|
type ShortCircuitOperator = ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.QuestionQuestionToken;
|
|
6
7
|
type SimpleOperator = ts.AdditiveOperatorOrHigher | Exclude<ts.RelationalOperator, ts.SyntaxKind.InstanceOfKeyword | ts.SyntaxKind.InKeyword> | ts.EqualityOperator | ts.LogicalOperator;
|
|
7
|
-
export declare function createShortCircuitBinaryExpressionPrecedingStatements(context: TransformationContext, lhs: lua.Expression, rhs: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression):
|
|
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):
|
|
8
|
+
export declare function createShortCircuitBinaryExpressionPrecedingStatements(context: TransformationContext, lhs: lua.Expression, rhs: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression): WithPrecedingStatements<lua.Expression>;
|
|
9
|
+
export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node): WithPrecedingStatements<lua.Expression>;
|
|
9
10
|
export declare const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression>;
|
|
10
11
|
export declare function transformBinaryExpressionStatement(context: TransformationContext, node: ts.ExpressionStatement): lua.Statement[] | lua.Statement | undefined;
|
|
11
12
|
export {};
|
|
@@ -78,23 +78,23 @@ function createShortCircuitBinaryExpressionPrecedingStatements(context, lhs, rhs
|
|
|
78
78
|
break;
|
|
79
79
|
}
|
|
80
80
|
const ifStatement = lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(conditionIdentifier, rhs)]), undefined, node === null || node === void 0 ? void 0 : node.left);
|
|
81
|
-
return [
|
|
81
|
+
return { precedingStatements: [assignmentStatement, ifStatement], result: conditionIdentifier };
|
|
82
82
|
}
|
|
83
83
|
exports.createShortCircuitBinaryExpressionPrecedingStatements = createShortCircuitBinaryExpressionPrecedingStatements;
|
|
84
84
|
function transformShortCircuitBinaryExpression(context, node, operator) {
|
|
85
85
|
const lhs = context.transformExpression(node.left);
|
|
86
|
-
const
|
|
87
|
-
return transformBinaryOperation(context, lhs,
|
|
86
|
+
const { precedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
|
|
87
|
+
return transformBinaryOperation(context, lhs, result, precedingStatements, operator, node);
|
|
88
88
|
}
|
|
89
89
|
function transformBinaryOperation(context, left, right, rightPrecedingStatements, operator, node) {
|
|
90
90
|
if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) {
|
|
91
91
|
(0, utils_1.assert)(ts.isBinaryExpression(node));
|
|
92
92
|
return createShortCircuitBinaryExpressionPrecedingStatements(context, left, right, rightPrecedingStatements, operator, node);
|
|
93
93
|
}
|
|
94
|
-
return
|
|
95
|
-
rightPrecedingStatements,
|
|
96
|
-
transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node),
|
|
97
|
-
|
|
94
|
+
return {
|
|
95
|
+
precedingStatements: rightPrecedingStatements,
|
|
96
|
+
result: transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node),
|
|
97
|
+
};
|
|
98
98
|
}
|
|
99
99
|
exports.transformBinaryOperation = transformBinaryOperation;
|
|
100
100
|
const transformBinaryExpression = (node, context) => {
|
|
@@ -127,7 +127,7 @@ const transformBinaryExpression = (node, context) => {
|
|
|
127
127
|
}
|
|
128
128
|
case ts.SyntaxKind.CommaToken: {
|
|
129
129
|
const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left));
|
|
130
|
-
const
|
|
130
|
+
const { precedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
|
|
131
131
|
statements.push(...precedingStatements);
|
|
132
132
|
context.addPrecedingStatements(statements);
|
|
133
133
|
return result;
|
|
@@ -135,14 +135,13 @@ const transformBinaryExpression = (node, context) => {
|
|
|
135
135
|
case ts.SyntaxKind.QuestionQuestionToken:
|
|
136
136
|
case ts.SyntaxKind.AmpersandAmpersandToken:
|
|
137
137
|
case ts.SyntaxKind.BarBarToken: {
|
|
138
|
-
const
|
|
138
|
+
const { precedingStatements, result } = transformShortCircuitBinaryExpression(context, node, operator);
|
|
139
139
|
context.addPrecedingStatements(precedingStatements);
|
|
140
140
|
return result;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
[precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node);
|
|
143
|
+
const { precedingStatements: orderedExpressionPrecedingStatements, result: [lhs, rhs], } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.transformOrderedExpressions)(context, [node.left, node.right]));
|
|
144
|
+
const { precedingStatements, result } = transformBinaryOperation(context, lhs, rhs, orderedExpressionPrecedingStatements, operator, node);
|
|
146
145
|
context.addPrecedingStatements(precedingStatements);
|
|
147
146
|
return result;
|
|
148
147
|
};
|
|
@@ -174,7 +173,7 @@ function transformNullishCoalescingOperationNoPrecedingStatements(context, node,
|
|
|
174
173
|
// Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'.
|
|
175
174
|
if ((0, typescript_1.canBeFalsyWhenNotNull)(context, lhsType)) {
|
|
176
175
|
// reuse logic from case with preceding statements
|
|
177
|
-
const
|
|
176
|
+
const { precedingStatements, result } = createShortCircuitBinaryExpressionPrecedingStatements(context, transformedLeft, transformedRight, [], ts.SyntaxKind.QuestionQuestionToken, node);
|
|
178
177
|
context.addPrecedingStatements(precedingStatements);
|
|
179
178
|
return result;
|
|
180
179
|
}
|
|
@@ -55,7 +55,7 @@ function transformCallWithArguments(context, callExpression, transformedArgument
|
|
|
55
55
|
return [call, transformedArguments];
|
|
56
56
|
}
|
|
57
57
|
function transformCallAndArguments(context, callExpression, params, signature, callContext) {
|
|
58
|
-
const
|
|
58
|
+
const { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, params, signature, callContext));
|
|
59
59
|
return transformCallWithArguments(context, callExpression, transformedArguments, argPrecedingStatements);
|
|
60
60
|
}
|
|
61
61
|
exports.transformCallAndArguments = transformCallAndArguments;
|
|
@@ -82,7 +82,7 @@ function transformContextualCallExpression(context, node, args, signature) {
|
|
|
82
82
|
return (0, optional_chaining_1.transformOptionalChain)(context, node);
|
|
83
83
|
}
|
|
84
84
|
const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag;
|
|
85
|
-
let
|
|
85
|
+
let { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, args, signature));
|
|
86
86
|
if (ts.isPropertyAccessExpression(left) &&
|
|
87
87
|
ts.isIdentifier(left.name) &&
|
|
88
88
|
(0, safe_names_1.isValidLuaIdentifier)(left.name.text, context.options) &&
|
|
@@ -20,7 +20,7 @@ const transformClassDeclaration = (declaration, context) => {
|
|
|
20
20
|
// If declaration is a default export, transform to export variable assignment instead
|
|
21
21
|
if ((0, export_1.hasDefaultExportModifier)(declaration)) {
|
|
22
22
|
// Class declaration including assignment to ____exports.default are in preceding statements
|
|
23
|
-
const
|
|
23
|
+
const { precedingStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
24
24
|
transformClassAsExpression(declaration, context);
|
|
25
25
|
return [];
|
|
26
26
|
});
|
|
@@ -22,7 +22,7 @@ exports.createPropertyDecoratingExpression = createPropertyDecoratingExpression;
|
|
|
22
22
|
function transformClassInstanceFields(context, instanceFields) {
|
|
23
23
|
const statements = [];
|
|
24
24
|
for (const f of instanceFields) {
|
|
25
|
-
const
|
|
25
|
+
const { precedingStatements, result: statement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
26
26
|
// Get identifier
|
|
27
27
|
const fieldName = (0, literal_1.transformPropertyName)(context, f.name);
|
|
28
28
|
const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
|
|
@@ -10,12 +10,12 @@ const typescript_1 = require("../utils/typescript");
|
|
|
10
10
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
11
11
|
function transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse) {
|
|
12
12
|
const tempVar = context.createTempNameForNode(expression.condition);
|
|
13
|
-
const trueStatements = whenTrue
|
|
14
|
-
const falseStatements = whenFalse
|
|
13
|
+
const trueStatements = whenTrue.precedingStatements.concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue.result, expression.whenTrue));
|
|
14
|
+
const falseStatements = whenFalse.precedingStatements.concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse.result, expression.whenFalse));
|
|
15
15
|
context.addPrecedingStatements([
|
|
16
16
|
lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition),
|
|
17
|
-
...condition
|
|
18
|
-
lua.createIfStatement(condition
|
|
17
|
+
...condition.precedingStatements,
|
|
18
|
+
lua.createIfStatement(condition.result, lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression),
|
|
19
19
|
]);
|
|
20
20
|
return lua.cloneIdentifier(tempVar);
|
|
21
21
|
}
|
|
@@ -25,15 +25,15 @@ const transformConditionalExpression = (expression, context) => {
|
|
|
25
25
|
const condition = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.condition));
|
|
26
26
|
const whenTrue = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenTrue));
|
|
27
27
|
const whenFalse = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenFalse));
|
|
28
|
-
if (whenTrue
|
|
29
|
-
whenFalse
|
|
28
|
+
if (whenTrue.precedingStatements.length > 0 ||
|
|
29
|
+
whenFalse.precedingStatements.length > 0 ||
|
|
30
30
|
(0, typescript_1.canBeFalsy)(context, context.checker.getTypeAtLocation(expression.whenTrue))) {
|
|
31
31
|
return transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse);
|
|
32
32
|
}
|
|
33
33
|
// condition and v1 or v2
|
|
34
|
-
context.addPrecedingStatements(condition
|
|
35
|
-
const conditionAnd = lua.createBinaryExpression(condition
|
|
36
|
-
return lua.createBinaryExpression(conditionAnd, whenFalse
|
|
34
|
+
context.addPrecedingStatements(condition.precedingStatements);
|
|
35
|
+
const conditionAnd = lua.createBinaryExpression(condition.result, whenTrue.result, lua.SyntaxKind.AndOperator);
|
|
36
|
+
return lua.createBinaryExpression(conditionAnd, whenFalse.result, lua.SyntaxKind.OrOperator, expression);
|
|
37
37
|
};
|
|
38
38
|
exports.transformConditionalExpression = transformConditionalExpression;
|
|
39
39
|
function transformIfStatement(statement, context) {
|
|
@@ -47,7 +47,7 @@ function transformIfStatement(statement, context) {
|
|
|
47
47
|
if (statement.elseStatement) {
|
|
48
48
|
if (ts.isIfStatement(statement.elseStatement)) {
|
|
49
49
|
const tsElseStatement = statement.elseStatement;
|
|
50
|
-
const
|
|
50
|
+
const { precedingStatements, result: elseStatement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformIfStatement(tsElseStatement, context));
|
|
51
51
|
// If else-if condition generates preceding statements, we can't use elseif, we have to break it down:
|
|
52
52
|
// if conditionA then
|
|
53
53
|
// ...
|
|
@@ -34,7 +34,7 @@ function transformExpressions(context, expressions) {
|
|
|
34
34
|
const transformedExpressions = [];
|
|
35
35
|
let lastPrecedingStatementsIndex = -1;
|
|
36
36
|
for (let i = 0; i < expressions.length; ++i) {
|
|
37
|
-
const
|
|
37
|
+
const { precedingStatements: expressionPrecedingStatements, result: expression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expressions[i]));
|
|
38
38
|
transformedExpressions.push(expression);
|
|
39
39
|
if (expressionPrecedingStatements.length > 0) {
|
|
40
40
|
lastPrecedingStatementsIndex = i;
|
|
@@ -69,7 +69,7 @@ function isFunctionTypeWithProperties(context, functionType) {
|
|
|
69
69
|
exports.isFunctionTypeWithProperties = isFunctionTypeWithProperties;
|
|
70
70
|
function transformFunctionBodyContent(context, body) {
|
|
71
71
|
if (!ts.isBlock(body)) {
|
|
72
|
-
const
|
|
72
|
+
const { precedingStatements, result: returnStatement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, return_1.transformExpressionBodyToReturnStatement)(context, body));
|
|
73
73
|
return [...precedingStatements, returnStatement];
|
|
74
74
|
}
|
|
75
75
|
const bodyStatements = (0, scope_1.performHoisting)(context, context.transformStatements(body.statements));
|
|
@@ -90,7 +90,7 @@ function transformFunctionBodyHeader(context, bodyScope, parameters, spreadIdent
|
|
|
90
90
|
}
|
|
91
91
|
// Binding pattern
|
|
92
92
|
const name = declaration.name;
|
|
93
|
-
const
|
|
93
|
+
const { precedingStatements, result: bindings } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, name, identifier));
|
|
94
94
|
bindingPatternDeclarations.push(...precedingStatements, ...bindings);
|
|
95
95
|
}
|
|
96
96
|
else if (declaration.initializer !== undefined) {
|
|
@@ -9,7 +9,7 @@ const transformWhileStatement = (statement, context) => {
|
|
|
9
9
|
// Check if we need to add diagnostic about Lua truthiness
|
|
10
10
|
(0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
|
|
11
11
|
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
12
|
-
let
|
|
12
|
+
let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
13
13
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
14
14
|
//
|
|
15
15
|
// while true do
|
|
@@ -31,7 +31,7 @@ const transformDoStatement = (statement, context) => {
|
|
|
31
31
|
// Check if we need to add diagnostic about Lua truthiness
|
|
32
32
|
(0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
|
|
33
33
|
const body = lua.createDoStatement((0, utils_1.transformLoopBody)(context, statement));
|
|
34
|
-
let
|
|
34
|
+
let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
|
|
35
35
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
36
36
|
//
|
|
37
37
|
// repeat
|
|
@@ -21,9 +21,9 @@ const transformForStatement = (statement, context) => {
|
|
|
21
21
|
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
22
22
|
let condition;
|
|
23
23
|
if (statement.condition) {
|
|
24
|
-
let conditionPrecedingStatements;
|
|
25
24
|
const tsCondition = statement.condition;
|
|
26
|
-
|
|
25
|
+
const { precedingStatements: conditionPrecedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsCondition));
|
|
26
|
+
condition = result;
|
|
27
27
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
28
28
|
//
|
|
29
29
|
// while true do
|
|
@@ -40,7 +40,7 @@ function transformForInitializer(context, initializer, block) {
|
|
|
40
40
|
// Declaration of new variable
|
|
41
41
|
const binding = getVariableDeclarationBinding(context, initializer);
|
|
42
42
|
if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) {
|
|
43
|
-
const
|
|
43
|
+
const { precedingStatements, result: bindings } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, binding, valueVariable));
|
|
44
44
|
block.statements.unshift(...precedingStatements, ...bindings);
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
@@ -99,7 +99,7 @@ function transformOptionalChainWithCapture(context, tsNode, thisValueCapture, is
|
|
|
99
99
|
// transform right expression first to check if thisValue capture is needed
|
|
100
100
|
// capture and return thisValue if requested from outside
|
|
101
101
|
let returnThisValue;
|
|
102
|
-
const
|
|
102
|
+
const { precedingStatements: rightPrecedingStatements, result: rightExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
103
103
|
if (!thisValueCapture) {
|
|
104
104
|
return context.transformExpression(tsRightExpression);
|
|
105
105
|
}
|
|
@@ -113,7 +113,7 @@ function transformOptionalChainWithCapture(context, tsNode, thisValueCapture, is
|
|
|
113
113
|
let capturedThisValue;
|
|
114
114
|
const optionalContinuationData = getOptionalContinuationData(tsTemp);
|
|
115
115
|
const rightContextualCall = optionalContinuationData === null || optionalContinuationData === void 0 ? void 0 : optionalContinuationData.contextualCall;
|
|
116
|
-
const
|
|
116
|
+
const { precedingStatements: leftPrecedingStatements, result: leftExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
117
117
|
let result;
|
|
118
118
|
if (rightContextualCall) {
|
|
119
119
|
({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture(context, tsLeftExpression, leftThisValueTemp));
|
|
@@ -15,7 +15,7 @@ const transformSourceFileNode = (node, context) => {
|
|
|
15
15
|
const [statement] = node.statements;
|
|
16
16
|
if (statement) {
|
|
17
17
|
(0, utils_1.assert)(ts.isExpressionStatement(statement));
|
|
18
|
-
const
|
|
18
|
+
const { precedingStatements, result: expression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
19
19
|
statements.push(...precedingStatements);
|
|
20
20
|
statements.push(lua.createReturnStatement([expression]));
|
|
21
21
|
}
|
|
@@ -25,18 +25,21 @@ const createOrExpression = (context, left, right, rightPrecedingStatements) => {
|
|
|
25
25
|
return (0, binary_expression_1.createShortCircuitBinaryExpressionPrecedingStatements)(context, left, right, rightPrecedingStatements, ts.SyntaxKind.BarBarToken);
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
precedingStatements: rightPrecedingStatements,
|
|
30
|
+
result: lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator),
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
};
|
|
31
34
|
const coalesceCondition = (condition, conditionPrecedingStatements, switchVariable, expression, context) => {
|
|
32
|
-
const
|
|
35
|
+
const { precedingStatements, result: transformedExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
|
|
33
36
|
// Coalesce skipped statements
|
|
34
37
|
const comparison = lua.createBinaryExpression(switchVariable, transformedExpression, lua.SyntaxKind.EqualityOperator);
|
|
35
38
|
if (condition) {
|
|
36
39
|
return createOrExpression(context, condition, comparison, precedingStatements);
|
|
37
40
|
}
|
|
38
41
|
// Next condition
|
|
39
|
-
return [
|
|
42
|
+
return { precedingStatements: [...conditionPrecedingStatements, ...precedingStatements], result: comparison };
|
|
40
43
|
};
|
|
41
44
|
const transformSwitchStatement = (statement, context) => {
|
|
42
45
|
const scope = context.pushScope(scope_1.ScopeType.Switch);
|
|
@@ -77,7 +80,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
77
80
|
}
|
|
78
81
|
// Compute the condition for the if statement
|
|
79
82
|
if (!ts.isDefaultClause(clause)) {
|
|
80
|
-
|
|
83
|
+
const { precedingStatements, result } = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
|
|
84
|
+
conditionPrecedingStatements = precedingStatements;
|
|
85
|
+
condition = result;
|
|
81
86
|
// Skip empty clauses unless final clause (i.e side-effects)
|
|
82
87
|
if (i !== clauses.length - 1 && clause.statements.length === 0)
|
|
83
88
|
continue;
|
|
@@ -86,7 +91,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
86
91
|
statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition));
|
|
87
92
|
}
|
|
88
93
|
else {
|
|
89
|
-
|
|
94
|
+
const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
95
|
+
conditionPrecedingStatements = precedingStatements;
|
|
96
|
+
condition = result;
|
|
90
97
|
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
91
98
|
}
|
|
92
99
|
isInitialCondition = false;
|
|
@@ -104,7 +111,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
104
111
|
if (i === clauses.length - 1) {
|
|
105
112
|
// Evaluate the final condition that we may be skipping
|
|
106
113
|
if (condition) {
|
|
107
|
-
|
|
114
|
+
const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
115
|
+
conditionPrecedingStatements = precedingStatements;
|
|
116
|
+
condition = result;
|
|
108
117
|
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
109
118
|
}
|
|
110
119
|
continue;
|
|
@@ -43,7 +43,7 @@ function transformTypeOfBinaryExpression(context, node) {
|
|
|
43
43
|
}
|
|
44
44
|
const innerExpression = context.transformExpression(typeOfExpression.expression);
|
|
45
45
|
const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression);
|
|
46
|
-
const
|
|
46
|
+
const { precedingStatements, result } = (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, [], operator, node);
|
|
47
47
|
context.addPrecedingStatements(precedingStatements);
|
|
48
48
|
return result;
|
|
49
49
|
}
|
|
@@ -61,7 +61,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
|
|
|
61
61
|
const variableName = (0, identifier_1.transformIdentifier)(context, element.name);
|
|
62
62
|
// The field to extract
|
|
63
63
|
const elementName = (_a = element.propertyName) !== null && _a !== void 0 ? _a : element.name;
|
|
64
|
-
const
|
|
64
|
+
const { precedingStatements, result: propertyName } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, literal_1.transformPropertyName)(context, elementName));
|
|
65
65
|
result.push(...precedingStatements); // Keep property's preceding statements in order
|
|
66
66
|
let expression;
|
|
67
67
|
if (element.dotDotDotToken) {
|
|
@@ -101,7 +101,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
|
|
|
101
101
|
if (element.initializer) {
|
|
102
102
|
const identifier = (0, export_1.addExportToIdentifier)(context, variableName);
|
|
103
103
|
const tsInitializer = element.initializer;
|
|
104
|
-
const
|
|
104
|
+
const { precedingStatements: initializerPrecedingStatements, result: initializer } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsInitializer));
|
|
105
105
|
result.push(lua.createIfStatement(lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([
|
|
106
106
|
...initializerPrecedingStatements,
|
|
107
107
|
lua.createAssignmentStatement(identifier, initializer),
|
|
@@ -124,7 +124,7 @@ function transformBindingVariableDeclaration(context, bindingPattern, initialize
|
|
|
124
124
|
if ((0, multi_1.isMultiReturnCall)(context, initializer)) {
|
|
125
125
|
expression = (0, lua_ast_1.wrapInTable)(expression);
|
|
126
126
|
}
|
|
127
|
-
const
|
|
127
|
+
const { precedingStatements: moveStatements, result: movedExpr } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.moveToPrecedingTemp)(context, expression, initializer));
|
|
128
128
|
statements.push(...moveStatements);
|
|
129
129
|
table = movedExpr;
|
|
130
130
|
}
|
|
@@ -7,7 +7,7 @@ export interface TranspiledFile {
|
|
|
7
7
|
declaration?: string;
|
|
8
8
|
declarationMap?: string;
|
|
9
9
|
}
|
|
10
|
-
export declare function createEmitOutputCollector(): {
|
|
10
|
+
export declare function createEmitOutputCollector(luaExtension?: string): {
|
|
11
11
|
writeFile: ts.WriteFileCallback;
|
|
12
12
|
files: TranspiledFile[];
|
|
13
13
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createEmitOutputCollector = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
function createEmitOutputCollector() {
|
|
5
|
+
function createEmitOutputCollector(luaExtension = ".lua") {
|
|
6
6
|
const files = [];
|
|
7
7
|
const writeFile = (fileName, data, _bom, _onError, sourceFiles = []) => {
|
|
8
8
|
let file = files.find(f => (0, utils_1.intersection)(f.sourceFiles, sourceFiles).length > 0);
|
|
@@ -13,10 +13,10 @@ function createEmitOutputCollector() {
|
|
|
13
13
|
else {
|
|
14
14
|
file.sourceFiles = (0, utils_1.union)(file.sourceFiles, sourceFiles);
|
|
15
15
|
}
|
|
16
|
-
if (fileName.endsWith(
|
|
16
|
+
if (fileName.endsWith(luaExtension)) {
|
|
17
17
|
file.lua = data;
|
|
18
18
|
}
|
|
19
|
-
else if (fileName.endsWith(
|
|
19
|
+
else if (fileName.endsWith(`${luaExtension}.map`)) {
|
|
20
20
|
file.luaSourceMap = data;
|
|
21
21
|
}
|
|
22
22
|
else if (fileName.endsWith(".js")) {
|
|
@@ -15,6 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({
|
|
|
15
15
|
enforceExtension: true,
|
|
16
16
|
fileSystem: { ...new resolve.CachedInputFileSystem(fs) },
|
|
17
17
|
useSyncFileSystemCalls: true,
|
|
18
|
+
conditionNames: ["require", "node", "tstl", "default"],
|
|
18
19
|
symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection)
|
|
19
20
|
});
|
|
20
21
|
class ResolutionContext {
|
|
@@ -40,8 +41,8 @@ class ResolutionContext {
|
|
|
40
41
|
// Remove @NoResolution prefix if not building in library mode
|
|
41
42
|
if (!isBuildModeLibrary(this.program)) {
|
|
42
43
|
const path = required.requirePath.replace("@NoResolution:", "");
|
|
43
|
-
replaceRequireInCode(file, required, path);
|
|
44
|
-
replaceRequireInSourceMap(file, required, path);
|
|
44
|
+
replaceRequireInCode(file, required, path, this.options.extension);
|
|
45
|
+
replaceRequireInSourceMap(file, required, path, this.options.extension);
|
|
45
46
|
}
|
|
46
47
|
// Skip
|
|
47
48
|
continue;
|
|
@@ -72,8 +73,8 @@ class ResolutionContext {
|
|
|
72
73
|
// Figure out resolved require path and dependency output path
|
|
73
74
|
if (shouldRewriteRequires(dependencyPath, this.program)) {
|
|
74
75
|
const resolvedRequire = (0, transpiler_1.getEmitPathRelativeToOutDir)(dependencyPath, this.program);
|
|
75
|
-
replaceRequireInCode(file, required, resolvedRequire);
|
|
76
|
-
replaceRequireInSourceMap(file, required, resolvedRequire);
|
|
76
|
+
replaceRequireInCode(file, required, resolvedRequire, this.options.extension);
|
|
77
|
+
replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension);
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
processDependency(dependencyPath) {
|
|
@@ -96,8 +97,8 @@ class ResolutionContext {
|
|
|
96
97
|
}
|
|
97
98
|
couldNotResolveImport(required, file) {
|
|
98
99
|
const fallbackRequire = fallbackResolve(required, (0, transpiler_1.getSourceDir)(this.program), path.dirname(file.fileName));
|
|
99
|
-
replaceRequireInCode(file, required, fallbackRequire);
|
|
100
|
-
replaceRequireInSourceMap(file, required, fallbackRequire);
|
|
100
|
+
replaceRequireInCode(file, required, fallbackRequire, this.options.extension);
|
|
101
|
+
replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension);
|
|
101
102
|
this.diagnostics.push((0, diagnostics_1.couldNotResolveRequire)(required.requirePath, path.relative((0, transpiler_1.getProjectRoot)(this.program), file.fileName)));
|
|
102
103
|
}
|
|
103
104
|
resolveDependencyPath(requiringFile, dependency) {
|
|
@@ -263,19 +264,27 @@ function shouldIncludeDependency(resolvedDependency, program) {
|
|
|
263
264
|
function isBuildModeLibrary(program) {
|
|
264
265
|
return program.getCompilerOptions().buildMode === CompilerOptions_1.BuildMode.Library;
|
|
265
266
|
}
|
|
266
|
-
function replaceRequireInCode(file, originalRequire, newRequire) {
|
|
267
|
-
const requirePath = (
|
|
267
|
+
function replaceRequireInCode(file, originalRequire, newRequire, extension) {
|
|
268
|
+
const requirePath = requirePathForFile(newRequire, extension);
|
|
268
269
|
file.code = file.code =
|
|
269
270
|
file.code.substring(0, originalRequire.from) +
|
|
270
271
|
`require("${requirePath}")` +
|
|
271
272
|
file.code.substring(originalRequire.to + 1);
|
|
272
273
|
}
|
|
273
|
-
function replaceRequireInSourceMap(file, originalRequire, newRequire) {
|
|
274
|
-
const requirePath = (
|
|
274
|
+
function replaceRequireInSourceMap(file, originalRequire, newRequire, extension) {
|
|
275
|
+
const requirePath = requirePathForFile(newRequire, extension);
|
|
275
276
|
if (file.sourceMapNode) {
|
|
276
277
|
replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire.requirePath}"`, `"${requirePath}"`);
|
|
277
278
|
}
|
|
278
279
|
}
|
|
280
|
+
function requirePathForFile(filePath, extension = ".lua") {
|
|
281
|
+
if (filePath.endsWith(extension)) {
|
|
282
|
+
return (0, utils_1.formatPathToLuaPath)(filePath.substring(0, filePath.length - extension.length));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
return (0, utils_1.formatPathToLuaPath)(filePath);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
279
288
|
function replaceInSourceMap(node, parent, require, resolvedRequire) {
|
|
280
289
|
if ((!node.children || node.children.length === 0) && node.toString() === require) {
|
|
281
290
|
parent.children = [new source_map_1.SourceNode(node.line, node.column, node.source, [resolvedRequire])];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typescript-to-lua",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
|
|
5
5
|
"repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
|
|
6
6
|
"homepage": "https://typescripttolua.github.io/",
|