typescript-to-lua 1.1.1 → 1.2.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/CHANGELOG.md +16 -0
- package/dist/LuaAST.d.ts +1 -0
- package/dist/LuaAST.js +10 -2
- package/dist/LuaLib.d.ts +3 -3
- package/dist/LuaLib.js +4 -4
- package/dist/LuaPrinter.d.ts +11 -4
- package/dist/LuaPrinter.js +54 -11
- 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 +14 -10
- package/dist/lualib/CloneDescriptor.lua +8 -8
- 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/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 +18 -22
- 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 +603 -555
- package/dist/transformation/builtins/array.js +1 -2
- package/dist/transformation/builtins/function.js +1 -2
- package/dist/transformation/builtins/index.d.ts +1 -1
- package/dist/transformation/builtins/index.js +37 -4
- 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 +6 -0
- package/dist/transformation/utils/diagnostics.js +3 -1
- package/dist/transformation/utils/lua-ast.d.ts +0 -1
- package/dist/transformation/utils/lua-ast.js +13 -22
- package/dist/transformation/utils/preceding-statements.d.ts +3 -0
- package/dist/transformation/utils/preceding-statements.js +11 -0
- package/dist/transformation/utils/scope.d.ts +1 -0
- package/dist/transformation/utils/scope.js +8 -1
- package/dist/transformation/utils/typescript/index.d.ts +1 -0
- package/dist/transformation/utils/typescript/index.js +16 -1
- 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 +64 -20
- package/dist/transformation/visitors/call.d.ts +3 -2
- package/dist/transformation/visitors/call.js +109 -122
- package/dist/transformation/visitors/class/index.js +4 -7
- package/dist/transformation/visitors/class/new.js +4 -6
- package/dist/transformation/visitors/conditional.js +28 -14
- package/dist/transformation/visitors/delete.js +4 -0
- package/dist/transformation/visitors/expression-list.d.ts +7 -0
- package/dist/transformation/visitors/expression-list.js +120 -0
- package/dist/transformation/visitors/function.js +6 -8
- package/dist/transformation/visitors/identifier.js +4 -0
- package/dist/transformation/visitors/literal.js +69 -16
- package/dist/transformation/visitors/loops/do-while.js +34 -8
- 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 +13 -2
- package/dist/transformation/visitors/modules/export.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/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 +21 -7
- package/dist/transformation/visitors/void.js +4 -7
- package/dist/transpilation/transformers.js +4 -1
- package/dist/transpilation/utils.js +2 -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
|
@@ -10,6 +10,7 @@ const export_1 = require("../utils/export");
|
|
|
10
10
|
const function_context_1 = require("../utils/function-context");
|
|
11
11
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
12
12
|
const lualib_1 = require("../utils/lualib");
|
|
13
|
+
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
13
14
|
const scope_1 = require("../utils/scope");
|
|
14
15
|
const async_await_1 = require("./async-await");
|
|
15
16
|
const identifier_1 = require("./identifier");
|
|
@@ -34,8 +35,8 @@ function isRestParameterReferenced(identifier, scope) {
|
|
|
34
35
|
}
|
|
35
36
|
function transformFunctionBodyContent(context, body) {
|
|
36
37
|
if (!ts.isBlock(body)) {
|
|
37
|
-
const returnStatement = (0, return_1.transformExpressionBodyToReturnStatement)(context, body);
|
|
38
|
-
return [returnStatement];
|
|
38
|
+
const [precedingStatements, returnStatement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, return_1.transformExpressionBodyToReturnStatement)(context, body));
|
|
39
|
+
return [...precedingStatements, returnStatement];
|
|
39
40
|
}
|
|
40
41
|
const bodyStatements = (0, scope_1.performHoisting)(context, context.transformStatements(body.statements));
|
|
41
42
|
return bodyStatements;
|
|
@@ -163,14 +164,11 @@ function transformFunctionLikeDeclaration(node, context) {
|
|
|
163
164
|
if (symbol) {
|
|
164
165
|
// TODO: Not using symbol ids because of https://github.com/microsoft/TypeScript/issues/37131
|
|
165
166
|
const isReferenced = [...functionScope.referencedSymbols].some(([, nodes]) => nodes.some(n => { var _a; return ((_a = context.checker.getSymbolAtLocation(n)) === null || _a === void 0 ? void 0 : _a.valueDeclaration) === symbol.valueDeclaration; }));
|
|
166
|
-
// Only
|
|
167
|
+
// Only handle if the name is actually referenced inside the function
|
|
167
168
|
if (isReferenced) {
|
|
168
169
|
const nameIdentifier = (0, identifier_1.transformIdentifier)(context, node.name);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// with var-arg optimization because the IIFE is just wrapping another function which will already push
|
|
172
|
-
// another scope.
|
|
173
|
-
return (0, lua_ast_1.createImmediatelyInvokedFunctionExpression)([lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], lua.cloneIdentifier(nameIdentifier));
|
|
170
|
+
context.addPrecedingStatements(lua.createVariableDeclarationStatement(nameIdentifier, functionExpression));
|
|
171
|
+
return lua.cloneIdentifier(nameIdentifier);
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
}
|
|
@@ -16,7 +16,11 @@ const operators_1 = require("./language-extensions/operators");
|
|
|
16
16
|
const range_1 = require("./language-extensions/range");
|
|
17
17
|
const table_1 = require("./language-extensions/table");
|
|
18
18
|
const vararg_1 = require("./language-extensions/vararg");
|
|
19
|
+
const optional_chaining_1 = require("./optional-chaining");
|
|
19
20
|
function transformIdentifier(context, identifier) {
|
|
21
|
+
if ((0, optional_chaining_1.isOptionalContinuation)(identifier)) {
|
|
22
|
+
return lua.createIdentifier(identifier.text);
|
|
23
|
+
}
|
|
20
24
|
if ((0, multi_1.isMultiFunctionNode)(context, identifier)) {
|
|
21
25
|
context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionUse)(identifier));
|
|
22
26
|
return lua.createAnonymousIdentifier(identifier);
|
|
@@ -11,7 +11,7 @@ const safe_names_1 = require("../utils/safe-names");
|
|
|
11
11
|
const symbols_1 = require("../utils/symbols");
|
|
12
12
|
const typescript_1 = require("../utils/typescript");
|
|
13
13
|
const function_1 = require("./function");
|
|
14
|
-
const
|
|
14
|
+
const expression_list_1 = require("./expression-list");
|
|
15
15
|
const multi_1 = require("./language-extensions/multi");
|
|
16
16
|
// TODO: Move to object-literal.ts?
|
|
17
17
|
function transformPropertyName(context, node) {
|
|
@@ -61,13 +61,27 @@ const transformObjectLiteralExpression = (expression, context) => {
|
|
|
61
61
|
context.diagnostics.push(...violations.map(e => (0, diagnostics_1.invalidMultiFunctionUse)(e)));
|
|
62
62
|
return lua.createNilLiteral(expression);
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
64
|
+
const properties = [];
|
|
65
|
+
const initializers = [];
|
|
66
|
+
const keyPrecedingStatements = [];
|
|
67
|
+
const valuePrecedingStatements = [];
|
|
68
|
+
let lastPrecedingStatementsIndex = -1;
|
|
69
|
+
for (let i = 0; i < expression.properties.length; ++i) {
|
|
70
|
+
const element = expression.properties[i];
|
|
71
|
+
// Transform key and cache preceding statements
|
|
72
|
+
context.pushPrecedingStatements();
|
|
67
73
|
const name = element.name ? transformPropertyName(context, element.name) : undefined;
|
|
74
|
+
let precedingStatements = context.popPrecedingStatements();
|
|
75
|
+
keyPrecedingStatements.push(precedingStatements);
|
|
76
|
+
if (precedingStatements.length > 0) {
|
|
77
|
+
lastPrecedingStatementsIndex = i;
|
|
78
|
+
}
|
|
79
|
+
// Transform value and cache preceding statements
|
|
80
|
+
context.pushPrecedingStatements();
|
|
68
81
|
if (ts.isPropertyAssignment(element)) {
|
|
69
82
|
const expression = context.transformExpression(element.initializer);
|
|
70
83
|
properties.push(lua.createTableFieldExpression(expression, name, element));
|
|
84
|
+
initializers.push(element.initializer);
|
|
71
85
|
}
|
|
72
86
|
else if (ts.isShorthandPropertyAssignment(element)) {
|
|
73
87
|
const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element);
|
|
@@ -76,19 +90,14 @@ const transformObjectLiteralExpression = (expression, context) => {
|
|
|
76
90
|
}
|
|
77
91
|
const identifier = createShorthandIdentifier(context, valueSymbol, element.name);
|
|
78
92
|
properties.push(lua.createTableFieldExpression(identifier, name, element));
|
|
93
|
+
initializers.push(element);
|
|
79
94
|
}
|
|
80
95
|
else if (ts.isMethodDeclaration(element)) {
|
|
81
96
|
const expression = (0, function_1.transformFunctionLikeDeclaration)(element, context);
|
|
82
97
|
properties.push(lua.createTableFieldExpression(expression, name, element));
|
|
98
|
+
initializers.push(element);
|
|
83
99
|
}
|
|
84
100
|
else if (ts.isSpreadAssignment(element)) {
|
|
85
|
-
// Create a table for preceding properties to preserve property order
|
|
86
|
-
// { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2})
|
|
87
|
-
if (properties.length > 0) {
|
|
88
|
-
const tableExpression = lua.createTableExpression(properties, expression);
|
|
89
|
-
tableExpressions.push(tableExpression);
|
|
90
|
-
properties = [];
|
|
91
|
-
}
|
|
92
101
|
const type = context.checker.getTypeAtLocation(element.expression);
|
|
93
102
|
let tableExpression;
|
|
94
103
|
if ((0, typescript_1.isArrayType)(context, type)) {
|
|
@@ -97,7 +106,8 @@ const transformObjectLiteralExpression = (expression, context) => {
|
|
|
97
106
|
else {
|
|
98
107
|
tableExpression = context.transformExpression(element.expression);
|
|
99
108
|
}
|
|
100
|
-
|
|
109
|
+
properties.push(tableExpression);
|
|
110
|
+
initializers.push(element.expression);
|
|
101
111
|
}
|
|
102
112
|
else if (ts.isAccessor(element)) {
|
|
103
113
|
context.diagnostics.push((0, diagnostics_1.unsupportedAccessorInObjectLiteral)(element));
|
|
@@ -105,13 +115,56 @@ const transformObjectLiteralExpression = (expression, context) => {
|
|
|
105
115
|
else {
|
|
106
116
|
(0, utils_1.assertNever)(element);
|
|
107
117
|
}
|
|
118
|
+
precedingStatements = context.popPrecedingStatements();
|
|
119
|
+
valuePrecedingStatements.push(precedingStatements);
|
|
120
|
+
if (precedingStatements.length > 0) {
|
|
121
|
+
lastPrecedingStatementsIndex = i;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Expressions referenced before others that produced preceding statements need to be cached in temps
|
|
125
|
+
if (lastPrecedingStatementsIndex >= 0) {
|
|
126
|
+
for (let i = 0; i < properties.length; ++i) {
|
|
127
|
+
const property = properties[i];
|
|
128
|
+
// Bubble up key's preceding statements
|
|
129
|
+
context.addPrecedingStatements(keyPrecedingStatements[i]);
|
|
130
|
+
// Cache computed property name in temp if before the last expression that generated preceding statements
|
|
131
|
+
if (i <= lastPrecedingStatementsIndex && lua.isTableFieldExpression(property) && property.key) {
|
|
132
|
+
property.key = (0, expression_list_1.moveToPrecedingTemp)(context, property.key, expression.properties[i].name);
|
|
133
|
+
}
|
|
134
|
+
// Bubble up value's preceding statements
|
|
135
|
+
context.addPrecedingStatements(valuePrecedingStatements[i]);
|
|
136
|
+
// Cache property value in temp if before the last expression that generated preceding statements
|
|
137
|
+
if (i < lastPrecedingStatementsIndex) {
|
|
138
|
+
if (lua.isTableFieldExpression(property)) {
|
|
139
|
+
property.value = (0, expression_list_1.moveToPrecedingTemp)(context, property.value, initializers[i]);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
properties[i] = (0, expression_list_1.moveToPrecedingTemp)(context, property, initializers[i]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Sort into field expressions and tables to pass into __TS__ObjectAssign
|
|
148
|
+
let fields = [];
|
|
149
|
+
const tableExpressions = [];
|
|
150
|
+
for (const property of properties) {
|
|
151
|
+
if (lua.isTableFieldExpression(property)) {
|
|
152
|
+
fields.push(property);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
if (fields.length > 0) {
|
|
156
|
+
tableExpressions.push(lua.createTableExpression(fields));
|
|
157
|
+
}
|
|
158
|
+
tableExpressions.push(property);
|
|
159
|
+
fields = [];
|
|
160
|
+
}
|
|
108
161
|
}
|
|
109
162
|
if (tableExpressions.length === 0) {
|
|
110
|
-
return lua.createTableExpression(
|
|
163
|
+
return lua.createTableExpression(fields, expression);
|
|
111
164
|
}
|
|
112
165
|
else {
|
|
113
|
-
if (
|
|
114
|
-
const tableExpression = lua.createTableExpression(
|
|
166
|
+
if (fields.length > 0) {
|
|
167
|
+
const tableExpression = lua.createTableExpression(fields, expression);
|
|
115
168
|
tableExpressions.push(tableExpression);
|
|
116
169
|
}
|
|
117
170
|
if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) {
|
|
@@ -122,7 +175,7 @@ const transformObjectLiteralExpression = (expression, context) => {
|
|
|
122
175
|
};
|
|
123
176
|
const transformArrayLiteralExpression = (expression, context) => {
|
|
124
177
|
const filteredElements = expression.elements.map(e => ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e);
|
|
125
|
-
const values = (0,
|
|
178
|
+
const values = (0, expression_list_1.transformExpressionList)(context, filteredElements).map(e => lua.createTableFieldExpression(e));
|
|
126
179
|
return lua.createTableExpression(values, expression);
|
|
127
180
|
};
|
|
128
181
|
exports.literalVisitors = {
|
|
@@ -2,19 +2,45 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.transformDoStatement = exports.transformWhileStatement = void 0;
|
|
4
4
|
const lua = require("../../../LuaAST");
|
|
5
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
5
6
|
const utils_1 = require("./utils");
|
|
6
|
-
const transformWhileStatement = (statement, context) =>
|
|
7
|
+
const transformWhileStatement = (statement, context) => {
|
|
8
|
+
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
9
|
+
let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
10
|
+
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
11
|
+
//
|
|
12
|
+
// while true do
|
|
13
|
+
// condition's preceding statements
|
|
14
|
+
// if not condition then
|
|
15
|
+
// break
|
|
16
|
+
// end
|
|
17
|
+
// ...
|
|
18
|
+
// end
|
|
19
|
+
if (conditionPrecedingStatements.length > 0) {
|
|
20
|
+
conditionPrecedingStatements.push(lua.createIfStatement((0, utils_1.invertCondition)(condition), lua.createBlock([lua.createBreakStatement()]), undefined, statement.expression));
|
|
21
|
+
body.unshift(...conditionPrecedingStatements);
|
|
22
|
+
condition = lua.createBooleanLiteral(true);
|
|
23
|
+
}
|
|
24
|
+
return lua.createWhileStatement(lua.createBlock(body), condition, statement);
|
|
25
|
+
};
|
|
7
26
|
exports.transformWhileStatement = transformWhileStatement;
|
|
8
27
|
const transformDoStatement = (statement, context) => {
|
|
9
28
|
const body = lua.createDoStatement((0, utils_1.transformLoopBody)(context, statement));
|
|
10
|
-
let condition = context.transformExpression(statement.expression);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
|
|
30
|
+
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
31
|
+
//
|
|
32
|
+
// repeat
|
|
33
|
+
// ...
|
|
34
|
+
// condition's preceding statements
|
|
35
|
+
// if condition then
|
|
36
|
+
// break
|
|
37
|
+
// end
|
|
38
|
+
// end
|
|
39
|
+
if (conditionPrecedingStatements.length > 0) {
|
|
40
|
+
conditionPrecedingStatements.push(lua.createIfStatement(condition, lua.createBlock([lua.createBreakStatement()]), undefined, statement.expression));
|
|
41
|
+
condition = lua.createBooleanLiteral(false);
|
|
16
42
|
}
|
|
17
|
-
return lua.createRepeatStatement(lua.createBlock([body]), condition, statement);
|
|
43
|
+
return lua.createRepeatStatement(lua.createBlock([body, ...conditionPrecedingStatements]), condition, statement);
|
|
18
44
|
};
|
|
19
45
|
exports.transformDoStatement = transformDoStatement;
|
|
20
46
|
//# sourceMappingURL=do-while.js.map
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.transformForStatement = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
6
7
|
const variable_declaration_1 = require("../variable-declaration");
|
|
7
8
|
const utils_1 = require("./utils");
|
|
8
9
|
const transformForStatement = (statement, context) => {
|
|
@@ -17,16 +18,35 @@ const transformForStatement = (statement, context) => {
|
|
|
17
18
|
result.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.initializer)));
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
const condition = statement.condition
|
|
21
|
-
? context.transformExpression(statement.condition)
|
|
22
|
-
: lua.createBooleanLiteral(true);
|
|
23
|
-
// Add body
|
|
24
21
|
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
22
|
+
let condition;
|
|
23
|
+
if (statement.condition) {
|
|
24
|
+
let conditionPrecedingStatements;
|
|
25
|
+
const tsCondition = statement.condition;
|
|
26
|
+
[conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsCondition));
|
|
27
|
+
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
28
|
+
//
|
|
29
|
+
// while true do
|
|
30
|
+
// condition's preceding statements
|
|
31
|
+
// if not condition then
|
|
32
|
+
// break
|
|
33
|
+
// end
|
|
34
|
+
// ...
|
|
35
|
+
// end
|
|
36
|
+
if (conditionPrecedingStatements.length > 0) {
|
|
37
|
+
conditionPrecedingStatements.push(lua.createIfStatement((0, utils_1.invertCondition)(condition), lua.createBlock([lua.createBreakStatement()]), undefined, statement.condition));
|
|
38
|
+
body.unshift(...conditionPrecedingStatements);
|
|
39
|
+
condition = lua.createBooleanLiteral(true);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
condition = lua.createBooleanLiteral(true);
|
|
44
|
+
}
|
|
25
45
|
if (statement.incrementor) {
|
|
26
46
|
body.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.incrementor)));
|
|
27
47
|
}
|
|
28
48
|
// while (condition) do ... end
|
|
29
|
-
result.push(lua.createWhileStatement(lua.createBlock(body), condition));
|
|
49
|
+
result.push(lua.createWhileStatement(lua.createBlock(body), condition, statement));
|
|
30
50
|
return lua.createDoStatement(result, statement);
|
|
31
51
|
};
|
|
32
52
|
exports.transformForStatement = transformForStatement;
|
|
@@ -4,3 +4,4 @@ import { TransformationContext } from "../../context";
|
|
|
4
4
|
export declare function transformLoopBody(context: TransformationContext, loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement): lua.Statement[];
|
|
5
5
|
export declare function getVariableDeclarationBinding(context: TransformationContext, node: ts.VariableDeclarationList): ts.BindingName;
|
|
6
6
|
export declare function transformForInitializer(context: TransformationContext, initializer: ts.ForInitializer, block: lua.Block): lua.Identifier;
|
|
7
|
+
export declare function invertCondition(expression: lua.Expression): lua.Expression;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformForInitializer = exports.getVariableDeclarationBinding = exports.transformLoopBody = void 0;
|
|
3
|
+
exports.invertCondition = exports.transformForInitializer = exports.getVariableDeclarationBinding = exports.transformLoopBody = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
6
|
const scope_1 = require("../../utils/scope");
|
|
@@ -48,10 +48,21 @@ function transformForInitializer(context, initializer, block) {
|
|
|
48
48
|
else {
|
|
49
49
|
// Assignment to existing variable(s)
|
|
50
50
|
block.statements.unshift(...((0, typescript_1.isAssignmentPattern)(initializer)
|
|
51
|
-
? (0, destructuring_assignments_1.transformAssignmentPattern)(context, initializer, valueVariable)
|
|
51
|
+
? (0, destructuring_assignments_1.transformAssignmentPattern)(context, initializer, valueVariable, false)
|
|
52
52
|
: (0, assignments_1.transformAssignment)(context, initializer, valueVariable)));
|
|
53
53
|
}
|
|
54
54
|
return valueVariable;
|
|
55
55
|
}
|
|
56
56
|
exports.transformForInitializer = transformForInitializer;
|
|
57
|
+
function invertCondition(expression) {
|
|
58
|
+
if (lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator) {
|
|
59
|
+
return expression.operand;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const notExpression = lua.createUnaryExpression(expression, lua.SyntaxKind.NotOperator);
|
|
63
|
+
lua.setNodePosition(notExpression, lua.getOriginalPos(expression));
|
|
64
|
+
return notExpression;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.invertCondition = invertCondition;
|
|
57
68
|
//# sourceMappingURL=utils.js.map
|
|
@@ -79,7 +79,7 @@ function transformExportSpecifier(context, node) {
|
|
|
79
79
|
}
|
|
80
80
|
function transformExportSpecifiersFrom(context, statement, moduleSpecifier, exportSpecifiers) {
|
|
81
81
|
// First transpile as import clause
|
|
82
|
-
const importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(exportSpecifiers.map(s => ts.factory.createImportSpecifier(s.propertyName, s.name))));
|
|
82
|
+
const importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(exportSpecifiers.map(s => ts.factory.createImportSpecifier(statement.isTypeOnly, s.propertyName, s.name))));
|
|
83
83
|
const importDeclaration = ts.factory.createImportDeclaration(statement.decorators, statement.modifiers, importClause, moduleSpecifier);
|
|
84
84
|
// Wrap in block to prevent imports from hoisting out of `do` statement
|
|
85
85
|
const [block] = (0, block_1.transformScopeBlock)(context, ts.factory.createBlock([importDeclaration]), scope_1.ScopeType.Block);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import * as lua from "../../LuaAST";
|
|
3
|
+
import { TransformationContext } from "../context";
|
|
4
|
+
export interface ExpressionWithThisValue {
|
|
5
|
+
expression: lua.Expression;
|
|
6
|
+
thisValue?: lua.Expression;
|
|
7
|
+
}
|
|
8
|
+
export declare function captureThisValue(context: TransformationContext, expression: lua.Expression, thisValueCapture: lua.Identifier, tsOriginal: ts.Node): lua.Expression;
|
|
9
|
+
export interface OptionalContinuation {
|
|
10
|
+
contextualCall?: lua.CallExpression;
|
|
11
|
+
}
|
|
12
|
+
export declare function isOptionalContinuation(node: ts.Node): boolean;
|
|
13
|
+
export declare function getOptionalContinuationData(identifier: ts.Identifier): OptionalContinuation | undefined;
|
|
14
|
+
export declare function transformOptionalChain(context: TransformationContext, node: ts.OptionalChain): lua.Expression;
|
|
15
|
+
export declare function transformOptionalChainWithCapture(context: TransformationContext, node: ts.OptionalChain, thisValueCapture: lua.Identifier | undefined, isDelete?: ts.DeleteExpression): ExpressionWithThisValue;
|
|
16
|
+
export declare function transformOptionalDeleteExpression(context: TransformationContext, node: ts.DeleteExpression, innerExpression: ts.OptionalChain): lua.BooleanLiteral;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformOptionalDeleteExpression = exports.transformOptionalChainWithCapture = exports.transformOptionalChain = exports.getOptionalContinuationData = exports.isOptionalContinuation = exports.captureThisValue = void 0;
|
|
4
|
+
const ts = require("typescript");
|
|
5
|
+
const lua = require("../../LuaAST");
|
|
6
|
+
const context_1 = require("../context");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
9
|
+
const access_1 = require("./access");
|
|
10
|
+
const expression_list_1 = require("./expression-list");
|
|
11
|
+
function skipNonNullChains(chain) {
|
|
12
|
+
while (ts.isNonNullChain(chain)) {
|
|
13
|
+
chain = chain.expression;
|
|
14
|
+
}
|
|
15
|
+
return chain;
|
|
16
|
+
}
|
|
17
|
+
function flattenChain(chain) {
|
|
18
|
+
chain = skipNonNullChains(chain);
|
|
19
|
+
const links = [chain];
|
|
20
|
+
while (!chain.questionDotToken && !ts.isTaggedTemplateExpression(chain)) {
|
|
21
|
+
const nextLink = chain.expression;
|
|
22
|
+
(0, utils_1.assert)(ts.isOptionalChain(nextLink));
|
|
23
|
+
chain = skipNonNullChains(nextLink);
|
|
24
|
+
links.unshift(chain);
|
|
25
|
+
}
|
|
26
|
+
return { expression: chain.expression, chain: links };
|
|
27
|
+
}
|
|
28
|
+
function transformExpressionWithThisValueCapture(context, node, thisValueCapture) {
|
|
29
|
+
if (ts.isParenthesizedExpression(node)) {
|
|
30
|
+
return transformExpressionWithThisValueCapture(context, node.expression, thisValueCapture);
|
|
31
|
+
}
|
|
32
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
33
|
+
return (0, access_1.transformPropertyAccessExpressionWithCapture)(context, node, thisValueCapture);
|
|
34
|
+
}
|
|
35
|
+
if (ts.isElementAccessExpression(node)) {
|
|
36
|
+
return (0, access_1.transformElementAccessExpressionWithCapture)(context, node, thisValueCapture);
|
|
37
|
+
}
|
|
38
|
+
return { expression: context.transformExpression(node) };
|
|
39
|
+
}
|
|
40
|
+
// returns thisValueCapture exactly if a temp variable was used.
|
|
41
|
+
function captureThisValue(context, expression, thisValueCapture, tsOriginal) {
|
|
42
|
+
if (!(0, expression_list_1.shouldMoveToTemp)(context, expression, tsOriginal) && !isOptionalContinuation(tsOriginal)) {
|
|
43
|
+
return expression;
|
|
44
|
+
}
|
|
45
|
+
const tempAssignment = lua.createAssignmentStatement(thisValueCapture, expression, tsOriginal);
|
|
46
|
+
context.addPrecedingStatements(tempAssignment);
|
|
47
|
+
return thisValueCapture;
|
|
48
|
+
}
|
|
49
|
+
exports.captureThisValue = captureThisValue;
|
|
50
|
+
const optionalContinuations = new WeakMap();
|
|
51
|
+
// should be translated verbatim to lua
|
|
52
|
+
function createOptionalContinuationIdentifier(text, tsOriginal) {
|
|
53
|
+
const identifier = ts.factory.createIdentifier(text);
|
|
54
|
+
ts.setOriginalNode(identifier, tsOriginal);
|
|
55
|
+
optionalContinuations.set(identifier, {});
|
|
56
|
+
return identifier;
|
|
57
|
+
}
|
|
58
|
+
function isOptionalContinuation(node) {
|
|
59
|
+
return ts.isIdentifier(node) && optionalContinuations.has(node);
|
|
60
|
+
}
|
|
61
|
+
exports.isOptionalContinuation = isOptionalContinuation;
|
|
62
|
+
function getOptionalContinuationData(identifier) {
|
|
63
|
+
return optionalContinuations.get(identifier);
|
|
64
|
+
}
|
|
65
|
+
exports.getOptionalContinuationData = getOptionalContinuationData;
|
|
66
|
+
function transformOptionalChain(context, node) {
|
|
67
|
+
return transformOptionalChainWithCapture(context, node, undefined).expression;
|
|
68
|
+
}
|
|
69
|
+
exports.transformOptionalChain = transformOptionalChain;
|
|
70
|
+
function transformOptionalChainWithCapture(context, node, thisValueCapture, isDelete) {
|
|
71
|
+
var _a;
|
|
72
|
+
const luaTemp = context.createTempNameForNode(node);
|
|
73
|
+
const { expression: tsLeftExpression, chain } = flattenChain(node);
|
|
74
|
+
// build temp.b.c.d
|
|
75
|
+
const tsTemp = createOptionalContinuationIdentifier(luaTemp.text, tsLeftExpression);
|
|
76
|
+
let tsRightExpression = tsTemp;
|
|
77
|
+
for (const link of chain) {
|
|
78
|
+
if (ts.isPropertyAccessExpression(link)) {
|
|
79
|
+
tsRightExpression = ts.factory.createPropertyAccessExpression(tsRightExpression, link.name);
|
|
80
|
+
}
|
|
81
|
+
else if (ts.isElementAccessExpression(link)) {
|
|
82
|
+
tsRightExpression = ts.factory.createElementAccessExpression(tsRightExpression, link.argumentExpression);
|
|
83
|
+
}
|
|
84
|
+
else if (ts.isCallExpression(link)) {
|
|
85
|
+
tsRightExpression = ts.factory.createCallExpression(tsRightExpression, undefined, link.arguments);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
(0, utils_1.assertNever)(link);
|
|
89
|
+
}
|
|
90
|
+
ts.setOriginalNode(tsRightExpression, link);
|
|
91
|
+
}
|
|
92
|
+
if (isDelete) {
|
|
93
|
+
tsRightExpression = ts.factory.createDeleteExpression(tsRightExpression);
|
|
94
|
+
ts.setOriginalNode(tsRightExpression, isDelete);
|
|
95
|
+
}
|
|
96
|
+
// transform right expression first to check if thisValue capture is needed
|
|
97
|
+
// capture and return thisValue if requested from outside
|
|
98
|
+
let returnThisValue;
|
|
99
|
+
const [rightPrecedingStatements, rightAssignment] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
100
|
+
let result;
|
|
101
|
+
if (thisValueCapture) {
|
|
102
|
+
({ expression: result, thisValue: returnThisValue } = transformExpressionWithThisValueCapture(context, tsRightExpression, thisValueCapture));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
result = context.transformExpression(tsRightExpression);
|
|
106
|
+
}
|
|
107
|
+
return lua.createAssignmentStatement(luaTemp, result);
|
|
108
|
+
});
|
|
109
|
+
// transform left expression, handle thisValue if needed by rightExpression
|
|
110
|
+
const thisValueCaptureName = context.createTempName("this");
|
|
111
|
+
const leftThisValueTemp = lua.createIdentifier(thisValueCaptureName, undefined, context_1.tempSymbolId);
|
|
112
|
+
let capturedThisValue;
|
|
113
|
+
const rightContextualCall = (_a = getOptionalContinuationData(tsTemp)) === null || _a === void 0 ? void 0 : _a.contextualCall;
|
|
114
|
+
const [leftPrecedingStatements, leftExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
115
|
+
let result;
|
|
116
|
+
if (rightContextualCall) {
|
|
117
|
+
({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture(context, tsLeftExpression, leftThisValueTemp));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
result = context.transformExpression(tsLeftExpression);
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
});
|
|
124
|
+
// handle context
|
|
125
|
+
if (rightContextualCall) {
|
|
126
|
+
if (capturedThisValue) {
|
|
127
|
+
rightContextualCall.params[0] = capturedThisValue;
|
|
128
|
+
if (capturedThisValue === leftThisValueTemp) {
|
|
129
|
+
context.addPrecedingStatements(lua.createVariableDeclarationStatement(leftThisValueTemp));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
if (context.isStrict) {
|
|
134
|
+
rightContextualCall.params[0] = lua.createNilLiteral();
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const identifier = lua.createIdentifier("_G");
|
|
138
|
+
if (rightPrecedingStatements.length === 0) {
|
|
139
|
+
rightContextualCall.params[0] = identifier;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const tempContext = context.createTempNameForLuaExpression(identifier);
|
|
143
|
+
rightPrecedingStatements.unshift(lua.createVariableDeclarationStatement(tempContext, identifier));
|
|
144
|
+
rightContextualCall.params[0] = tempContext;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// <left preceding statements>
|
|
150
|
+
// local temp = <left>
|
|
151
|
+
// if temp ~= nil then
|
|
152
|
+
// <right preceding statements>
|
|
153
|
+
// temp = temp.b.c.d
|
|
154
|
+
// end
|
|
155
|
+
// return temp
|
|
156
|
+
context.addPrecedingStatements([
|
|
157
|
+
...leftPrecedingStatements,
|
|
158
|
+
lua.createVariableDeclarationStatement(luaTemp, leftExpression),
|
|
159
|
+
lua.createIfStatement(lua.createBinaryExpression(luaTemp, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), lua.createBlock([...rightPrecedingStatements, rightAssignment])),
|
|
160
|
+
]);
|
|
161
|
+
return {
|
|
162
|
+
expression: luaTemp,
|
|
163
|
+
thisValue: returnThisValue,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
exports.transformOptionalChainWithCapture = transformOptionalChainWithCapture;
|
|
167
|
+
function transformOptionalDeleteExpression(context, node, innerExpression) {
|
|
168
|
+
transformOptionalChainWithCapture(context, innerExpression, undefined, node);
|
|
169
|
+
return lua.createBooleanLiteral(true, node);
|
|
170
|
+
}
|
|
171
|
+
exports.transformOptionalDeleteExpression = transformOptionalDeleteExpression;
|
|
172
|
+
//# sourceMappingURL=optional-chaining.js.map
|
|
@@ -6,6 +6,7 @@ const lua = require("../../LuaAST");
|
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
7
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
8
8
|
const lualib_1 = require("../utils/lualib");
|
|
9
|
+
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
9
10
|
const scope_1 = require("../utils/scope");
|
|
10
11
|
const typescript_1 = require("../utils/typescript");
|
|
11
12
|
const transformSourceFileNode = (node, context) => {
|
|
@@ -15,7 +16,9 @@ const transformSourceFileNode = (node, context) => {
|
|
|
15
16
|
const [statement] = node.statements;
|
|
16
17
|
if (statement) {
|
|
17
18
|
(0, utils_1.assert)(ts.isExpressionStatement(statement));
|
|
18
|
-
|
|
19
|
+
const [precedingStatements, expression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
20
|
+
statements.push(...precedingStatements);
|
|
21
|
+
statements.push(lua.createReturnStatement([expression]));
|
|
19
22
|
}
|
|
20
23
|
else {
|
|
21
24
|
const errorCall = lua.createCallExpression(lua.createIdentifier("error"), [
|
|
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.transformSwitchStatement = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
|
+
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
6
7
|
const scope_1 = require("../utils/scope");
|
|
8
|
+
const binary_expression_1 = require("./binary-expression");
|
|
7
9
|
const containsBreakOrReturn = (nodes) => {
|
|
8
10
|
for (const s of nodes) {
|
|
9
11
|
if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) {
|
|
@@ -18,13 +20,23 @@ const containsBreakOrReturn = (nodes) => {
|
|
|
18
20
|
}
|
|
19
21
|
return false;
|
|
20
22
|
};
|
|
21
|
-
const
|
|
23
|
+
const createOrExpression = (context, left, right, rightPrecedingStatements) => {
|
|
24
|
+
if (rightPrecedingStatements.length > 0) {
|
|
25
|
+
return (0, binary_expression_1.createShortCircuitBinaryExpressionPrecedingStatements)(context, left, right, rightPrecedingStatements, ts.SyntaxKind.BarBarToken);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)];
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const coalesceCondition = (condition, conditionPrecedingStatements, switchVariable, expression, context) => {
|
|
32
|
+
const [precedingStatements, transformedExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
|
|
22
33
|
// Coalesce skipped statements
|
|
34
|
+
const comparison = lua.createBinaryExpression(switchVariable, transformedExpression, lua.SyntaxKind.EqualityOperator);
|
|
23
35
|
if (condition) {
|
|
24
|
-
return
|
|
36
|
+
return createOrExpression(context, condition, comparison, precedingStatements);
|
|
25
37
|
}
|
|
26
38
|
// Next condition
|
|
27
|
-
return
|
|
39
|
+
return [[...conditionPrecedingStatements, ...precedingStatements], comparison];
|
|
28
40
|
};
|
|
29
41
|
const transformSwitchStatement = (statement, context) => {
|
|
30
42
|
const scope = (0, scope_1.pushScope)(context, scope_1.ScopeType.Switch);
|
|
@@ -53,6 +65,7 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
53
65
|
let defaultTransformed = false;
|
|
54
66
|
let isInitialCondition = true;
|
|
55
67
|
let condition = undefined;
|
|
68
|
+
let conditionPrecedingStatements = [];
|
|
56
69
|
for (let i = 0; i < clauses.length; i++) {
|
|
57
70
|
const clause = clauses[i];
|
|
58
71
|
const previousClause = clauses[i - 1];
|
|
@@ -64,29 +77,35 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
64
77
|
}
|
|
65
78
|
// Compute the condition for the if statement
|
|
66
79
|
if (!ts.isDefaultClause(clause)) {
|
|
67
|
-
condition = coalesceCondition(condition, switchVariable, clause.expression, context);
|
|
80
|
+
[conditionPrecedingStatements, condition] = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
|
|
68
81
|
// Skip empty clauses unless final clause (i.e side-effects)
|
|
69
82
|
if (i !== clauses.length - 1 && clause.statements.length === 0)
|
|
70
83
|
continue;
|
|
71
84
|
// Declare or assign condition variable
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
if (isInitialCondition) {
|
|
86
|
+
statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition));
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
[conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
90
|
+
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
91
|
+
}
|
|
75
92
|
isInitialCondition = false;
|
|
76
93
|
}
|
|
77
94
|
else {
|
|
78
95
|
// If the default is proceeded by empty clauses and will be emitted we may need to initialize the condition
|
|
79
96
|
if (isInitialCondition) {
|
|
80
|
-
statements.push(lua.createVariableDeclarationStatement(conditionVariable, condition !== null && condition !== void 0 ? condition : lua.createBooleanLiteral(false)));
|
|
97
|
+
statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition !== null && condition !== void 0 ? condition : lua.createBooleanLiteral(false)));
|
|
81
98
|
// Clear condition ot ensure it is not evaluated twice
|
|
82
99
|
condition = undefined;
|
|
100
|
+
conditionPrecedingStatements = [];
|
|
83
101
|
isInitialCondition = false;
|
|
84
102
|
}
|
|
85
103
|
// Allow default to fallthrough to final default clause
|
|
86
104
|
if (i === clauses.length - 1) {
|
|
87
105
|
// Evaluate the final condition that we may be skipping
|
|
88
106
|
if (condition) {
|
|
89
|
-
|
|
107
|
+
[conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
108
|
+
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
90
109
|
}
|
|
91
110
|
continue;
|
|
92
111
|
}
|
|
@@ -106,6 +125,7 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
106
125
|
statements.push(lua.createIfStatement(conditionVariable, lua.createBlock(clauseStatements)));
|
|
107
126
|
// Clear condition for next clause
|
|
108
127
|
condition = undefined;
|
|
128
|
+
conditionPrecedingStatements = [];
|
|
109
129
|
}
|
|
110
130
|
// If no conditions above match, we need to create the final default case code-path,
|
|
111
131
|
// as we only handle fallthrough into defaults in the previous if statement chain
|