typescript-to-lua 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CompilerOptions.d.ts +2 -1
- package/dist/CompilerOptions.js +1 -0
- package/dist/LuaLib.d.ts +4 -0
- package/dist/LuaLib.js +69 -19
- package/dist/LuaPrinter.js +2 -1
- package/dist/lualib/5.0/ArraySlice.lua +2 -10
- package/dist/lualib/5.0/ArraySplice.lua +1 -5
- package/dist/lualib/5.0/ParseFloat.lua +1 -5
- package/dist/lualib/5.0/StringCharCodeAt.lua +1 -5
- package/dist/lualib/5.0/lualib_bundle.lua +5 -25
- package/dist/lualib/universal/ArraySlice.lua +2 -10
- package/dist/lualib/universal/ArraySplice.lua +1 -5
- package/dist/lualib/universal/ParseFloat.lua +1 -5
- package/dist/lualib/universal/SparseArraySpread.lua +1 -5
- package/dist/lualib/universal/StringCharCodeAt.lua +1 -5
- package/dist/lualib/universal/lualib_bundle.lua +6 -30
- package/dist/lualib-build/plugin.js +1 -1
- package/dist/transformation/builtins/array.js +1 -1
- package/dist/transformation/utils/diagnostics.d.ts +6 -0
- package/dist/transformation/utils/diagnostics.js +3 -1
- package/dist/transformation/utils/language-extensions.d.ts +4 -0
- package/dist/transformation/utils/language-extensions.js +66 -1
- package/dist/transformation/utils/preceding-statements.d.ts +5 -1
- package/dist/transformation/utils/preceding-statements.js +1 -1
- package/dist/transformation/utils/typescript/index.d.ts +1 -0
- package/dist/transformation/utils/typescript/index.js +5 -1
- package/dist/transformation/utils/typescript/types.js +0 -3
- package/dist/transformation/visitors/binary-expression/assignments.js +3 -3
- package/dist/transformation/visitors/binary-expression/compound.d.ts +0 -7
- package/dist/transformation/visitors/binary-expression/compound.js +40 -22
- package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +5 -5
- package/dist/transformation/visitors/binary-expression/index.d.ts +3 -2
- package/dist/transformation/visitors/binary-expression/index.js +12 -13
- package/dist/transformation/visitors/call.js +2 -2
- package/dist/transformation/visitors/class/index.js +1 -1
- package/dist/transformation/visitors/class/members/fields.js +1 -1
- package/dist/transformation/visitors/conditional.js +10 -10
- package/dist/transformation/visitors/expression-list.js +1 -1
- package/dist/transformation/visitors/expression-statement.d.ts +2 -2
- package/dist/transformation/visitors/expression-statement.js +4 -5
- package/dist/transformation/visitors/function.js +2 -2
- package/dist/transformation/visitors/identifier.js +3 -1
- package/dist/transformation/visitors/language-extensions/operators.js +9 -15
- package/dist/transformation/visitors/language-extensions/table.d.ts +2 -4
- package/dist/transformation/visitors/language-extensions/table.js +32 -38
- package/dist/transformation/visitors/loops/do-while.js +2 -2
- package/dist/transformation/visitors/loops/for.js +2 -2
- package/dist/transformation/visitors/loops/utils.js +1 -1
- package/dist/transformation/visitors/optional-chaining.d.ts +2 -1
- package/dist/transformation/visitors/optional-chaining.js +79 -33
- package/dist/transformation/visitors/sourceFile.js +1 -1
- package/dist/transformation/visitors/switch.js +15 -6
- package/dist/transformation/visitors/typeof.js +1 -1
- package/dist/transformation/visitors/variable-declaration.js +3 -3
- package/dist/transformation/visitors/void.js +1 -1
- package/dist/transpilation/diagnostics.js +1 -1
- package/dist/transpilation/output-collector.d.ts +1 -1
- package/dist/transpilation/output-collector.js +3 -3
- package/dist/transpilation/resolve.js +19 -10
- package/dist/transpilation/transpiler.d.ts +1 -0
- package/dist/transpilation/transpiler.js +13 -3
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tableExtensionTransformers = exports.tableNewExtensions = exports.isTableNewCall = void 0;
|
|
4
|
-
const ts = require("typescript");
|
|
5
4
|
const lua = require("../../../LuaAST");
|
|
6
5
|
const language_extensions_1 = require("../../utils/language-extensions");
|
|
7
6
|
const expression_list_1 = require("../expression-list");
|
|
@@ -19,62 +18,57 @@ exports.tableExtensionTransformers = {
|
|
|
19
18
|
[language_extensions_1.ExtensionKind.TableHasMethodType]: transformTableHasExpression,
|
|
20
19
|
[language_extensions_1.ExtensionKind.TableSetType]: transformTableSetExpression,
|
|
21
20
|
[language_extensions_1.ExtensionKind.TableSetMethodType]: transformTableSetExpression,
|
|
22
|
-
[language_extensions_1.ExtensionKind.TableAddKeyType]:
|
|
23
|
-
[language_extensions_1.ExtensionKind.TableAddKeyMethodType]:
|
|
21
|
+
[language_extensions_1.ExtensionKind.TableAddKeyType]: transformTableAddKeyExpression,
|
|
22
|
+
[language_extensions_1.ExtensionKind.TableAddKeyMethodType]: transformTableAddKeyExpression,
|
|
24
23
|
};
|
|
25
24
|
function transformTableDeleteExpression(context, node, extensionKind) {
|
|
26
|
-
const args =
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
// In case of method (no table argument), push method owner to front of args list
|
|
30
|
-
args.unshift(node.expression.expression);
|
|
25
|
+
const args = (0, language_extensions_1.getBinaryCallExtensionArgs)(context, node, extensionKind);
|
|
26
|
+
if (!args) {
|
|
27
|
+
return lua.createNilLiteral();
|
|
31
28
|
}
|
|
32
|
-
const [table,
|
|
29
|
+
const [table, key] = (0, expression_list_1.transformOrderedExpressions)(context, args);
|
|
33
30
|
// arg0[arg1] = nil
|
|
34
|
-
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table,
|
|
31
|
+
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createNilLiteral(), node));
|
|
35
32
|
return lua.createBooleanLiteral(true);
|
|
36
33
|
}
|
|
37
|
-
function transformWithTableArgument(context, node) {
|
|
38
|
-
if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) {
|
|
39
|
-
return (0, expression_list_1.transformExpressionList)(context, [node.expression.expression, ...node.arguments]);
|
|
40
|
-
}
|
|
41
|
-
// todo: report diagnostic?
|
|
42
|
-
return [lua.createNilLiteral(), ...(0, expression_list_1.transformExpressionList)(context, node.arguments)];
|
|
43
|
-
}
|
|
44
34
|
function transformTableGetExpression(context, node, extensionKind) {
|
|
45
|
-
const args =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
const args = (0, language_extensions_1.getBinaryCallExtensionArgs)(context, node, extensionKind);
|
|
36
|
+
if (!args) {
|
|
37
|
+
return lua.createNilLiteral();
|
|
38
|
+
}
|
|
39
|
+
const [table, key] = (0, expression_list_1.transformOrderedExpressions)(context, args);
|
|
49
40
|
// arg0[arg1]
|
|
50
|
-
return lua.createTableIndexExpression(table,
|
|
41
|
+
return lua.createTableIndexExpression(table, key, node);
|
|
51
42
|
}
|
|
52
43
|
function transformTableHasExpression(context, node, extensionKind) {
|
|
53
|
-
const args =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
const args = (0, language_extensions_1.getBinaryCallExtensionArgs)(context, node, extensionKind);
|
|
45
|
+
if (!args) {
|
|
46
|
+
return lua.createNilLiteral();
|
|
47
|
+
}
|
|
48
|
+
const [table, key] = (0, expression_list_1.transformOrderedExpressions)(context, args);
|
|
57
49
|
// arg0[arg1]
|
|
58
|
-
const tableIndexExpression = lua.createTableIndexExpression(table,
|
|
50
|
+
const tableIndexExpression = lua.createTableIndexExpression(table, key);
|
|
59
51
|
// arg0[arg1] ~= nil
|
|
60
52
|
return lua.createBinaryExpression(tableIndexExpression, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator, node);
|
|
61
53
|
}
|
|
62
54
|
function transformTableSetExpression(context, node, extensionKind) {
|
|
63
|
-
const args =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
const args = (0, language_extensions_1.getNaryCallExtensionArgs)(context, node, extensionKind, 3);
|
|
56
|
+
if (!args) {
|
|
57
|
+
return lua.createNilLiteral();
|
|
58
|
+
}
|
|
59
|
+
const [table, key, value] = (0, expression_list_1.transformOrderedExpressions)(context, args);
|
|
67
60
|
// arg0[arg1] = arg2
|
|
68
|
-
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table,
|
|
61
|
+
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), value, node));
|
|
69
62
|
return lua.createNilLiteral();
|
|
70
63
|
}
|
|
71
|
-
function
|
|
72
|
-
const args =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
function transformTableAddKeyExpression(context, node, extensionKind) {
|
|
65
|
+
const args = (0, language_extensions_1.getNaryCallExtensionArgs)(context, node, extensionKind, 2);
|
|
66
|
+
if (!args) {
|
|
67
|
+
return lua.createNilLiteral();
|
|
68
|
+
}
|
|
69
|
+
const [table, key] = (0, expression_list_1.transformOrderedExpressions)(context, args);
|
|
76
70
|
// arg0[arg1] = true
|
|
77
|
-
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table,
|
|
71
|
+
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createBooleanLiteral(true), node));
|
|
78
72
|
return lua.createNilLiteral();
|
|
79
73
|
}
|
|
80
74
|
//# sourceMappingURL=table.js.map
|
|
@@ -9,7 +9,7 @@ const transformWhileStatement = (statement, context) => {
|
|
|
9
9
|
// Check if we need to add diagnostic about Lua truthiness
|
|
10
10
|
(0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
|
|
11
11
|
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
12
|
-
let
|
|
12
|
+
let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
13
13
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
14
14
|
//
|
|
15
15
|
// while true do
|
|
@@ -31,7 +31,7 @@ const transformDoStatement = (statement, context) => {
|
|
|
31
31
|
// Check if we need to add diagnostic about Lua truthiness
|
|
32
32
|
(0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
|
|
33
33
|
const body = lua.createDoStatement((0, utils_1.transformLoopBody)(context, statement));
|
|
34
|
-
let
|
|
34
|
+
let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
|
|
35
35
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
36
36
|
//
|
|
37
37
|
// repeat
|
|
@@ -21,9 +21,9 @@ const transformForStatement = (statement, context) => {
|
|
|
21
21
|
const body = (0, utils_1.transformLoopBody)(context, statement);
|
|
22
22
|
let condition;
|
|
23
23
|
if (statement.condition) {
|
|
24
|
-
let conditionPrecedingStatements;
|
|
25
24
|
const tsCondition = statement.condition;
|
|
26
|
-
|
|
25
|
+
const { precedingStatements: conditionPrecedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsCondition));
|
|
26
|
+
condition = result;
|
|
27
27
|
// If condition has preceding statements, ensure they are executed every iteration by using the form:
|
|
28
28
|
//
|
|
29
29
|
// while true do
|
|
@@ -40,7 +40,7 @@ function transformForInitializer(context, initializer, block) {
|
|
|
40
40
|
// Declaration of new variable
|
|
41
41
|
const binding = getVariableDeclarationBinding(context, initializer);
|
|
42
42
|
if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) {
|
|
43
|
-
const
|
|
43
|
+
const { precedingStatements, result: bindings } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, binding, valueVariable));
|
|
44
44
|
block.statements.unshift(...precedingStatements, ...bindings);
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
@@ -8,9 +8,10 @@ export interface ExpressionWithThisValue {
|
|
|
8
8
|
export declare function captureThisValue(context: TransformationContext, expression: lua.Expression, thisValueCapture: lua.Identifier, tsOriginal: ts.Node): lua.Expression;
|
|
9
9
|
export interface OptionalContinuation {
|
|
10
10
|
contextualCall?: lua.CallExpression;
|
|
11
|
+
usedIdentifiers: lua.Identifier[];
|
|
11
12
|
}
|
|
12
13
|
export declare function isOptionalContinuation(node: ts.Node): boolean;
|
|
13
14
|
export declare function getOptionalContinuationData(identifier: ts.Identifier): OptionalContinuation | undefined;
|
|
14
15
|
export declare function transformOptionalChain(context: TransformationContext, node: ts.OptionalChain): lua.Expression;
|
|
15
|
-
export declare function transformOptionalChainWithCapture(context: TransformationContext,
|
|
16
|
+
export declare function transformOptionalChainWithCapture(context: TransformationContext, tsNode: ts.OptionalChain, thisValueCapture: lua.Identifier | undefined, isDelete?: ts.DeleteExpression): ExpressionWithThisValue;
|
|
16
17
|
export declare function transformOptionalDeleteExpression(context: TransformationContext, node: ts.DeleteExpression, innerExpression: ts.OptionalChain): lua.BooleanLiteral;
|
|
@@ -8,6 +8,8 @@ const utils_1 = require("../../utils");
|
|
|
8
8
|
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
9
9
|
const access_1 = require("./access");
|
|
10
10
|
const expression_list_1 = require("./expression-list");
|
|
11
|
+
const typescript_1 = require("../utils/typescript");
|
|
12
|
+
const expression_statement_1 = require("./expression-statement");
|
|
11
13
|
function skipNonNullChains(chain) {
|
|
12
14
|
while (ts.isNonNullChain(chain)) {
|
|
13
15
|
chain = chain.expression;
|
|
@@ -39,7 +41,7 @@ function transformExpressionWithThisValueCapture(context, node, thisValueCapture
|
|
|
39
41
|
}
|
|
40
42
|
// returns thisValueCapture exactly if a temp variable was used.
|
|
41
43
|
function captureThisValue(context, expression, thisValueCapture, tsOriginal) {
|
|
42
|
-
if (!(0, expression_list_1.shouldMoveToTemp)(context, expression, tsOriginal)
|
|
44
|
+
if (!(0, expression_list_1.shouldMoveToTemp)(context, expression, tsOriginal)) {
|
|
43
45
|
return expression;
|
|
44
46
|
}
|
|
45
47
|
const tempAssignment = lua.createAssignmentStatement(thisValueCapture, expression, tsOriginal);
|
|
@@ -52,7 +54,9 @@ const optionalContinuations = new WeakMap();
|
|
|
52
54
|
function createOptionalContinuationIdentifier(text, tsOriginal) {
|
|
53
55
|
const identifier = ts.factory.createIdentifier(text);
|
|
54
56
|
ts.setOriginalNode(identifier, tsOriginal);
|
|
55
|
-
optionalContinuations.set(identifier, {
|
|
57
|
+
optionalContinuations.set(identifier, {
|
|
58
|
+
usedIdentifiers: [],
|
|
59
|
+
});
|
|
56
60
|
return identifier;
|
|
57
61
|
}
|
|
58
62
|
function isOptionalContinuation(node) {
|
|
@@ -67,12 +71,11 @@ function transformOptionalChain(context, node) {
|
|
|
67
71
|
return transformOptionalChainWithCapture(context, node, undefined).expression;
|
|
68
72
|
}
|
|
69
73
|
exports.transformOptionalChain = transformOptionalChain;
|
|
70
|
-
function transformOptionalChainWithCapture(context,
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
const { expression: tsLeftExpression, chain } = flattenChain(node);
|
|
74
|
+
function transformOptionalChainWithCapture(context, tsNode, thisValueCapture, isDelete) {
|
|
75
|
+
const luaTempName = context.createTempName("opt");
|
|
76
|
+
const { expression: tsLeftExpression, chain } = flattenChain(tsNode);
|
|
74
77
|
// build temp.b.c.d
|
|
75
|
-
const tsTemp = createOptionalContinuationIdentifier(
|
|
78
|
+
const tsTemp = createOptionalContinuationIdentifier(luaTempName, tsLeftExpression);
|
|
76
79
|
let tsRightExpression = tsTemp;
|
|
77
80
|
for (const link of chain) {
|
|
78
81
|
if (ts.isPropertyAccessExpression(link)) {
|
|
@@ -96,22 +99,21 @@ function transformOptionalChainWithCapture(context, node, thisValueCapture, isDe
|
|
|
96
99
|
// transform right expression first to check if thisValue capture is needed
|
|
97
100
|
// capture and return thisValue if requested from outside
|
|
98
101
|
let returnThisValue;
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
({ expression: result, thisValue: returnThisValue } = transformExpressionWithThisValueCapture(context, tsRightExpression, thisValueCapture));
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
result = context.transformExpression(tsRightExpression);
|
|
102
|
+
const { precedingStatements: rightPrecedingStatements, result: rightExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
103
|
+
if (!thisValueCapture) {
|
|
104
|
+
return context.transformExpression(tsRightExpression);
|
|
106
105
|
}
|
|
107
|
-
|
|
106
|
+
const { expression: result, thisValue } = transformExpressionWithThisValueCapture(context, tsRightExpression, thisValueCapture);
|
|
107
|
+
returnThisValue = thisValue;
|
|
108
|
+
return result;
|
|
108
109
|
});
|
|
109
110
|
// transform left expression, handle thisValue if needed by rightExpression
|
|
110
111
|
const thisValueCaptureName = context.createTempName("this");
|
|
111
112
|
const leftThisValueTemp = lua.createIdentifier(thisValueCaptureName, undefined, context_1.tempSymbolId);
|
|
112
113
|
let capturedThisValue;
|
|
113
|
-
const
|
|
114
|
-
const
|
|
114
|
+
const optionalContinuationData = getOptionalContinuationData(tsTemp);
|
|
115
|
+
const rightContextualCall = optionalContinuationData === null || optionalContinuationData === void 0 ? void 0 : optionalContinuationData.contextualCall;
|
|
116
|
+
const { precedingStatements: leftPrecedingStatements, result: leftExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
|
|
115
117
|
let result;
|
|
116
118
|
if (rightContextualCall) {
|
|
117
119
|
({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture(context, tsLeftExpression, leftThisValueTemp));
|
|
@@ -146,22 +148,66 @@ function transformOptionalChainWithCapture(context, node, thisValueCapture, isDe
|
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
// evaluate optional chain
|
|
152
|
+
context.addPrecedingStatements(leftPrecedingStatements);
|
|
153
|
+
// try use existing variable instead of creating new one, if possible
|
|
154
|
+
let leftIdentifier;
|
|
155
|
+
const usedLuaIdentifiers = optionalContinuationData === null || optionalContinuationData === void 0 ? void 0 : optionalContinuationData.usedIdentifiers;
|
|
156
|
+
const reuseLeftIdentifier = usedLuaIdentifiers &&
|
|
157
|
+
usedLuaIdentifiers.length > 0 &&
|
|
158
|
+
lua.isIdentifier(leftExpression) &&
|
|
159
|
+
(rightPrecedingStatements.length === 0 || !(0, expression_list_1.shouldMoveToTemp)(context, leftExpression, tsLeftExpression));
|
|
160
|
+
if (reuseLeftIdentifier) {
|
|
161
|
+
leftIdentifier = leftExpression;
|
|
162
|
+
for (const usedIdentifier of usedLuaIdentifiers) {
|
|
163
|
+
usedIdentifier.text = leftIdentifier.text;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
leftIdentifier = lua.createIdentifier(luaTempName, undefined, context_1.tempSymbolId);
|
|
168
|
+
context.addPrecedingStatements(lua.createVariableDeclarationStatement(leftIdentifier, leftExpression));
|
|
169
|
+
}
|
|
170
|
+
if (!(0, typescript_1.expressionResultIsUsed)(tsNode) || isDelete) {
|
|
171
|
+
// if left ~= nil then
|
|
172
|
+
// <right preceding statements>
|
|
173
|
+
// <right expression>
|
|
174
|
+
// end
|
|
175
|
+
const innerExpression = (0, expression_statement_1.wrapInStatement)(rightExpression);
|
|
176
|
+
const innerStatements = rightPrecedingStatements;
|
|
177
|
+
if (innerExpression)
|
|
178
|
+
innerStatements.push(innerExpression);
|
|
179
|
+
context.addPrecedingStatements(lua.createIfStatement(lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), lua.createBlock(innerStatements)));
|
|
180
|
+
return { expression: lua.createNilLiteral(), thisValue: returnThisValue };
|
|
181
|
+
}
|
|
182
|
+
else if (rightPrecedingStatements.length === 0 &&
|
|
183
|
+
!(0, typescript_1.canBeFalsyWhenNotNull)(context, context.checker.getTypeAtLocation(tsLeftExpression))) {
|
|
184
|
+
// return a && a.b
|
|
185
|
+
return {
|
|
186
|
+
expression: lua.createBinaryExpression(leftIdentifier, rightExpression, lua.SyntaxKind.AndOperator, tsNode),
|
|
187
|
+
thisValue: returnThisValue,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
let resultIdentifier;
|
|
192
|
+
if (!reuseLeftIdentifier) {
|
|
193
|
+
// reuse temp variable for output
|
|
194
|
+
resultIdentifier = leftIdentifier;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
resultIdentifier = lua.createIdentifier(context.createTempName("opt_result"), undefined, context_1.tempSymbolId);
|
|
198
|
+
context.addPrecedingStatements(lua.createVariableDeclarationStatement(resultIdentifier));
|
|
199
|
+
}
|
|
200
|
+
// if left ~= nil then
|
|
201
|
+
// <right preceding statements>
|
|
202
|
+
// result = <right expression>
|
|
203
|
+
// end
|
|
204
|
+
// return result
|
|
205
|
+
context.addPrecedingStatements(lua.createIfStatement(lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), lua.createBlock([
|
|
206
|
+
...rightPrecedingStatements,
|
|
207
|
+
lua.createAssignmentStatement(resultIdentifier, rightExpression),
|
|
208
|
+
])));
|
|
209
|
+
return { expression: resultIdentifier, thisValue: returnThisValue };
|
|
210
|
+
}
|
|
165
211
|
}
|
|
166
212
|
exports.transformOptionalChainWithCapture = transformOptionalChainWithCapture;
|
|
167
213
|
function transformOptionalDeleteExpression(context, node, innerExpression) {
|
|
@@ -15,7 +15,7 @@ const transformSourceFileNode = (node, context) => {
|
|
|
15
15
|
const [statement] = node.statements;
|
|
16
16
|
if (statement) {
|
|
17
17
|
(0, utils_1.assert)(ts.isExpressionStatement(statement));
|
|
18
|
-
const
|
|
18
|
+
const { precedingStatements, result: expression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
|
|
19
19
|
statements.push(...precedingStatements);
|
|
20
20
|
statements.push(lua.createReturnStatement([expression]));
|
|
21
21
|
}
|
|
@@ -25,18 +25,21 @@ const createOrExpression = (context, left, right, rightPrecedingStatements) => {
|
|
|
25
25
|
return (0, binary_expression_1.createShortCircuitBinaryExpressionPrecedingStatements)(context, left, right, rightPrecedingStatements, ts.SyntaxKind.BarBarToken);
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
precedingStatements: rightPrecedingStatements,
|
|
30
|
+
result: lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator),
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
};
|
|
31
34
|
const coalesceCondition = (condition, conditionPrecedingStatements, switchVariable, expression, context) => {
|
|
32
|
-
const
|
|
35
|
+
const { precedingStatements, result: transformedExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
|
|
33
36
|
// Coalesce skipped statements
|
|
34
37
|
const comparison = lua.createBinaryExpression(switchVariable, transformedExpression, lua.SyntaxKind.EqualityOperator);
|
|
35
38
|
if (condition) {
|
|
36
39
|
return createOrExpression(context, condition, comparison, precedingStatements);
|
|
37
40
|
}
|
|
38
41
|
// Next condition
|
|
39
|
-
return [
|
|
42
|
+
return { precedingStatements: [...conditionPrecedingStatements, ...precedingStatements], result: comparison };
|
|
40
43
|
};
|
|
41
44
|
const transformSwitchStatement = (statement, context) => {
|
|
42
45
|
const scope = context.pushScope(scope_1.ScopeType.Switch);
|
|
@@ -77,7 +80,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
77
80
|
}
|
|
78
81
|
// Compute the condition for the if statement
|
|
79
82
|
if (!ts.isDefaultClause(clause)) {
|
|
80
|
-
|
|
83
|
+
const { precedingStatements, result } = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
|
|
84
|
+
conditionPrecedingStatements = precedingStatements;
|
|
85
|
+
condition = result;
|
|
81
86
|
// Skip empty clauses unless final clause (i.e side-effects)
|
|
82
87
|
if (i !== clauses.length - 1 && clause.statements.length === 0)
|
|
83
88
|
continue;
|
|
@@ -86,7 +91,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
86
91
|
statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition));
|
|
87
92
|
}
|
|
88
93
|
else {
|
|
89
|
-
|
|
94
|
+
const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
95
|
+
conditionPrecedingStatements = precedingStatements;
|
|
96
|
+
condition = result;
|
|
90
97
|
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
91
98
|
}
|
|
92
99
|
isInitialCondition = false;
|
|
@@ -104,7 +111,9 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
104
111
|
if (i === clauses.length - 1) {
|
|
105
112
|
// Evaluate the final condition that we may be skipping
|
|
106
113
|
if (condition) {
|
|
107
|
-
|
|
114
|
+
const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
|
|
115
|
+
conditionPrecedingStatements = precedingStatements;
|
|
116
|
+
condition = result;
|
|
108
117
|
statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
|
|
109
118
|
}
|
|
110
119
|
continue;
|
|
@@ -43,7 +43,7 @@ function transformTypeOfBinaryExpression(context, node) {
|
|
|
43
43
|
}
|
|
44
44
|
const innerExpression = context.transformExpression(typeOfExpression.expression);
|
|
45
45
|
const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression);
|
|
46
|
-
const
|
|
46
|
+
const { precedingStatements, result } = (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, [], operator, node);
|
|
47
47
|
context.addPrecedingStatements(precedingStatements);
|
|
48
48
|
return result;
|
|
49
49
|
}
|
|
@@ -61,7 +61,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
|
|
|
61
61
|
const variableName = (0, identifier_1.transformIdentifier)(context, element.name);
|
|
62
62
|
// The field to extract
|
|
63
63
|
const elementName = (_a = element.propertyName) !== null && _a !== void 0 ? _a : element.name;
|
|
64
|
-
const
|
|
64
|
+
const { precedingStatements, result: propertyName } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, literal_1.transformPropertyName)(context, elementName));
|
|
65
65
|
result.push(...precedingStatements); // Keep property's preceding statements in order
|
|
66
66
|
let expression;
|
|
67
67
|
if (element.dotDotDotToken) {
|
|
@@ -101,7 +101,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
|
|
|
101
101
|
if (element.initializer) {
|
|
102
102
|
const identifier = (0, export_1.addExportToIdentifier)(context, variableName);
|
|
103
103
|
const tsInitializer = element.initializer;
|
|
104
|
-
const
|
|
104
|
+
const { precedingStatements: initializerPrecedingStatements, result: initializer } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsInitializer));
|
|
105
105
|
result.push(lua.createIfStatement(lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([
|
|
106
106
|
...initializerPrecedingStatements,
|
|
107
107
|
lua.createAssignmentStatement(identifier, initializer),
|
|
@@ -124,7 +124,7 @@ function transformBindingVariableDeclaration(context, bindingPattern, initialize
|
|
|
124
124
|
if ((0, multi_1.isMultiReturnCall)(context, initializer)) {
|
|
125
125
|
expression = (0, lua_ast_1.wrapInTable)(expression);
|
|
126
126
|
}
|
|
127
|
-
const
|
|
127
|
+
const { precedingStatements: moveStatements, result: movedExpr } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.moveToPrecedingTemp)(context, expression, initializer));
|
|
128
128
|
statements.push(...moveStatements);
|
|
129
129
|
table = movedExpr;
|
|
130
130
|
}
|
|
@@ -8,7 +8,7 @@ const expression_statement_1 = require("./expression-statement");
|
|
|
8
8
|
const transformVoidExpression = (node, context) => {
|
|
9
9
|
// If content is a literal it is safe to replace the entire expression with nil
|
|
10
10
|
if (!ts.isLiteralExpression(node.expression)) {
|
|
11
|
-
const statements = (0, expression_statement_1.
|
|
11
|
+
const statements = (0, expression_statement_1.wrapInStatement)(context.transformExpression(node.expression));
|
|
12
12
|
if (statements)
|
|
13
13
|
context.addPrecedingStatements(statements);
|
|
14
14
|
}
|
|
@@ -17,7 +17,7 @@ exports.usingLuaBundleWithInlineMightGenerateDuplicateCode = (0, utils_1.createS
|
|
|
17
17
|
messageText: "Using 'luaBundle' with 'luaLibImport: \"inline\"' might generate duplicate code. " +
|
|
18
18
|
"It is recommended to use 'luaLibImport: \"require\"'.",
|
|
19
19
|
}));
|
|
20
|
-
exports.cannotBundleLibrary = createDiagnosticFactory(() => 'Cannot bundle
|
|
20
|
+
exports.cannotBundleLibrary = createDiagnosticFactory(() => 'Cannot bundle projects with "buildmode": "library". Projects including the library can still bundle (which will include external library files).');
|
|
21
21
|
exports.unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.');
|
|
22
22
|
exports.pathsWithoutBaseUrl = createDiagnosticFactory(() => "When configuring 'paths' in tsconfig.json, the option 'baseUrl' must also be provided.");
|
|
23
23
|
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -7,7 +7,7 @@ export interface TranspiledFile {
|
|
|
7
7
|
declaration?: string;
|
|
8
8
|
declarationMap?: string;
|
|
9
9
|
}
|
|
10
|
-
export declare function createEmitOutputCollector(): {
|
|
10
|
+
export declare function createEmitOutputCollector(luaExtension?: string): {
|
|
11
11
|
writeFile: ts.WriteFileCallback;
|
|
12
12
|
files: TranspiledFile[];
|
|
13
13
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createEmitOutputCollector = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
function createEmitOutputCollector() {
|
|
5
|
+
function createEmitOutputCollector(luaExtension = ".lua") {
|
|
6
6
|
const files = [];
|
|
7
7
|
const writeFile = (fileName, data, _bom, _onError, sourceFiles = []) => {
|
|
8
8
|
let file = files.find(f => (0, utils_1.intersection)(f.sourceFiles, sourceFiles).length > 0);
|
|
@@ -13,10 +13,10 @@ function createEmitOutputCollector() {
|
|
|
13
13
|
else {
|
|
14
14
|
file.sourceFiles = (0, utils_1.union)(file.sourceFiles, sourceFiles);
|
|
15
15
|
}
|
|
16
|
-
if (fileName.endsWith(
|
|
16
|
+
if (fileName.endsWith(luaExtension)) {
|
|
17
17
|
file.lua = data;
|
|
18
18
|
}
|
|
19
|
-
else if (fileName.endsWith(
|
|
19
|
+
else if (fileName.endsWith(`${luaExtension}.map`)) {
|
|
20
20
|
file.luaSourceMap = data;
|
|
21
21
|
}
|
|
22
22
|
else if (fileName.endsWith(".js")) {
|
|
@@ -15,6 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({
|
|
|
15
15
|
enforceExtension: true,
|
|
16
16
|
fileSystem: { ...new resolve.CachedInputFileSystem(fs) },
|
|
17
17
|
useSyncFileSystemCalls: true,
|
|
18
|
+
conditionNames: ["require", "node", "tstl", "default"],
|
|
18
19
|
symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection)
|
|
19
20
|
});
|
|
20
21
|
class ResolutionContext {
|
|
@@ -40,8 +41,8 @@ class ResolutionContext {
|
|
|
40
41
|
// Remove @NoResolution prefix if not building in library mode
|
|
41
42
|
if (!isBuildModeLibrary(this.program)) {
|
|
42
43
|
const path = required.requirePath.replace("@NoResolution:", "");
|
|
43
|
-
replaceRequireInCode(file, required, path);
|
|
44
|
-
replaceRequireInSourceMap(file, required, path);
|
|
44
|
+
replaceRequireInCode(file, required, path, this.options.extension);
|
|
45
|
+
replaceRequireInSourceMap(file, required, path, this.options.extension);
|
|
45
46
|
}
|
|
46
47
|
// Skip
|
|
47
48
|
continue;
|
|
@@ -72,8 +73,8 @@ class ResolutionContext {
|
|
|
72
73
|
// Figure out resolved require path and dependency output path
|
|
73
74
|
if (shouldRewriteRequires(dependencyPath, this.program)) {
|
|
74
75
|
const resolvedRequire = (0, transpiler_1.getEmitPathRelativeToOutDir)(dependencyPath, this.program);
|
|
75
|
-
replaceRequireInCode(file, required, resolvedRequire);
|
|
76
|
-
replaceRequireInSourceMap(file, required, resolvedRequire);
|
|
76
|
+
replaceRequireInCode(file, required, resolvedRequire, this.options.extension);
|
|
77
|
+
replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension);
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
processDependency(dependencyPath) {
|
|
@@ -96,8 +97,8 @@ class ResolutionContext {
|
|
|
96
97
|
}
|
|
97
98
|
couldNotResolveImport(required, file) {
|
|
98
99
|
const fallbackRequire = fallbackResolve(required, (0, transpiler_1.getSourceDir)(this.program), path.dirname(file.fileName));
|
|
99
|
-
replaceRequireInCode(file, required, fallbackRequire);
|
|
100
|
-
replaceRequireInSourceMap(file, required, fallbackRequire);
|
|
100
|
+
replaceRequireInCode(file, required, fallbackRequire, this.options.extension);
|
|
101
|
+
replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension);
|
|
101
102
|
this.diagnostics.push((0, diagnostics_1.couldNotResolveRequire)(required.requirePath, path.relative((0, transpiler_1.getProjectRoot)(this.program), file.fileName)));
|
|
102
103
|
}
|
|
103
104
|
resolveDependencyPath(requiringFile, dependency) {
|
|
@@ -263,19 +264,27 @@ function shouldIncludeDependency(resolvedDependency, program) {
|
|
|
263
264
|
function isBuildModeLibrary(program) {
|
|
264
265
|
return program.getCompilerOptions().buildMode === CompilerOptions_1.BuildMode.Library;
|
|
265
266
|
}
|
|
266
|
-
function replaceRequireInCode(file, originalRequire, newRequire) {
|
|
267
|
-
const requirePath = (
|
|
267
|
+
function replaceRequireInCode(file, originalRequire, newRequire, extension) {
|
|
268
|
+
const requirePath = requirePathForFile(newRequire, extension);
|
|
268
269
|
file.code = file.code =
|
|
269
270
|
file.code.substring(0, originalRequire.from) +
|
|
270
271
|
`require("${requirePath}")` +
|
|
271
272
|
file.code.substring(originalRequire.to + 1);
|
|
272
273
|
}
|
|
273
|
-
function replaceRequireInSourceMap(file, originalRequire, newRequire) {
|
|
274
|
-
const requirePath = (
|
|
274
|
+
function replaceRequireInSourceMap(file, originalRequire, newRequire, extension) {
|
|
275
|
+
const requirePath = requirePathForFile(newRequire, extension);
|
|
275
276
|
if (file.sourceMapNode) {
|
|
276
277
|
replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire.requirePath}"`, `"${requirePath}"`);
|
|
277
278
|
}
|
|
278
279
|
}
|
|
280
|
+
function requirePathForFile(filePath, extension = ".lua") {
|
|
281
|
+
if (filePath.endsWith(extension)) {
|
|
282
|
+
return (0, utils_1.formatPathToLuaPath)(filePath.substring(0, filePath.length - extension.length));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
return (0, utils_1.formatPathToLuaPath)(filePath);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
279
288
|
function replaceInSourceMap(node, parent, require, resolvedRequire) {
|
|
280
289
|
if ((!node.children || node.children.length === 0) && node.toString() === require) {
|
|
281
290
|
parent.children = [new source_map_1.SourceNode(node.line, node.column, node.source, [resolvedRequire])];
|
|
@@ -19,6 +19,7 @@ export declare class Transpiler {
|
|
|
19
19
|
protected getEmitPlan(program: ts.Program, diagnostics: ts.Diagnostic[], files: ProcessedFile[]): {
|
|
20
20
|
emitPlan: EmitFile[];
|
|
21
21
|
};
|
|
22
|
+
private getLuaLibBundleContent;
|
|
22
23
|
}
|
|
23
24
|
export declare function getEmitPath(file: string, program: ts.Program): string;
|
|
24
25
|
export declare function getEmitPathRelativeToOutDir(fileName: string, program: ts.Program): string;
|
|
@@ -61,7 +61,6 @@ class Transpiler {
|
|
|
61
61
|
return diagnostics;
|
|
62
62
|
}
|
|
63
63
|
getEmitPlan(program, diagnostics, files) {
|
|
64
|
-
var _a;
|
|
65
64
|
performance.startSection("getEmitPlan");
|
|
66
65
|
const options = program.getCompilerOptions();
|
|
67
66
|
if (options.tstlVerbose) {
|
|
@@ -79,8 +78,8 @@ class Transpiler {
|
|
|
79
78
|
}
|
|
80
79
|
// Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan
|
|
81
80
|
const fileName = (0, utils_1.normalizeSlashes)(path.resolve(getSourceDir(program), "lualib_bundle.lua"));
|
|
82
|
-
const
|
|
83
|
-
resolutionResult.resolvedFiles.unshift({ fileName, code
|
|
81
|
+
const code = this.getLuaLibBundleContent(options, resolutionResult.resolvedFiles);
|
|
82
|
+
resolutionResult.resolvedFiles.unshift({ fileName, code });
|
|
84
83
|
}
|
|
85
84
|
let emitPlan;
|
|
86
85
|
if ((0, CompilerOptions_1.isBundleEnabled)(options)) {
|
|
@@ -97,6 +96,17 @@ class Transpiler {
|
|
|
97
96
|
performance.endSection("getEmitPlan");
|
|
98
97
|
return { emitPlan };
|
|
99
98
|
}
|
|
99
|
+
getLuaLibBundleContent(options, resolvedFiles) {
|
|
100
|
+
var _a;
|
|
101
|
+
const luaTarget = (_a = options.luaTarget) !== null && _a !== void 0 ? _a : CompilerOptions_1.LuaTarget.Universal;
|
|
102
|
+
if (options.luaLibImport === CompilerOptions_1.LuaLibImportKind.RequireMinimal) {
|
|
103
|
+
const usedFeatures = (0, LuaLib_1.findUsedLualibFeatures)(luaTarget, this.emitHost, resolvedFiles.map(f => f.code));
|
|
104
|
+
return (0, LuaLib_1.buildMinimalLualibBundle)(usedFeatures, luaTarget, this.emitHost);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
return (0, LuaLib_1.getLuaLibBundle)(luaTarget, this.emitHost);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
100
110
|
}
|
|
101
111
|
exports.Transpiler = Transpiler;
|
|
102
112
|
function getEmitPath(file, program) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typescript-to-lua",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
|
|
5
5
|
"repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
|
|
6
6
|
"homepage": "https://typescripttolua.github.io/",
|