typescript-to-lua 1.0.0 → 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 +34 -0
- package/dist/CompilerOptions.d.ts +4 -3
- package/dist/LuaAST.d.ts +1 -0
- package/dist/LuaAST.js +14 -6
- package/dist/LuaLib.d.ts +4 -3
- package/dist/LuaLib.js +5 -4
- package/dist/LuaPrinter.d.ts +15 -4
- package/dist/LuaPrinter.js +79 -27
- package/dist/cli/diagnostics.js +2 -2
- package/dist/cli/parse.d.ts +1 -1
- package/dist/cli/parse.js +14 -0
- package/dist/cli/report.js +1 -1
- package/dist/cli/tsconfig.js +4 -4
- 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 +39 -19
- 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 +36 -26
- package/dist/lualib/Set.lua +119 -123
- package/dist/lualib/SetDescriptor.lua +7 -1
- package/dist/lualib/SourceMapTraceBack.lua +19 -9
- 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 +12 -11
- package/dist/lualib/StringReplaceAll.lua +35 -0
- 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 +705 -586
- package/dist/transformation/builtins/array.js +29 -30
- package/dist/transformation/builtins/console.js +2 -2
- package/dist/transformation/builtins/function.js +9 -10
- package/dist/transformation/builtins/global.js +8 -8
- package/dist/transformation/builtins/index.d.ts +1 -1
- package/dist/transformation/builtins/index.js +69 -36
- package/dist/transformation/builtins/math.js +4 -4
- package/dist/transformation/builtins/number.js +7 -7
- package/dist/transformation/builtins/object.d.ts +2 -1
- package/dist/transformation/builtins/object.js +12 -13
- package/dist/transformation/builtins/promise.js +9 -9
- package/dist/transformation/builtins/string.js +32 -31
- package/dist/transformation/builtins/symbol.js +3 -3
- package/dist/transformation/context/context.d.ts +12 -0
- package/dist/transformation/context/context.js +105 -6
- package/dist/transformation/index.js +1 -1
- package/dist/transformation/utils/annotations.d.ts +1 -3
- package/dist/transformation/utils/annotations.js +0 -2
- package/dist/transformation/utils/assignment-validation.js +8 -7
- package/dist/transformation/utils/diagnostics.d.ts +6 -0
- package/dist/transformation/utils/diagnostics.js +7 -5
- package/dist/transformation/utils/export.d.ts +3 -2
- package/dist/transformation/utils/export.js +14 -7
- package/dist/transformation/utils/function-context.js +8 -8
- package/dist/transformation/utils/lua-ast.d.ts +0 -1
- package/dist/transformation/utils/lua-ast.js +25 -35
- package/dist/transformation/utils/lualib.js +1 -1
- package/dist/transformation/utils/preceding-statements.d.ts +3 -0
- package/dist/transformation/utils/preceding-statements.js +11 -0
- package/dist/transformation/utils/safe-names.js +5 -5
- package/dist/transformation/utils/scope.d.ts +7 -0
- package/dist/transformation/utils/scope.js +77 -40
- package/dist/transformation/utils/symbols.js +6 -6
- package/dist/transformation/utils/typescript/index.d.ts +1 -0
- package/dist/transformation/utils/typescript/index.js +16 -1
- package/dist/transformation/utils/typescript/nodes.d.ts +2 -0
- package/dist/transformation/utils/typescript/nodes.js +21 -1
- package/dist/transformation/visitors/access.d.ts +3 -0
- package/dist/transformation/visitors/access.js +74 -47
- package/dist/transformation/visitors/async-await.js +5 -4
- package/dist/transformation/visitors/binary-expression/assignments.d.ts +3 -2
- package/dist/transformation/visitors/binary-expression/assignments.js +86 -77
- package/dist/transformation/visitors/binary-expression/bit.js +4 -4
- package/dist/transformation/visitors/binary-expression/compound.d.ts +5 -4
- package/dist/transformation/visitors/binary-expression/compound.js +69 -71
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.d.ts +2 -2
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +65 -36
- package/dist/transformation/visitors/binary-expression/index.d.ts +3 -1
- package/dist/transformation/visitors/binary-expression/index.js +84 -40
- package/dist/transformation/visitors/block.js +6 -6
- package/dist/transformation/visitors/break-continue.js +4 -9
- package/dist/transformation/visitors/call.d.ts +3 -2
- package/dist/transformation/visitors/call.js +130 -143
- package/dist/transformation/visitors/class/decorators.js +3 -3
- package/dist/transformation/visitors/class/index.js +43 -39
- 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 +14 -16
- package/dist/transformation/visitors/class/setup.js +11 -11
- package/dist/transformation/visitors/class/utils.js +2 -2
- package/dist/transformation/visitors/conditional.js +34 -20
- package/dist/transformation/visitors/delete.js +8 -4
- package/dist/transformation/visitors/enum.js +8 -8
- package/dist/transformation/visitors/errors.js +30 -30
- package/dist/transformation/visitors/expression-list.d.ts +7 -0
- package/dist/transformation/visitors/expression-list.js +120 -0
- package/dist/transformation/visitors/expression-statement.js +10 -6
- package/dist/transformation/visitors/function.js +30 -32
- package/dist/transformation/visitors/identifier.js +26 -22
- package/dist/transformation/visitors/index.js +2 -2
- package/dist/transformation/visitors/language-extensions/iterable.js +7 -7
- package/dist/transformation/visitors/language-extensions/multi.d.ts +1 -1
- package/dist/transformation/visitors/language-extensions/multi.js +3 -3
- 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 +87 -57
- package/dist/transformation/visitors/loops/do-while.js +35 -9
- 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 +28 -8
- package/dist/transformation/visitors/loops/utils.d.ts +1 -0
- package/dist/transformation/visitors/loops/utils.js +21 -10
- package/dist/transformation/visitors/modules/export.js +14 -15
- package/dist/transformation/visitors/modules/import.js +10 -10
- package/dist/transformation/visitors/namespace.js +13 -13
- package/dist/transformation/visitors/optional-chaining.d.ts +16 -0
- package/dist/transformation/visitors/optional-chaining.js +172 -0
- package/dist/transformation/visitors/return.d.ts +1 -0
- package/dist/transformation/visitors/return.js +40 -26
- package/dist/transformation/visitors/sourceFile.js +12 -9
- package/dist/transformation/visitors/spread.js +11 -11
- package/dist/transformation/visitors/switch.js +152 -30
- package/dist/transformation/visitors/template.js +10 -7
- package/dist/transformation/visitors/typeof.js +4 -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 +46 -32
- package/dist/transformation/visitors/void.d.ts +6 -0
- package/dist/transformation/visitors/void.js +20 -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 +26 -14
- package/dist/transpilation/transformers.js +45 -25
- package/dist/transpilation/transpile.js +6 -6
- package/dist/transpilation/transpiler.js +8 -8
- package/dist/transpilation/utils.js +5 -3
- package/dist/tstl.js +8 -8
- package/dist/utils.js +2 -2
- package/package.json +15 -12
- 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
- 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
|
@@ -13,11 +13,11 @@ const symbols_1 = require("../utils/symbols");
|
|
|
13
13
|
const identifier_1 = require("./identifier");
|
|
14
14
|
function createModuleLocalNameIdentifier(context, declaration) {
|
|
15
15
|
const moduleSymbol = context.checker.getSymbolAtLocation(declaration.name);
|
|
16
|
-
if (moduleSymbol !== undefined && safe_names_1.isUnsafeName(moduleSymbol.name)) {
|
|
17
|
-
return lua.createIdentifier(safe_names_1.createSafeName(declaration.name.text), declaration.name, moduleSymbol && symbols_1.getSymbolIdOfSymbol(context, moduleSymbol), declaration.name.text);
|
|
16
|
+
if (moduleSymbol !== undefined && (0, safe_names_1.isUnsafeName)(moduleSymbol.name)) {
|
|
17
|
+
return lua.createIdentifier((0, safe_names_1.createSafeName)(declaration.name.text), declaration.name, moduleSymbol && (0, symbols_1.getSymbolIdOfSymbol)(context, moduleSymbol), declaration.name.text);
|
|
18
18
|
}
|
|
19
19
|
// TODO: Should synthetic name nodes be escaped as well?
|
|
20
|
-
return identifier_1.transformIdentifier(context, declaration.name);
|
|
20
|
+
return (0, identifier_1.transformIdentifier)(context, declaration.name);
|
|
21
21
|
}
|
|
22
22
|
exports.createModuleLocalNameIdentifier = createModuleLocalNameIdentifier;
|
|
23
23
|
// TODO: Do it based on transform result?
|
|
@@ -37,17 +37,17 @@ function moduleHasEmittedBody(node) {
|
|
|
37
37
|
const currentNamespaces = new WeakMap();
|
|
38
38
|
const transformModuleDeclaration = (node, context) => {
|
|
39
39
|
var _a, _b;
|
|
40
|
-
const annotations = annotations_1.getTypeAnnotations(context.checker.getTypeAtLocation(node));
|
|
40
|
+
const annotations = (0, annotations_1.getTypeAnnotations)(context.checker.getTypeAtLocation(node));
|
|
41
41
|
// If phantom namespace elide the declaration and return the body
|
|
42
42
|
if (annotations.has(annotations_1.AnnotationKind.Phantom)) {
|
|
43
|
-
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.Phantom));
|
|
43
|
+
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.Phantom));
|
|
44
44
|
}
|
|
45
45
|
const currentNamespace = currentNamespaces.get(context);
|
|
46
46
|
const result = [];
|
|
47
47
|
const symbol = context.checker.getSymbolAtLocation(node.name);
|
|
48
48
|
const hasExports = symbol !== undefined && context.checker.getExportsOfModule(symbol).length > 0;
|
|
49
|
-
const nameIdentifier = identifier_1.transformIdentifier(context, node.name);
|
|
50
|
-
const exportScope = export_1.getIdentifierExportScope(context, nameIdentifier);
|
|
49
|
+
const nameIdentifier = (0, identifier_1.transformIdentifier)(context, node.name);
|
|
50
|
+
const exportScope = (0, export_1.getIdentifierExportScope)(context, nameIdentifier);
|
|
51
51
|
// Non-module namespace could be merged if:
|
|
52
52
|
// - is top level
|
|
53
53
|
// - is nested and exported
|
|
@@ -60,17 +60,17 @@ const transformModuleDeclaration = (node, context) => {
|
|
|
60
60
|
ts.getOriginalNode(node) === ((_b = symbol.declarations) === null || _b === void 0 ? void 0 : _b.find(ts.isModuleDeclaration)));
|
|
61
61
|
if (isNonModuleMergeable) {
|
|
62
62
|
// 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}'
|
|
63
|
-
const localDeclaration = lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, nameIdentifier, lua.createBinaryExpression(export_1.addExportToIdentifier(context, nameIdentifier), lua.createTableExpression(), lua.SyntaxKind.OrOperator));
|
|
63
|
+
const localDeclaration = (0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, nameIdentifier, lua.createBinaryExpression((0, export_1.addExportToIdentifier)(context, nameIdentifier), lua.createTableExpression(), lua.SyntaxKind.OrOperator));
|
|
64
64
|
result.push(...localDeclaration);
|
|
65
65
|
}
|
|
66
66
|
else if (isFirstDeclaration) {
|
|
67
67
|
// local NS = {} or exportTable.NS = {}
|
|
68
|
-
const localDeclaration = lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, nameIdentifier, lua.createTableExpression());
|
|
68
|
+
const localDeclaration = (0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, nameIdentifier, lua.createTableExpression());
|
|
69
69
|
result.push(...localDeclaration);
|
|
70
70
|
}
|
|
71
71
|
if ((isNonModuleMergeable || isFirstDeclaration) && exportScope && hasExports && moduleHasEmittedBody(node)) {
|
|
72
72
|
// local NS = exportTable.NS
|
|
73
|
-
const localDeclaration = lua_ast_1.createHoistableVariableDeclarationStatement(context, createModuleLocalNameIdentifier(context, node), export_1.createExportedIdentifier(context, nameIdentifier, exportScope));
|
|
73
|
+
const localDeclaration = (0, lua_ast_1.createHoistableVariableDeclarationStatement)(context, createModuleLocalNameIdentifier(context, node), (0, export_1.createExportedIdentifier)(context, nameIdentifier, exportScope));
|
|
74
74
|
result.push(localDeclaration);
|
|
75
75
|
}
|
|
76
76
|
// Set current namespace for nested NS
|
|
@@ -78,9 +78,9 @@ const transformModuleDeclaration = (node, context) => {
|
|
|
78
78
|
currentNamespaces.set(context, node);
|
|
79
79
|
// Transform moduleblock to block and visit it
|
|
80
80
|
if (moduleHasEmittedBody(node)) {
|
|
81
|
-
scope_1.pushScope(context, scope_1.ScopeType.Block);
|
|
82
|
-
const statements = scope_1.performHoisting(context, context.transformStatements(ts.isModuleBlock(node.body) ? node.body.statements : node.body));
|
|
83
|
-
scope_1.popScope(context);
|
|
81
|
+
(0, scope_1.pushScope)(context, scope_1.ScopeType.Block);
|
|
82
|
+
const statements = (0, scope_1.performHoisting)(context, context.transformStatements(ts.isModuleBlock(node.body) ? node.body.statements : node.body));
|
|
83
|
+
(0, scope_1.popScope)(context);
|
|
84
84
|
result.push(lua.createDoStatement(statements));
|
|
85
85
|
}
|
|
86
86
|
currentNamespaces.set(context, currentNamespace);
|
|
@@ -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
|
|
@@ -3,3 +3,4 @@ import * as lua from "../../LuaAST";
|
|
|
3
3
|
import { FunctionVisitor, TransformationContext } from "../context";
|
|
4
4
|
export declare function transformExpressionBodyToReturnStatement(context: TransformationContext, node: ts.Expression): lua.Statement;
|
|
5
5
|
export declare const transformReturnStatement: FunctionVisitor<ts.ReturnStatement>;
|
|
6
|
+
export declare function createReturnStatement(context: TransformationContext, values: lua.Expression[], node: ts.Node): lua.ReturnStatement;
|
|
@@ -1,6 +1,6 @@
|
|
|
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
6
|
const assignment_validation_1 = require("../utils/assignment-validation");
|
|
@@ -9,65 +9,79 @@ const scope_1 = require("../utils/scope");
|
|
|
9
9
|
const call_1 = require("./call");
|
|
10
10
|
const multi_1 = require("./language-extensions/multi");
|
|
11
11
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
12
|
+
const typescript_1 = require("../utils/typescript");
|
|
12
13
|
function transformExpressionsInReturn(context, node, insideTryCatch) {
|
|
13
14
|
const expressionType = context.checker.getTypeAtLocation(node);
|
|
14
15
|
if (ts.isCallExpression(node)) {
|
|
15
16
|
// $multi(...)
|
|
16
|
-
if (multi_1.isMultiFunctionCall(context, node)) {
|
|
17
|
+
if ((0, multi_1.isMultiFunctionCall)(context, node)) {
|
|
17
18
|
// Don't allow $multi to be implicitly cast to something other than LuaMultiReturn
|
|
18
19
|
const type = context.checker.getContextualType(node);
|
|
19
|
-
if (type && !multi_1.canBeMultiReturnType(type)) {
|
|
20
|
-
context.diagnostics.push(diagnostics_1.invalidMultiFunctionReturnType(node));
|
|
20
|
+
if (type && !(0, multi_1.canBeMultiReturnType)(type)) {
|
|
21
|
+
context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionReturnType)(node));
|
|
21
22
|
}
|
|
22
|
-
let returnValues = call_1.transformArguments(context, node.arguments);
|
|
23
|
+
let returnValues = (0, call_1.transformArguments)(context, node.arguments);
|
|
23
24
|
if (insideTryCatch) {
|
|
24
|
-
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
|
|
25
26
|
}
|
|
26
27
|
return returnValues;
|
|
27
28
|
}
|
|
28
29
|
// Force-wrap LuaMultiReturn when returning inside try/catch
|
|
29
|
-
if (insideTryCatch && multi_1.returnsMultiType(context, node) && !multi_1.shouldMultiReturnCallBeWrapped(context, node)) {
|
|
30
|
-
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))];
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
|
-
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)) {
|
|
34
35
|
// Unpack objects typed as LuaMultiReturn
|
|
35
|
-
return [lua_ast_1.createUnpackCall(context, context.transformExpression(node), node)];
|
|
36
|
+
return [(0, lua_ast_1.createUnpackCall)(context, context.transformExpression(node), node)];
|
|
36
37
|
}
|
|
37
38
|
return [context.transformExpression(node)];
|
|
38
39
|
}
|
|
39
40
|
function transformExpressionBodyToReturnStatement(context, node) {
|
|
40
41
|
const expressions = transformExpressionsInReturn(context, node, false);
|
|
41
|
-
return
|
|
42
|
+
return createReturnStatement(context, expressions, node);
|
|
42
43
|
}
|
|
43
44
|
exports.transformExpressionBodyToReturnStatement = transformExpressionBodyToReturnStatement;
|
|
44
45
|
const transformReturnStatement = (statement, context) => {
|
|
45
|
-
// Bubble up explicit return flag and check if we're inside a try/catch block
|
|
46
|
-
let insideTryCatch = false;
|
|
47
|
-
for (const scope of scope_1.walkScopesUp(context)) {
|
|
48
|
-
scope.functionReturned = true;
|
|
49
|
-
if (scope.type === scope_1.ScopeType.Function) {
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
insideTryCatch = insideTryCatch || scope.type === scope_1.ScopeType.Try || scope.type === scope_1.ScopeType.Catch;
|
|
53
|
-
}
|
|
54
46
|
let results;
|
|
55
47
|
if (statement.expression) {
|
|
56
48
|
const expressionType = context.checker.getTypeAtLocation(statement.expression);
|
|
57
49
|
const returnType = context.checker.getContextualType(statement.expression);
|
|
58
50
|
if (returnType) {
|
|
59
|
-
assignment_validation_1.validateAssignment(context, statement, expressionType, returnType);
|
|
51
|
+
(0, assignment_validation_1.validateAssignment)(context, statement, expressionType, returnType);
|
|
60
52
|
}
|
|
61
|
-
results = transformExpressionsInReturn(context, statement.expression,
|
|
53
|
+
results = transformExpressionsInReturn(context, statement.expression, isInTryCatch(context));
|
|
62
54
|
}
|
|
63
55
|
else {
|
|
64
56
|
// Empty return
|
|
65
57
|
results = [];
|
|
66
58
|
}
|
|
67
|
-
|
|
68
|
-
results.unshift(lua.createBooleanLiteral(true));
|
|
69
|
-
}
|
|
70
|
-
return lua.createReturnStatement(results, statement);
|
|
59
|
+
return createReturnStatement(context, results, statement);
|
|
71
60
|
};
|
|
72
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
|
+
}
|
|
73
87
|
//# sourceMappingURL=return.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) => {
|
|
@@ -14,8 +15,10 @@ const transformSourceFileNode = (node, context) => {
|
|
|
14
15
|
if (node.flags & ts.NodeFlags.JsonFile) {
|
|
15
16
|
const [statement] = node.statements;
|
|
16
17
|
if (statement) {
|
|
17
|
-
utils_1.assert(ts.isExpressionStatement(statement));
|
|
18
|
-
|
|
18
|
+
(0, utils_1.assert)(ts.isExpressionStatement(statement));
|
|
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"), [
|
|
@@ -25,21 +28,21 @@ const transformSourceFileNode = (node, context) => {
|
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
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);
|
|
31
|
+
(0, scope_1.pushScope)(context, scope_1.ScopeType.File);
|
|
32
|
+
statements = (0, scope_1.performHoisting)(context, context.transformStatements(node.statements));
|
|
33
|
+
(0, scope_1.popScope)(context);
|
|
31
34
|
if (context.isModule) {
|
|
32
35
|
// If export equals was not used. Create the exports table.
|
|
33
36
|
// local ____exports = {}
|
|
34
|
-
if (!typescript_1.hasExportEquals(node)) {
|
|
35
|
-
statements.unshift(lua.createVariableDeclarationStatement(lua_ast_1.createExportsIdentifier(), lua.createTableExpression()));
|
|
37
|
+
if (!(0, typescript_1.hasExportEquals)(node)) {
|
|
38
|
+
statements.unshift(lua.createVariableDeclarationStatement((0, lua_ast_1.createExportsIdentifier)(), lua.createTableExpression()));
|
|
36
39
|
}
|
|
37
40
|
// return ____exports
|
|
38
|
-
statements.push(lua.createReturnStatement([lua_ast_1.createExportsIdentifier()]));
|
|
41
|
+
statements.push(lua.createReturnStatement([(0, lua_ast_1.createExportsIdentifier)()]));
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
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);
|
|
45
|
+
return lua.createFile(statements, (0, lualib_1.getUsedLuaLibFeatures)(context), trivia, node);
|
|
43
46
|
};
|
|
44
47
|
exports.transformSourceFileNode = transformSourceFileNode;
|
|
45
48
|
//# sourceMappingURL=sourceFile.js.map
|
|
@@ -17,16 +17,16 @@ function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
|
17
17
|
return false;
|
|
18
18
|
}
|
|
19
19
|
// Walk up, stopping at any scope types which could stop optimization
|
|
20
|
-
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);
|
|
21
21
|
if (!scope) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
// $vararg global constant
|
|
25
|
-
if (vararg_1.isGlobalVarargConstant(context, symbol, scope)) {
|
|
25
|
+
if ((0, vararg_1.isGlobalVarargConstant)(context, symbol, scope)) {
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
28
28
|
// Scope must be a function scope associated with a real ts function
|
|
29
|
-
if (!scope_1.isFunctionScopeWithDefinition(scope)) {
|
|
29
|
+
if (!(0, scope_1.isFunctionScopeWithDefinition)(scope)) {
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
32
|
// Scope cannot be an async function
|
|
@@ -39,11 +39,11 @@ function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
|
39
39
|
return false;
|
|
40
40
|
}
|
|
41
41
|
// De-optimize if already referenced outside of a spread, as the array may have been modified
|
|
42
|
-
if (scope_1.hasReferencedSymbol(context, scope, symbol)) {
|
|
42
|
+
if ((0, scope_1.hasReferencedSymbol)(context, scope, symbol)) {
|
|
43
43
|
return false;
|
|
44
44
|
}
|
|
45
45
|
// De-optimize if a function is being hoisted from below to above, as it may have modified the array
|
|
46
|
-
if (scope_1.hasReferencedUndefinedLocalFunction(context, scope)) {
|
|
46
|
+
if ((0, scope_1.hasReferencedUndefinedLocalFunction)(context, scope)) {
|
|
47
47
|
return false;
|
|
48
48
|
}
|
|
49
49
|
return true;
|
|
@@ -52,8 +52,8 @@ exports.isOptimizedVarArgSpread = isOptimizedVarArgSpread;
|
|
|
52
52
|
// TODO: Currently it's also used as an array member
|
|
53
53
|
const transformSpreadElement = (node, context) => {
|
|
54
54
|
if (ts.isIdentifier(node.expression)) {
|
|
55
|
-
if (annotations_1.isVarargType(context, node.expression)) {
|
|
56
|
-
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));
|
|
57
57
|
}
|
|
58
58
|
const symbol = context.checker.getSymbolAtLocation(node.expression);
|
|
59
59
|
if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) {
|
|
@@ -61,13 +61,13 @@ const transformSpreadElement = (node, context) => {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
const innerExpression = context.transformExpression(node.expression);
|
|
64
|
-
if (multi_1.isMultiReturnCall(context, node.expression))
|
|
64
|
+
if ((0, multi_1.isMultiReturnCall)(context, node.expression))
|
|
65
65
|
return innerExpression;
|
|
66
66
|
const type = context.checker.getTypeAtLocation(node.expression);
|
|
67
|
-
if (typescript_1.isArrayType(context, type)) {
|
|
68
|
-
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);
|
|
69
69
|
}
|
|
70
|
-
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Spread, node, innerExpression);
|
|
70
|
+
return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.Spread, node, innerExpression);
|
|
71
71
|
};
|
|
72
72
|
exports.transformSpreadElement = transformSpreadElement;
|
|
73
73
|
//# sourceMappingURL=spread.js.map
|