typescript-to-lua 0.41.2 → 1.1.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 +46 -0
- package/dist/CompilerOptions.d.ts +4 -3
- package/dist/LuaAST.js +4 -4
- package/dist/LuaLib.d.ts +7 -0
- package/dist/LuaLib.js +41 -5
- package/dist/LuaPrinter.d.ts +6 -2
- package/dist/LuaPrinter.js +25 -16
- package/dist/cli/diagnostics.js +2 -2
- package/dist/cli/report.js +1 -1
- package/dist/cli/tsconfig.js +4 -4
- package/dist/lualib/ArrayJoin.lua +2 -4
- package/dist/lualib/Await.lua +59 -0
- package/dist/lualib/Iterator.lua +1 -5
- package/dist/lualib/NumberToString.lua +4 -8
- package/dist/lualib/OptionalMethodCall.lua +3 -1
- package/dist/lualib/ParseInt.lua +1 -3
- package/dist/lualib/Promise.lua +172 -0
- package/dist/lualib/PromiseAll.lua +44 -0
- package/dist/lualib/PromiseAllSettled.lua +48 -0
- package/dist/lualib/PromiseAny.lua +41 -0
- package/dist/lualib/PromiseRace.lua +28 -0
- package/dist/lualib/SourceMapTraceBack.lua +18 -8
- package/dist/lualib/StringConcat.lua +1 -1
- package/dist/lualib/StringPadEnd.lua +7 -11
- package/dist/lualib/StringPadStart.lua +8 -12
- package/dist/lualib/StringReplace.lua +8 -13
- package/dist/lualib/StringReplaceAll.lua +35 -0
- package/dist/lualib/StringSubstring.lua +1 -1
- package/dist/lualib/lualib_bundle.lua +660 -239
- package/dist/transformation/builtins/array.js +29 -29
- package/dist/transformation/builtins/console.js +2 -2
- package/dist/transformation/builtins/function.js +9 -9
- package/dist/transformation/builtins/global.js +8 -8
- package/dist/transformation/builtins/index.js +35 -32
- package/dist/transformation/builtins/math.js +4 -4
- package/dist/transformation/builtins/number.js +7 -7
- package/dist/transformation/builtins/object.js +11 -11
- package/dist/transformation/builtins/promise.d.ts +7 -0
- package/dist/transformation/builtins/promise.js +46 -0
- package/dist/transformation/builtins/string.js +32 -30
- package/dist/transformation/builtins/symbol.js +3 -3
- package/dist/transformation/context/context.js +5 -5
- package/dist/transformation/index.js +1 -1
- package/dist/transformation/utils/annotations.d.ts +1 -4
- package/dist/transformation/utils/annotations.js +1 -32
- package/dist/transformation/utils/assignment-validation.js +8 -7
- package/dist/transformation/utils/diagnostics.d.ts +3 -0
- package/dist/transformation/utils/diagnostics.js +6 -5
- package/dist/transformation/utils/export.js +4 -4
- package/dist/transformation/utils/function-context.js +19 -13
- package/dist/transformation/utils/lua-ast.js +18 -19
- package/dist/transformation/utils/lualib.js +1 -1
- package/dist/transformation/utils/safe-names.js +5 -5
- package/dist/transformation/utils/scope.d.ts +6 -0
- package/dist/transformation/utils/scope.js +70 -40
- package/dist/transformation/utils/symbols.js +6 -6
- package/dist/transformation/utils/transform.js +3 -3
- package/dist/transformation/utils/typescript/nodes.d.ts +2 -0
- package/dist/transformation/utils/typescript/nodes.js +21 -1
- package/dist/transformation/visitors/access.js +25 -19
- package/dist/transformation/visitors/async-await.d.ts +6 -0
- package/dist/transformation/visitors/async-await.js +38 -0
- package/dist/transformation/visitors/binary-expression/assignments.js +32 -31
- package/dist/transformation/visitors/binary-expression/bit.js +4 -4
- package/dist/transformation/visitors/binary-expression/compound.js +18 -18
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +17 -17
- package/dist/transformation/visitors/binary-expression/index.js +22 -20
- package/dist/transformation/visitors/block.js +6 -6
- package/dist/transformation/visitors/break-continue.js +4 -9
- package/dist/transformation/visitors/call.js +38 -38
- package/dist/transformation/visitors/class/decorators.js +3 -3
- package/dist/transformation/visitors/class/index.js +34 -34
- package/dist/transformation/visitors/class/members/accessors.js +6 -6
- package/dist/transformation/visitors/class/members/constructor.js +7 -7
- package/dist/transformation/visitors/class/members/fields.js +6 -6
- package/dist/transformation/visitors/class/members/method.js +6 -6
- package/dist/transformation/visitors/class/new.js +13 -13
- package/dist/transformation/visitors/class/setup.js +11 -11
- package/dist/transformation/visitors/class/utils.js +2 -2
- package/dist/transformation/visitors/conditional.js +6 -6
- package/dist/transformation/visitors/delete.js +4 -4
- package/dist/transformation/visitors/enum.js +8 -8
- package/dist/transformation/visitors/errors.js +30 -31
- package/dist/transformation/visitors/expression-statement.js +10 -6
- package/dist/transformation/visitors/function.js +33 -21
- package/dist/transformation/visitors/identifier.js +25 -19
- package/dist/transformation/visitors/index.js +4 -2
- package/dist/transformation/visitors/language-extensions/iterable.js +7 -7
- package/dist/transformation/visitors/language-extensions/multi.d.ts +2 -1
- package/dist/transformation/visitors/language-extensions/multi.js +8 -4
- package/dist/transformation/visitors/language-extensions/operators.js +6 -6
- package/dist/transformation/visitors/language-extensions/range.js +6 -6
- package/dist/transformation/visitors/language-extensions/table.js +5 -5
- package/dist/transformation/visitors/literal.d.ts +1 -2
- package/dist/transformation/visitors/literal.js +19 -42
- package/dist/transformation/visitors/loops/do-while.js +2 -2
- package/dist/transformation/visitors/loops/for-in.js +4 -4
- package/dist/transformation/visitors/loops/for-of.js +13 -13
- package/dist/transformation/visitors/loops/for.js +3 -3
- package/dist/transformation/visitors/loops/utils.js +9 -9
- package/dist/transformation/visitors/modules/export.js +13 -13
- package/dist/transformation/visitors/modules/import.js +10 -10
- package/dist/transformation/visitors/namespace.js +13 -13
- package/dist/transformation/visitors/return.d.ts +1 -0
- package/dist/transformation/visitors/return.js +41 -49
- package/dist/transformation/visitors/sourceFile.js +8 -8
- package/dist/transformation/visitors/spread.js +16 -13
- package/dist/transformation/visitors/switch.js +132 -30
- package/dist/transformation/visitors/template.js +5 -5
- package/dist/transformation/visitors/typeof.js +2 -2
- package/dist/transformation/visitors/typescript.js +1 -1
- package/dist/transformation/visitors/unary-expression.js +9 -9
- package/dist/transformation/visitors/variable-declaration.js +29 -30
- package/dist/transformation/visitors/void.d.ts +6 -0
- package/dist/transformation/visitors/void.js +23 -0
- package/dist/transpilation/bundle.d.ts +3 -0
- package/dist/transpilation/bundle.js +56 -13
- package/dist/transpilation/diagnostics.js +3 -3
- package/dist/transpilation/index.js +2 -2
- package/dist/transpilation/output-collector.js +2 -2
- package/dist/transpilation/plugins.js +1 -1
- package/dist/transpilation/resolve.js +28 -14
- package/dist/transpilation/transformers.d.ts +1 -0
- package/dist/transpilation/transformers.js +61 -25
- package/dist/transpilation/transpile.js +7 -7
- package/dist/transpilation/transpiler.js +13 -11
- package/dist/transpilation/utils.js +3 -2
- package/dist/tstl.js +9 -9
- package/dist/utils.js +2 -2
- package/package.json +16 -13
- package/dist/transformation/visitors/jsx/jsx.d.ts +0 -9
- package/dist/transformation/visitors/jsx/jsx.js +0 -237
- package/dist/transformation/visitors/jsx/xhtml.d.ts +0 -3
- package/dist/transformation/visitors/jsx/xhtml.js +0 -260
|
@@ -1,95 +1,87 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformReturnStatement = exports.transformExpressionBodyToReturnStatement = void 0;
|
|
3
|
+
exports.createReturnStatement = exports.transformReturnStatement = exports.transformExpressionBodyToReturnStatement = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
|
-
const annotations_1 = require("../utils/annotations");
|
|
7
6
|
const assignment_validation_1 = require("../utils/assignment-validation");
|
|
8
7
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
9
8
|
const scope_1 = require("../utils/scope");
|
|
10
|
-
const typescript_1 = require("../utils/typescript");
|
|
11
9
|
const call_1 = require("./call");
|
|
12
10
|
const multi_1 = require("./language-extensions/multi");
|
|
13
11
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
12
|
+
const typescript_1 = require("../utils/typescript");
|
|
14
13
|
function transformExpressionsInReturn(context, node, insideTryCatch) {
|
|
15
14
|
const expressionType = context.checker.getTypeAtLocation(node);
|
|
16
15
|
if (ts.isCallExpression(node)) {
|
|
17
16
|
// $multi(...)
|
|
18
|
-
if (multi_1.isMultiFunctionCall(context, node)) {
|
|
17
|
+
if ((0, multi_1.isMultiFunctionCall)(context, node)) {
|
|
19
18
|
// Don't allow $multi to be implicitly cast to something other than LuaMultiReturn
|
|
20
19
|
const type = context.checker.getContextualType(node);
|
|
21
|
-
if (type && !multi_1.
|
|
22
|
-
context.diagnostics.push(diagnostics_1.invalidMultiFunctionReturnType(node));
|
|
20
|
+
if (type && !(0, multi_1.canBeMultiReturnType)(type)) {
|
|
21
|
+
context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionReturnType)(node));
|
|
23
22
|
}
|
|
24
|
-
let returnValues = call_1.transformArguments(context, node.arguments);
|
|
23
|
+
let returnValues = (0, call_1.transformArguments)(context, node.arguments);
|
|
25
24
|
if (insideTryCatch) {
|
|
26
|
-
returnValues = [lua_ast_1.wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch
|
|
25
|
+
returnValues = [(0, lua_ast_1.wrapInTable)(...returnValues)]; // Wrap results when returning inside try/catch
|
|
27
26
|
}
|
|
28
27
|
return returnValues;
|
|
29
28
|
}
|
|
30
29
|
// Force-wrap LuaMultiReturn when returning inside try/catch
|
|
31
|
-
if (insideTryCatch && multi_1.returnsMultiType(context, node) && !multi_1.shouldMultiReturnCallBeWrapped(context, node)) {
|
|
32
|
-
return [lua_ast_1.wrapInTable(context.transformExpression(node))];
|
|
30
|
+
if (insideTryCatch && (0, multi_1.returnsMultiType)(context, node) && !(0, multi_1.shouldMultiReturnCallBeWrapped)(context, node)) {
|
|
31
|
+
return [(0, lua_ast_1.wrapInTable)(context.transformExpression(node))];
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
|
-
else if (multi_1.isInMultiReturnFunction(context, node) && multi_1.isMultiReturnType(expressionType)) {
|
|
34
|
+
else if ((0, multi_1.isInMultiReturnFunction)(context, node) && (0, multi_1.isMultiReturnType)(expressionType)) {
|
|
36
35
|
// Unpack objects typed as LuaMultiReturn
|
|
37
|
-
return [lua_ast_1.createUnpackCall(context, context.transformExpression(node), node)];
|
|
38
|
-
}
|
|
39
|
-
if (!annotations_1.isInTupleReturnFunction(context, node)) {
|
|
40
|
-
return [context.transformExpression(node)];
|
|
41
|
-
}
|
|
42
|
-
let results;
|
|
43
|
-
// Parent function is a TupleReturn function
|
|
44
|
-
if (ts.isArrayLiteralExpression(node)) {
|
|
45
|
-
// If return expression is an array literal, leave out brackets.
|
|
46
|
-
results = node.elements.map(e => context.transformExpression(e));
|
|
47
|
-
}
|
|
48
|
-
else if (!annotations_1.isTupleReturnCall(context, node) && typescript_1.isArrayType(context, expressionType)) {
|
|
49
|
-
// If return expression is an array-type and not another TupleReturn call, unpack it
|
|
50
|
-
results = [lua_ast_1.createUnpackCall(context, context.transformExpression(node), node)];
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
results = [context.transformExpression(node)];
|
|
36
|
+
return [(0, lua_ast_1.createUnpackCall)(context, context.transformExpression(node), node)];
|
|
54
37
|
}
|
|
55
|
-
|
|
56
|
-
if (insideTryCatch) {
|
|
57
|
-
results = [lua_ast_1.wrapInTable(...results)];
|
|
58
|
-
}
|
|
59
|
-
return results;
|
|
38
|
+
return [context.transformExpression(node)];
|
|
60
39
|
}
|
|
61
40
|
function transformExpressionBodyToReturnStatement(context, node) {
|
|
62
41
|
const expressions = transformExpressionsInReturn(context, node, false);
|
|
63
|
-
return
|
|
42
|
+
return createReturnStatement(context, expressions, node);
|
|
64
43
|
}
|
|
65
44
|
exports.transformExpressionBodyToReturnStatement = transformExpressionBodyToReturnStatement;
|
|
66
45
|
const transformReturnStatement = (statement, context) => {
|
|
67
|
-
// Bubble up explicit return flag and check if we're inside a try/catch block
|
|
68
|
-
let insideTryCatch = false;
|
|
69
|
-
for (const scope of scope_1.walkScopesUp(context)) {
|
|
70
|
-
scope.functionReturned = true;
|
|
71
|
-
if (scope.type === scope_1.ScopeType.Function) {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
insideTryCatch = insideTryCatch || scope.type === scope_1.ScopeType.Try || scope.type === scope_1.ScopeType.Catch;
|
|
75
|
-
}
|
|
76
46
|
let results;
|
|
77
47
|
if (statement.expression) {
|
|
78
48
|
const expressionType = context.checker.getTypeAtLocation(statement.expression);
|
|
79
49
|
const returnType = context.checker.getContextualType(statement.expression);
|
|
80
50
|
if (returnType) {
|
|
81
|
-
assignment_validation_1.validateAssignment(context, statement, expressionType, returnType);
|
|
51
|
+
(0, assignment_validation_1.validateAssignment)(context, statement, expressionType, returnType);
|
|
82
52
|
}
|
|
83
|
-
results = transformExpressionsInReturn(context, statement.expression,
|
|
53
|
+
results = transformExpressionsInReturn(context, statement.expression, isInTryCatch(context));
|
|
84
54
|
}
|
|
85
55
|
else {
|
|
86
56
|
// Empty return
|
|
87
57
|
results = [];
|
|
88
58
|
}
|
|
89
|
-
|
|
90
|
-
results.unshift(lua.createBooleanLiteral(true));
|
|
91
|
-
}
|
|
92
|
-
return lua.createReturnStatement(results, statement);
|
|
59
|
+
return createReturnStatement(context, results, statement);
|
|
93
60
|
};
|
|
94
61
|
exports.transformReturnStatement = transformReturnStatement;
|
|
62
|
+
function createReturnStatement(context, values, node) {
|
|
63
|
+
const results = [...values];
|
|
64
|
+
if (isInTryCatch(context)) {
|
|
65
|
+
// Bubble up explicit return flag and check if we're inside a try/catch block
|
|
66
|
+
results.unshift(lua.createBooleanLiteral(true));
|
|
67
|
+
}
|
|
68
|
+
else if ((0, typescript_1.isInAsyncFunction)(node)) {
|
|
69
|
+
// Add nil error handler in async function and not in try
|
|
70
|
+
results.unshift(lua.createNilLiteral());
|
|
71
|
+
}
|
|
72
|
+
return lua.createReturnStatement(results, node);
|
|
73
|
+
}
|
|
74
|
+
exports.createReturnStatement = createReturnStatement;
|
|
75
|
+
function isInTryCatch(context) {
|
|
76
|
+
// Check if context is in a try or catch
|
|
77
|
+
let insideTryCatch = false;
|
|
78
|
+
for (const scope of (0, scope_1.walkScopesUp)(context)) {
|
|
79
|
+
scope.functionReturned = true;
|
|
80
|
+
if (scope.type === scope_1.ScopeType.Function) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
insideTryCatch = insideTryCatch || scope.type === scope_1.ScopeType.Try || scope.type === scope_1.ScopeType.Catch;
|
|
84
|
+
}
|
|
85
|
+
return insideTryCatch;
|
|
86
|
+
}
|
|
95
87
|
//# sourceMappingURL=return.js.map
|
|
@@ -14,7 +14,7 @@ const transformSourceFileNode = (node, context) => {
|
|
|
14
14
|
if (node.flags & ts.NodeFlags.JsonFile) {
|
|
15
15
|
const [statement] = node.statements;
|
|
16
16
|
if (statement) {
|
|
17
|
-
utils_1.assert(ts.isExpressionStatement(statement));
|
|
17
|
+
(0, utils_1.assert)(ts.isExpressionStatement(statement));
|
|
18
18
|
statements.push(lua.createReturnStatement([context.transformExpression(statement.expression)]));
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
@@ -25,21 +25,21 @@ const transformSourceFileNode = (node, context) => {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
|
-
scope_1.pushScope(context, scope_1.ScopeType.File);
|
|
29
|
-
statements = scope_1.performHoisting(context, context.transformStatements(node.statements));
|
|
30
|
-
scope_1.popScope(context);
|
|
28
|
+
(0, scope_1.pushScope)(context, scope_1.ScopeType.File);
|
|
29
|
+
statements = (0, scope_1.performHoisting)(context, context.transformStatements(node.statements));
|
|
30
|
+
(0, scope_1.popScope)(context);
|
|
31
31
|
if (context.isModule) {
|
|
32
32
|
// If export equals was not used. Create the exports table.
|
|
33
33
|
// local ____exports = {}
|
|
34
|
-
if (!typescript_1.hasExportEquals(node)) {
|
|
35
|
-
statements.unshift(lua.createVariableDeclarationStatement(lua_ast_1.createExportsIdentifier(), lua.createTableExpression()));
|
|
34
|
+
if (!(0, typescript_1.hasExportEquals)(node)) {
|
|
35
|
+
statements.unshift(lua.createVariableDeclarationStatement((0, lua_ast_1.createExportsIdentifier)(), lua.createTableExpression()));
|
|
36
36
|
}
|
|
37
37
|
// return ____exports
|
|
38
|
-
statements.push(lua.createReturnStatement([lua_ast_1.createExportsIdentifier()]));
|
|
38
|
+
statements.push(lua.createReturnStatement([(0, lua_ast_1.createExportsIdentifier)()]));
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
const trivia = (_b = (_a = node.getFullText().match(/^#!.*\r?\n/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "";
|
|
42
|
-
return lua.createFile(statements, lualib_1.getUsedLuaLibFeatures(context), trivia, node);
|
|
42
|
+
return lua.createFile(statements, (0, lualib_1.getUsedLuaLibFeatures)(context), trivia, node);
|
|
43
43
|
};
|
|
44
44
|
exports.transformSourceFileNode = transformSourceFileNode;
|
|
45
45
|
//# sourceMappingURL=sourceFile.js.map
|
|
@@ -12,20 +12,25 @@ const multi_1 = require("./language-extensions/multi");
|
|
|
12
12
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
13
13
|
const vararg_1 = require("./language-extensions/vararg");
|
|
14
14
|
function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
15
|
+
var _a;
|
|
15
16
|
if (!ts.isSpreadElement(identifier.parent)) {
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
19
|
// Walk up, stopping at any scope types which could stop optimization
|
|
19
|
-
const scope = scope_1.findScope(context, scope_1.ScopeType.Function | scope_1.ScopeType.Try | scope_1.ScopeType.Catch | scope_1.ScopeType.File);
|
|
20
|
+
const scope = (0, scope_1.findScope)(context, scope_1.ScopeType.Function | scope_1.ScopeType.Try | scope_1.ScopeType.Catch | scope_1.ScopeType.File);
|
|
20
21
|
if (!scope) {
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
// $vararg global constant
|
|
24
|
-
if (vararg_1.isGlobalVarargConstant(context, symbol, scope)) {
|
|
25
|
+
if ((0, vararg_1.isGlobalVarargConstant)(context, symbol, scope)) {
|
|
25
26
|
return true;
|
|
26
27
|
}
|
|
27
28
|
// Scope must be a function scope associated with a real ts function
|
|
28
|
-
if (!scope_1.isFunctionScopeWithDefinition(scope)) {
|
|
29
|
+
if (!(0, scope_1.isFunctionScopeWithDefinition)(scope)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Scope cannot be an async function
|
|
33
|
+
if ((_a = scope.node.modifiers) === null || _a === void 0 ? void 0 : _a.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) {
|
|
29
34
|
return false;
|
|
30
35
|
}
|
|
31
36
|
// Identifier must be a vararg in the local function scope's parameters
|
|
@@ -34,11 +39,11 @@ function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
|
34
39
|
return false;
|
|
35
40
|
}
|
|
36
41
|
// De-optimize if already referenced outside of a spread, as the array may have been modified
|
|
37
|
-
if (scope_1.hasReferencedSymbol(context, scope, symbol)) {
|
|
42
|
+
if ((0, scope_1.hasReferencedSymbol)(context, scope, symbol)) {
|
|
38
43
|
return false;
|
|
39
44
|
}
|
|
40
45
|
// De-optimize if a function is being hoisted from below to above, as it may have modified the array
|
|
41
|
-
if (scope_1.hasReferencedUndefinedLocalFunction(context, scope)) {
|
|
46
|
+
if ((0, scope_1.hasReferencedUndefinedLocalFunction)(context, scope)) {
|
|
42
47
|
return false;
|
|
43
48
|
}
|
|
44
49
|
return true;
|
|
@@ -47,8 +52,8 @@ exports.isOptimizedVarArgSpread = isOptimizedVarArgSpread;
|
|
|
47
52
|
// TODO: Currently it's also used as an array member
|
|
48
53
|
const transformSpreadElement = (node, context) => {
|
|
49
54
|
if (ts.isIdentifier(node.expression)) {
|
|
50
|
-
if (annotations_1.isVarargType(context, node.expression)) {
|
|
51
|
-
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.Vararg));
|
|
55
|
+
if ((0, annotations_1.isVarargType)(context, node.expression)) {
|
|
56
|
+
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.Vararg));
|
|
52
57
|
}
|
|
53
58
|
const symbol = context.checker.getSymbolAtLocation(node.expression);
|
|
54
59
|
if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) {
|
|
@@ -56,15 +61,13 @@ const transformSpreadElement = (node, context) => {
|
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
const innerExpression = context.transformExpression(node.expression);
|
|
59
|
-
if (
|
|
60
|
-
return innerExpression;
|
|
61
|
-
if (ts.isCallExpression(node.expression) && multi_1.returnsMultiType(context, node.expression))
|
|
64
|
+
if ((0, multi_1.isMultiReturnCall)(context, node.expression))
|
|
62
65
|
return innerExpression;
|
|
63
66
|
const type = context.checker.getTypeAtLocation(node.expression);
|
|
64
|
-
if (typescript_1.isArrayType(context, type)) {
|
|
65
|
-
return lua_ast_1.createUnpackCall(context, innerExpression, node);
|
|
67
|
+
if ((0, typescript_1.isArrayType)(context, type)) {
|
|
68
|
+
return (0, lua_ast_1.createUnpackCall)(context, innerExpression, node);
|
|
66
69
|
}
|
|
67
|
-
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Spread, node, innerExpression);
|
|
70
|
+
return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.Spread, node, innerExpression);
|
|
68
71
|
};
|
|
69
72
|
exports.transformSpreadElement = transformSpreadElement;
|
|
70
73
|
//# sourceMappingURL=spread.js.map
|
|
@@ -2,46 +2,148 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.transformSwitchStatement = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
|
-
const CompilerOptions_1 = require("../../CompilerOptions");
|
|
6
5
|
const lua = require("../../LuaAST");
|
|
7
|
-
const diagnostics_1 = require("../utils/diagnostics");
|
|
8
6
|
const scope_1 = require("../utils/scope");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const containsBreakOrReturn = (nodes) => {
|
|
8
|
+
for (const s of nodes) {
|
|
9
|
+
if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
else if (ts.isBlock(s) && containsBreakOrReturn(s.getChildren())) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
const coalesceCondition = (condition, switchVariable, expression, context) => {
|
|
22
|
+
// Coalesce skipped statements
|
|
23
|
+
if (condition) {
|
|
24
|
+
return lua.createBinaryExpression(condition, lua.createBinaryExpression(switchVariable, context.transformExpression(expression), lua.SyntaxKind.EqualityOperator), lua.SyntaxKind.OrOperator);
|
|
12
25
|
}
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
// Next condition
|
|
27
|
+
return lua.createBinaryExpression(switchVariable, context.transformExpression(expression), lua.SyntaxKind.EqualityOperator);
|
|
28
|
+
};
|
|
29
|
+
const transformSwitchStatement = (statement, context) => {
|
|
30
|
+
const scope = (0, scope_1.pushScope)(context, scope_1.ScopeType.Switch);
|
|
31
|
+
// Give the switch and condition accumulator a unique name to prevent nested switches from acting up.
|
|
15
32
|
const switchName = `____switch${scope.id}`;
|
|
33
|
+
const conditionName = `____cond${scope.id}`;
|
|
16
34
|
const switchVariable = lua.createIdentifier(switchName);
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
const conditionVariable = lua.createIdentifier(conditionName);
|
|
36
|
+
// If the switch only has a default clause, wrap it in a single do.
|
|
37
|
+
// Otherwise, we need to generate a set of if statements to emulate the switch.
|
|
38
|
+
const statements = [];
|
|
39
|
+
const hoistedStatements = [];
|
|
40
|
+
const hoistedIdentifiers = [];
|
|
41
|
+
const clauses = statement.caseBlock.clauses;
|
|
42
|
+
if (clauses.length === 1 && ts.isDefaultClause(clauses[0])) {
|
|
43
|
+
const defaultClause = clauses[0].statements;
|
|
44
|
+
if (defaultClause.length) {
|
|
45
|
+
const { statements: defaultStatements, hoistedStatements: defaultHoistedStatements, hoistedIdentifiers: defaultHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(defaultClause));
|
|
46
|
+
hoistedStatements.push(...defaultHoistedStatements);
|
|
47
|
+
hoistedIdentifiers.push(...defaultHoistedIdentifiers);
|
|
48
|
+
statements.push(lua.createDoStatement(defaultStatements));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Build up the condition for each if statement
|
|
53
|
+
let defaultTransformed = false;
|
|
54
|
+
let isInitialCondition = true;
|
|
55
|
+
let condition = undefined;
|
|
56
|
+
for (let i = 0; i < clauses.length; i++) {
|
|
57
|
+
const clause = clauses[i];
|
|
58
|
+
const previousClause = clauses[i - 1];
|
|
59
|
+
// Skip redundant default clauses, will be handled in final default case
|
|
60
|
+
if (i === 0 && ts.isDefaultClause(clause))
|
|
61
|
+
continue;
|
|
62
|
+
if (ts.isDefaultClause(clause) && previousClause && containsBreakOrReturn(previousClause.statements)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Compute the condition for the if statement
|
|
66
|
+
if (!ts.isDefaultClause(clause)) {
|
|
67
|
+
condition = coalesceCondition(condition, switchVariable, clause.expression, context);
|
|
68
|
+
// Skip empty clauses unless final clause (i.e side-effects)
|
|
69
|
+
if (i !== clauses.length - 1 && clause.statements.length === 0)
|
|
70
|
+
continue;
|
|
71
|
+
// Declare or assign condition variable
|
|
72
|
+
statements.push(isInitialCondition
|
|
73
|
+
? lua.createVariableDeclarationStatement(conditionVariable, condition)
|
|
74
|
+
: lua.createAssignmentStatement(conditionVariable, lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator)));
|
|
75
|
+
isInitialCondition = false;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// If the default is proceeded by empty clauses and will be emitted we may need to initialize the condition
|
|
79
|
+
if (isInitialCondition) {
|
|
80
|
+
statements.push(lua.createVariableDeclarationStatement(conditionVariable, condition !== null && condition !== void 0 ? condition : lua.createBooleanLiteral(false)));
|
|
81
|
+
// Clear condition ot ensure it is not evaluated twice
|
|
82
|
+
condition = undefined;
|
|
83
|
+
isInitialCondition = false;
|
|
84
|
+
}
|
|
85
|
+
// Allow default to fallthrough to final default clause
|
|
86
|
+
if (i === clauses.length - 1) {
|
|
87
|
+
// Evaluate the final condition that we may be skipping
|
|
88
|
+
if (condition) {
|
|
89
|
+
statements.push(lua.createAssignmentStatement(conditionVariable, lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator)));
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Transform the clause and append the final break statement if necessary
|
|
95
|
+
const { statements: clauseStatements, hoistedStatements: clauseHoistedStatements, hoistedIdentifiers: clauseHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(clause.statements));
|
|
96
|
+
if (i === clauses.length - 1 && !containsBreakOrReturn(clause.statements)) {
|
|
97
|
+
clauseStatements.push(lua.createBreakStatement());
|
|
98
|
+
}
|
|
99
|
+
hoistedStatements.push(...clauseHoistedStatements);
|
|
100
|
+
hoistedIdentifiers.push(...clauseHoistedIdentifiers);
|
|
101
|
+
// Remember that we transformed default clause so we don't duplicate hoisted statements later
|
|
102
|
+
if (ts.isDefaultClause(clause)) {
|
|
103
|
+
defaultTransformed = true;
|
|
104
|
+
}
|
|
105
|
+
// Push if statement for case
|
|
106
|
+
statements.push(lua.createIfStatement(conditionVariable, lua.createBlock(clauseStatements)));
|
|
107
|
+
// Clear condition for next clause
|
|
108
|
+
condition = undefined;
|
|
109
|
+
}
|
|
110
|
+
// If no conditions above match, we need to create the final default case code-path,
|
|
111
|
+
// as we only handle fallthrough into defaults in the previous if statement chain
|
|
112
|
+
const start = clauses.findIndex(c => ts.isDefaultClause(c));
|
|
113
|
+
if (start >= 0) {
|
|
114
|
+
// Find the last clause that we can fallthrough to
|
|
115
|
+
const end = clauses.findIndex((clause, index) => index >= start && containsBreakOrReturn(clause.statements));
|
|
116
|
+
const { statements: defaultStatements, hoistedStatements: defaultHoistedStatements, hoistedIdentifiers: defaultHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(clauses[start].statements));
|
|
117
|
+
// Only push hoisted statements if this is the first time we're transforming the default clause
|
|
118
|
+
if (!defaultTransformed) {
|
|
119
|
+
hoistedStatements.push(...defaultHoistedStatements);
|
|
120
|
+
hoistedIdentifiers.push(...defaultHoistedIdentifiers);
|
|
121
|
+
}
|
|
122
|
+
// Combine the fallthrough statements
|
|
123
|
+
for (const clause of clauses.slice(start + 1, end >= 0 ? end + 1 : undefined)) {
|
|
124
|
+
let statements = context.transformStatements(clause.statements);
|
|
125
|
+
// Drop hoisted statements as they were already added when clauses were initially transformed above
|
|
126
|
+
({ statements } = (0, scope_1.separateHoistedStatements)(context, statements));
|
|
127
|
+
defaultStatements.push(...statements);
|
|
128
|
+
}
|
|
129
|
+
// Add the default clause if it has any statements
|
|
130
|
+
// The switch will always break on the final clause and skip execution if valid to do so
|
|
131
|
+
if (defaultStatements.length) {
|
|
132
|
+
statements.push(lua.createDoStatement(defaultStatements));
|
|
133
|
+
}
|
|
23
134
|
}
|
|
24
|
-
// If the clause condition holds, go to the correct label
|
|
25
|
-
const condition = lua.createBinaryExpression(switchVariable, context.transformExpression(clause.expression), lua.SyntaxKind.EqualityOperator);
|
|
26
|
-
const goto = lua.createGotoStatement(`${switchName}_case_${index}`);
|
|
27
|
-
return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition);
|
|
28
|
-
}, undefined);
|
|
29
|
-
if (concatenatedIf) {
|
|
30
|
-
statements.push(concatenatedIf);
|
|
31
135
|
}
|
|
32
|
-
|
|
33
|
-
statements.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
statements.push(lua.createLabelStatement(labelName));
|
|
37
|
-
statements.push(lua.createDoStatement(context.transformStatements(clause.statements)));
|
|
136
|
+
// Hoist the variable, function, and import statements to the top of the switch
|
|
137
|
+
statements.unshift(...hoistedStatements);
|
|
138
|
+
if (hoistedIdentifiers.length > 0) {
|
|
139
|
+
statements.unshift(lua.createVariableDeclarationStatement(hoistedIdentifiers));
|
|
38
140
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
scope_1.popScope(context);
|
|
141
|
+
(0, scope_1.popScope)(context);
|
|
142
|
+
// Add the switch expression after hoisting
|
|
42
143
|
const expression = context.transformExpression(statement.expression);
|
|
43
144
|
statements.unshift(lua.createVariableDeclarationStatement(switchVariable, expression));
|
|
44
|
-
|
|
145
|
+
// Wrap the statements in a repeat until true statement to facilitate dynamic break/returns
|
|
146
|
+
return lua.createRepeatStatement(lua.createBlock(statements), lua.createBooleanLiteral(true));
|
|
45
147
|
};
|
|
46
148
|
exports.transformSwitchStatement = transformSwitchStatement;
|
|
47
149
|
//# sourceMappingURL=switch.js.map
|
|
@@ -24,11 +24,11 @@ const transformTemplateExpression = (node, context) => {
|
|
|
24
24
|
for (const span of node.templateSpans) {
|
|
25
25
|
const expression = context.transformExpression(span.expression);
|
|
26
26
|
const spanType = context.checker.getTypeAtLocation(span.expression);
|
|
27
|
-
if (types_1.isStringType(context, spanType)) {
|
|
27
|
+
if ((0, types_1.isStringType)(context, spanType)) {
|
|
28
28
|
parts.push(expression);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
parts.push(lua_ast_1.wrapInToStringForConcat(expression));
|
|
31
|
+
parts.push((0, lua_ast_1.wrapInToStringForConcat)(expression));
|
|
32
32
|
}
|
|
33
33
|
const text = span.literal.text;
|
|
34
34
|
if (text.length > 0) {
|
|
@@ -65,12 +65,12 @@ const transformTaggedTemplateExpression = (expression, context) => {
|
|
|
65
65
|
// Evaluate if there is a self parameter to be used.
|
|
66
66
|
const signature = context.checker.getResolvedSignature(expression);
|
|
67
67
|
const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
|
|
68
|
-
const useSelfParameter = signatureDeclaration && function_context_1.getDeclarationContextType(context, signatureDeclaration) !== function_context_1.ContextType.Void;
|
|
68
|
+
const useSelfParameter = signatureDeclaration && (0, function_context_1.getDeclarationContextType)(context, signatureDeclaration) !== function_context_1.ContextType.Void;
|
|
69
69
|
if (useSelfParameter) {
|
|
70
|
-
return call_1.transformContextualCallExpression(context, expression, expressions, signature);
|
|
70
|
+
return (0, call_1.transformContextualCallExpression)(context, expression, expressions, signature);
|
|
71
71
|
}
|
|
72
72
|
// Argument evaluation.
|
|
73
|
-
const callArguments = call_1.transformArguments(context, expressions, signature);
|
|
73
|
+
const callArguments = (0, call_1.transformArguments)(context, expressions, signature);
|
|
74
74
|
const leftHandSideExpression = context.transformExpression(expression.tag);
|
|
75
75
|
return lua.createCallExpression(leftHandSideExpression, callArguments);
|
|
76
76
|
};
|
|
@@ -8,7 +8,7 @@ const lualib_1 = require("../utils/lualib");
|
|
|
8
8
|
const binary_expression_1 = require("./binary-expression");
|
|
9
9
|
const transformTypeOfExpression = (node, context) => {
|
|
10
10
|
const innerExpression = context.transformExpression(node.expression);
|
|
11
|
-
return lualib_1.transformLuaLibFunction(context, LuaLib_1.LuaLibFeature.TypeOf, node, innerExpression);
|
|
11
|
+
return (0, lualib_1.transformLuaLibFunction)(context, LuaLib_1.LuaLibFeature.TypeOf, node, innerExpression);
|
|
12
12
|
};
|
|
13
13
|
exports.transformTypeOfExpression = transformTypeOfExpression;
|
|
14
14
|
function transformTypeOfBinaryExpression(context, node) {
|
|
@@ -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
|
-
return binary_expression_1.transformBinaryOperation(context, typeCall, comparedExpression, operator, node);
|
|
46
|
+
return (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, operator, node);
|
|
47
47
|
}
|
|
48
48
|
exports.transformTypeOfBinaryExpression = transformTypeOfBinaryExpression;
|
|
49
49
|
//# sourceMappingURL=typeof.js.map
|
|
@@ -5,7 +5,7 @@ const ts = require("typescript");
|
|
|
5
5
|
const assignment_validation_1 = require("../utils/assignment-validation");
|
|
6
6
|
const transformAssertionExpression = (expression, context) => {
|
|
7
7
|
if (!ts.isConstTypeReference(expression.type)) {
|
|
8
|
-
assignment_validation_1.validateAssignment(context, expression, context.checker.getTypeAtLocation(expression.expression), context.checker.getTypeAtLocation(expression.type));
|
|
8
|
+
(0, assignment_validation_1.validateAssignment)(context, expression, context.checker.getTypeAtLocation(expression.expression), context.checker.getTypeAtLocation(expression.type));
|
|
9
9
|
}
|
|
10
10
|
return context.transformExpression(expression.expression);
|
|
11
11
|
};
|
|
@@ -12,32 +12,32 @@ function transformUnaryExpressionStatement(context, node) {
|
|
|
12
12
|
(expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) {
|
|
13
13
|
// ++i, --i
|
|
14
14
|
const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken;
|
|
15
|
-
return compound_1.transformCompoundAssignmentStatement(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
|
|
15
|
+
return (0, compound_1.transformCompoundAssignmentStatement)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
|
|
16
16
|
}
|
|
17
17
|
else if (ts.isPostfixUnaryExpression(expression)) {
|
|
18
18
|
// i++, i--
|
|
19
19
|
const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken;
|
|
20
|
-
return compound_1.transformCompoundAssignmentStatement(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
|
|
20
|
+
return (0, compound_1.transformCompoundAssignmentStatement)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
exports.transformUnaryExpressionStatement = transformUnaryExpressionStatement;
|
|
24
24
|
const transformPostfixUnaryExpression = (expression, context) => {
|
|
25
25
|
switch (expression.operator) {
|
|
26
26
|
case ts.SyntaxKind.PlusPlusToken:
|
|
27
|
-
return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, true);
|
|
27
|
+
return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, true);
|
|
28
28
|
case ts.SyntaxKind.MinusMinusToken:
|
|
29
|
-
return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, true);
|
|
29
|
+
return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, true);
|
|
30
30
|
default:
|
|
31
|
-
utils_1.assertNever(expression.operator);
|
|
31
|
+
(0, utils_1.assertNever)(expression.operator);
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
exports.transformPostfixUnaryExpression = transformPostfixUnaryExpression;
|
|
35
35
|
const transformPrefixUnaryExpression = (expression, context) => {
|
|
36
36
|
switch (expression.operator) {
|
|
37
37
|
case ts.SyntaxKind.PlusPlusToken:
|
|
38
|
-
return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, false);
|
|
38
|
+
return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, false);
|
|
39
39
|
case ts.SyntaxKind.MinusMinusToken:
|
|
40
|
-
return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, false);
|
|
40
|
+
return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, false);
|
|
41
41
|
case ts.SyntaxKind.PlusToken:
|
|
42
42
|
// TODO: Wrap with `Number`
|
|
43
43
|
return context.transformExpression(expression.operand);
|
|
@@ -46,9 +46,9 @@ const transformPrefixUnaryExpression = (expression, context) => {
|
|
|
46
46
|
case ts.SyntaxKind.ExclamationToken:
|
|
47
47
|
return lua.createUnaryExpression(context.transformExpression(expression.operand), lua.SyntaxKind.NotOperator);
|
|
48
48
|
case ts.SyntaxKind.TildeToken:
|
|
49
|
-
return bit_1.transformUnaryBitOperation(context, expression, context.transformExpression(expression.operand), lua.SyntaxKind.BitwiseNotOperator);
|
|
49
|
+
return (0, bit_1.transformUnaryBitOperation)(context, expression, context.transformExpression(expression.operand), lua.SyntaxKind.BitwiseNotOperator);
|
|
50
50
|
default:
|
|
51
|
-
utils_1.assertNever(expression.operator);
|
|
51
|
+
(0, utils_1.assertNever)(expression.operator);
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
54
|
exports.transformPrefixUnaryExpression = transformPrefixUnaryExpression;
|