typescript-to-lua 1.2.0 → 1.3.3
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 +12 -0
- package/dist/LuaLib.d.ts +1 -0
- package/dist/LuaLib.js +2 -1
- package/dist/LuaPrinter.js +4 -4
- package/dist/lualib/Await.lua +7 -3
- package/dist/lualib/CloneDescriptor.lua +6 -6
- package/dist/lualib/MathSign.lua +8 -0
- package/dist/lualib/Promise.lua +10 -2
- package/dist/lualib/lualib_bundle.lua +226 -205
- package/dist/transformation/builtins/function.js +5 -2
- package/dist/transformation/builtins/index.js +9 -7
- package/dist/transformation/builtins/math.js +7 -1
- package/dist/transformation/utils/diagnostics.d.ts +3 -6
- package/dist/transformation/utils/diagnostics.js +2 -3
- package/dist/transformation/utils/language-extensions.d.ts +2 -0
- package/dist/transformation/utils/language-extensions.js +7 -1
- package/dist/transformation/utils/lua-ast.js +5 -5
- package/dist/transformation/utils/safe-names.d.ts +4 -2
- package/dist/transformation/utils/safe-names.js +11 -5
- package/dist/transformation/utils/scope.d.ts +2 -1
- package/dist/transformation/utils/scope.js +1 -0
- package/dist/transformation/utils/typescript/types.d.ts +3 -1
- package/dist/transformation/utils/typescript/types.js +40 -13
- package/dist/transformation/visitors/binary-expression/index.js +1 -3
- package/dist/transformation/visitors/call.js +7 -40
- package/dist/transformation/visitors/class/index.js +1 -1
- package/dist/transformation/visitors/class/members/fields.js +12 -8
- package/dist/transformation/visitors/conditional.js +2 -23
- package/dist/transformation/visitors/errors.js +11 -9
- package/dist/transformation/visitors/expression-statement.d.ts +3 -1
- package/dist/transformation/visitors/expression-statement.js +21 -19
- package/dist/transformation/visitors/function.d.ts +2 -0
- package/dist/transformation/visitors/function.js +58 -6
- package/dist/transformation/visitors/identifier.js +2 -1
- package/dist/transformation/visitors/language-extensions/index.d.ts +4 -0
- package/dist/transformation/visitors/language-extensions/index.js +17 -0
- package/dist/transformation/visitors/language-extensions/operators.d.ts +1 -1
- package/dist/transformation/visitors/language-extensions/operators.js +7 -2
- package/dist/transformation/visitors/language-extensions/pairsIterable.d.ts +5 -0
- package/dist/transformation/visitors/language-extensions/pairsIterable.js +53 -0
- package/dist/transformation/visitors/language-extensions/table.d.ts +1 -8
- package/dist/transformation/visitors/language-extensions/table.js +55 -53
- package/dist/transformation/visitors/loops/for-of.js +4 -0
- package/dist/transformation/visitors/loops/utils.js +6 -1
- package/dist/transformation/visitors/namespace.js +1 -1
- package/dist/transformation/visitors/spread.js +14 -7
- package/dist/transformation/visitors/variable-declaration.js +16 -1
- package/dist/transformation/visitors/void.d.ts +1 -4
- package/dist/transformation/visitors/void.js +6 -8
- package/language-extensions/index.d.ts +11 -1
- package/package.json +1 -1
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformExpressionStatement = void 0;
|
|
4
|
-
const ts = require("typescript");
|
|
3
|
+
exports.transformExpressionToStatement = exports.transformExpressionStatement = void 0;
|
|
5
4
|
const lua = require("../../LuaAST");
|
|
5
|
+
const context_1 = require("../context");
|
|
6
6
|
const binary_expression_1 = require("./binary-expression");
|
|
7
|
-
const table_1 = require("./language-extensions/table");
|
|
8
7
|
const unary_expression_1 = require("./unary-expression");
|
|
9
|
-
const void_1 = require("./void");
|
|
10
8
|
const transformExpressionStatement = (node, context) => {
|
|
11
|
-
const expression = node.expression;
|
|
12
|
-
if (ts.isCallExpression(expression) && (0, table_1.isTableDeleteCall)(context, expression)) {
|
|
13
|
-
return (0, table_1.transformTableDeleteExpression)(context, expression);
|
|
14
|
-
}
|
|
15
|
-
if (ts.isCallExpression(expression) && (0, table_1.isTableSetCall)(context, expression)) {
|
|
16
|
-
return (0, table_1.transformTableSetExpression)(context, expression);
|
|
17
|
-
}
|
|
18
|
-
if (ts.isVoidExpression(expression)) {
|
|
19
|
-
return (0, void_1.transformVoidExpressionStatement)(expression, context);
|
|
20
|
-
}
|
|
21
9
|
const unaryExpressionResult = (0, unary_expression_1.transformUnaryExpressionStatement)(context, node);
|
|
22
10
|
if (unaryExpressionResult) {
|
|
23
11
|
return unaryExpressionResult;
|
|
@@ -26,11 +14,25 @@ const transformExpressionStatement = (node, context) => {
|
|
|
26
14
|
if (binaryExpressionResult) {
|
|
27
15
|
return binaryExpressionResult;
|
|
28
16
|
}
|
|
29
|
-
|
|
30
|
-
return lua.isCallExpression(result) || lua.isMethodCallExpression(result)
|
|
31
|
-
? lua.createExpressionStatement(result)
|
|
32
|
-
: // Assign expression statements to dummy to make sure they're legal Lua
|
|
33
|
-
lua.createVariableDeclarationStatement(lua.createAnonymousIdentifier(), result);
|
|
17
|
+
return transformExpressionToStatement(context, node.expression);
|
|
34
18
|
};
|
|
35
19
|
exports.transformExpressionStatement = transformExpressionStatement;
|
|
20
|
+
function transformExpressionToStatement(context, expression) {
|
|
21
|
+
const result = context.transformExpression(expression);
|
|
22
|
+
const isTempVariable = lua.isIdentifier(result) && result.symbolId === context_1.tempSymbolId;
|
|
23
|
+
if (isTempVariable) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
// "synthetic": no side effects and no original source
|
|
27
|
+
const isSyntheticExpression = (lua.isIdentifier(result) || lua.isLiteral(result)) && result.line === undefined;
|
|
28
|
+
if (isSyntheticExpression) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
if (lua.isCallExpression(result) || lua.isMethodCallExpression(result)) {
|
|
32
|
+
return lua.createExpressionStatement(result);
|
|
33
|
+
}
|
|
34
|
+
// Assign expression statements to dummy to make sure they're legal Lua
|
|
35
|
+
return lua.createVariableDeclarationStatement(lua.createAnonymousIdentifier(), result);
|
|
36
|
+
}
|
|
37
|
+
exports.transformExpressionToStatement = transformExpressionToStatement;
|
|
36
38
|
//# sourceMappingURL=expression-statement.js.map
|
|
@@ -2,6 +2,8 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as lua from "../../LuaAST";
|
|
3
3
|
import { FunctionVisitor, TransformationContext } from "../context";
|
|
4
4
|
import { Scope } from "../utils/scope";
|
|
5
|
+
export declare function createCallableTable(functionExpression: lua.Expression): lua.Expression;
|
|
6
|
+
export declare function isFunctionTypeWithProperties(functionType: ts.Type): boolean;
|
|
5
7
|
export declare function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[];
|
|
6
8
|
export declare function transformFunctionBodyHeader(context: TransformationContext, bodyScope: Scope, parameters: ts.NodeArray<ts.ParameterDeclaration>, spreadIdentifier?: lua.Identifier): lua.Statement[];
|
|
7
9
|
export declare function transformFunctionBody(context: TransformationContext, parameters: ts.NodeArray<ts.ParameterDeclaration>, body: ts.ConciseBody, spreadIdentifier?: lua.Identifier, node?: ts.FunctionLikeDeclaration): [lua.Statement[], Scope];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformYieldExpression = exports.transformFunctionDeclaration = exports.transformFunctionLikeDeclaration = exports.transformFunctionToExpression = exports.transformParameters = exports.transformFunctionBody = exports.transformFunctionBodyHeader = exports.transformFunctionBodyContent = void 0;
|
|
3
|
+
exports.transformYieldExpression = exports.transformFunctionDeclaration = exports.transformFunctionLikeDeclaration = exports.transformFunctionToExpression = exports.transformParameters = exports.transformFunctionBody = exports.transformFunctionBodyHeader = exports.transformFunctionBodyContent = exports.isFunctionTypeWithProperties = exports.createCallableTable = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
@@ -8,10 +8,12 @@ const annotations_1 = require("../utils/annotations");
|
|
|
8
8
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
9
9
|
const export_1 = require("../utils/export");
|
|
10
10
|
const function_context_1 = require("../utils/function-context");
|
|
11
|
+
const language_extensions_1 = require("../utils/language-extensions");
|
|
11
12
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
12
13
|
const lualib_1 = require("../utils/lualib");
|
|
13
14
|
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
14
15
|
const scope_1 = require("../utils/scope");
|
|
16
|
+
const typescript_1 = require("../utils/typescript");
|
|
15
17
|
const async_await_1 = require("./async-await");
|
|
16
18
|
const identifier_1 = require("./identifier");
|
|
17
19
|
const return_1 = require("./return");
|
|
@@ -33,6 +35,39 @@ function isRestParameterReferenced(identifier, scope) {
|
|
|
33
35
|
const references = scope.referencedSymbols.get(identifier.symbolId);
|
|
34
36
|
return references !== undefined && references.length > 0;
|
|
35
37
|
}
|
|
38
|
+
function createCallableTable(functionExpression) {
|
|
39
|
+
var _a;
|
|
40
|
+
// __call metamethod receives the table as the first argument, so we need to add a dummy parameter
|
|
41
|
+
if (lua.isFunctionExpression(functionExpression)) {
|
|
42
|
+
(_a = functionExpression.params) === null || _a === void 0 ? void 0 : _a.unshift(lua.createAnonymousIdentifier());
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// functionExpression may have been replaced (lib functions, etc...),
|
|
46
|
+
// so we create a forwarding function to eat the extra argument
|
|
47
|
+
functionExpression = lua.createFunctionExpression(lua.createBlock([
|
|
48
|
+
lua.createReturnStatement([lua.createCallExpression(functionExpression, [lua.createDotsLiteral()])]),
|
|
49
|
+
]), [lua.createAnonymousIdentifier()], lua.createDotsLiteral(), lua.FunctionExpressionFlags.Inline);
|
|
50
|
+
}
|
|
51
|
+
return lua.createCallExpression(lua.createIdentifier("setmetatable"), [
|
|
52
|
+
lua.createTableExpression(),
|
|
53
|
+
lua.createTableExpression([
|
|
54
|
+
lua.createTableFieldExpression(functionExpression, lua.createStringLiteral("__call")),
|
|
55
|
+
]),
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
exports.createCallableTable = createCallableTable;
|
|
59
|
+
function isFunctionTypeWithProperties(functionType) {
|
|
60
|
+
if (functionType.isUnion()) {
|
|
61
|
+
return functionType.types.some(isFunctionTypeWithProperties);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return ((0, typescript_1.isFunctionType)(functionType) &&
|
|
65
|
+
functionType.getProperties().length > 0 &&
|
|
66
|
+
(0, language_extensions_1.getExtensionKinds)(functionType).length === 0 // ignore TSTL extension functions like $range
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.isFunctionTypeWithProperties = isFunctionTypeWithProperties;
|
|
36
71
|
function transformFunctionBodyContent(context, body) {
|
|
37
72
|
if (!ts.isBlock(body)) {
|
|
38
73
|
const [precedingStatements, returnStatement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, return_1.transformExpressionBodyToReturnStatement)(context, body));
|
|
@@ -55,7 +90,9 @@ function transformFunctionBodyHeader(context, bodyScope, parameters, spreadIdent
|
|
|
55
90
|
headerStatements.push(transformParameterDefaultValueDeclaration(context, identifier, declaration.initializer));
|
|
56
91
|
}
|
|
57
92
|
// Binding pattern
|
|
58
|
-
|
|
93
|
+
const name = declaration.name;
|
|
94
|
+
const [precedingStatements, bindings] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, name, identifier));
|
|
95
|
+
bindingPatternDeclarations.push(...precedingStatements, ...bindings);
|
|
59
96
|
}
|
|
60
97
|
else if (declaration.initializer !== undefined) {
|
|
61
98
|
// Default parameter
|
|
@@ -158,8 +195,9 @@ function transformFunctionLikeDeclaration(node, context) {
|
|
|
158
195
|
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.TupleReturn));
|
|
159
196
|
}
|
|
160
197
|
const [functionExpression, functionScope] = transformFunctionToExpression(context, node);
|
|
198
|
+
const isNamedFunctionExpression = ts.isFunctionExpression(node) && node.name;
|
|
161
199
|
// Handle named function expressions which reference themselves
|
|
162
|
-
if (
|
|
200
|
+
if (isNamedFunctionExpression && functionScope.referencedSymbols) {
|
|
163
201
|
const symbol = context.checker.getSymbolAtLocation(node.name);
|
|
164
202
|
if (symbol) {
|
|
165
203
|
// TODO: Not using symbol ids because of https://github.com/microsoft/TypeScript/issues/37131
|
|
@@ -167,12 +205,22 @@ function transformFunctionLikeDeclaration(node, context) {
|
|
|
167
205
|
// Only handle if the name is actually referenced inside the function
|
|
168
206
|
if (isReferenced) {
|
|
169
207
|
const nameIdentifier = (0, identifier_1.transformIdentifier)(context, node.name);
|
|
170
|
-
context.
|
|
208
|
+
if (isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))) {
|
|
209
|
+
context.addPrecedingStatements([
|
|
210
|
+
lua.createVariableDeclarationStatement(nameIdentifier),
|
|
211
|
+
lua.createAssignmentStatement(nameIdentifier, createCallableTable(functionExpression)),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
context.addPrecedingStatements(lua.createVariableDeclarationStatement(nameIdentifier, functionExpression));
|
|
216
|
+
}
|
|
171
217
|
return lua.cloneIdentifier(nameIdentifier);
|
|
172
218
|
}
|
|
173
219
|
}
|
|
174
220
|
}
|
|
175
|
-
return
|
|
221
|
+
return isNamedFunctionExpression && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))
|
|
222
|
+
? createCallableTable(functionExpression)
|
|
223
|
+
: functionExpression;
|
|
176
224
|
}
|
|
177
225
|
exports.transformFunctionLikeDeclaration = transformFunctionLikeDeclaration;
|
|
178
226
|
const transformFunctionDeclaration = (node, context) => {
|
|
@@ -199,7 +247,11 @@ const transformFunctionDeclaration = (node, context) => {
|
|
|
199
247
|
const functionInfo = { referencedSymbols: (_a = functionScope.referencedSymbols) !== null && _a !== void 0 ? _a : new Map() };
|
|
200
248
|
scope.functionDefinitions.set(name.symbolId, functionInfo);
|
|
201
249
|
}
|
|
202
|
-
|
|
250
|
+
// Wrap functions with properties into a callable table
|
|
251
|
+
const wrappedFunction = node.name && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node.name))
|
|
252
|
+
? createCallableTable(functionExpression)
|
|
253
|
+
: functionExpression;
|
|
254
|
+
return (0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, name, wrappedFunction, node);
|
|
203
255
|
};
|
|
204
256
|
exports.transformFunctionDeclaration = transformFunctionDeclaration;
|
|
205
257
|
const transformYieldExpression = (expression, context) => {
|
|
@@ -5,6 +5,7 @@ const ts = require("typescript");
|
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
6
|
const builtins_1 = require("../builtins");
|
|
7
7
|
const promise_1 = require("../builtins/promise");
|
|
8
|
+
const context_1 = require("../context");
|
|
8
9
|
const annotations_1 = require("../utils/annotations");
|
|
9
10
|
const diagnostics_1 = require("../utils/diagnostics");
|
|
10
11
|
const export_1 = require("../utils/export");
|
|
@@ -19,7 +20,7 @@ const vararg_1 = require("./language-extensions/vararg");
|
|
|
19
20
|
const optional_chaining_1 = require("./optional-chaining");
|
|
20
21
|
function transformIdentifier(context, identifier) {
|
|
21
22
|
if ((0, optional_chaining_1.isOptionalContinuation)(identifier)) {
|
|
22
|
-
return lua.createIdentifier(identifier.text);
|
|
23
|
+
return lua.createIdentifier(identifier.text, undefined, context_1.tempSymbolId);
|
|
23
24
|
}
|
|
24
25
|
if ((0, multi_1.isMultiFunctionNode)(context, identifier)) {
|
|
25
26
|
context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionUse)(identifier));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { TransformationContext } from "../../context";
|
|
2
|
+
import * as ts from "typescript";
|
|
3
|
+
import * as lua from "../../../LuaAST";
|
|
4
|
+
export declare function transformLanguageExtensionCallExpression(context: TransformationContext, node: ts.CallExpression, isOptionalCall: boolean): lua.Expression | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformLanguageExtensionCallExpression = void 0;
|
|
4
|
+
const operators_1 = require("./operators");
|
|
5
|
+
const table_1 = require("./table");
|
|
6
|
+
function transformLanguageExtensionCallExpression(context, node, isOptionalCall) {
|
|
7
|
+
const operatorMapping = (0, operators_1.transformOperatorMappingExpression)(context, node, isOptionalCall);
|
|
8
|
+
if (operatorMapping) {
|
|
9
|
+
return operatorMapping;
|
|
10
|
+
}
|
|
11
|
+
const tableCall = (0, table_1.transformTableExtensionCall)(context, node, isOptionalCall);
|
|
12
|
+
if (tableCall) {
|
|
13
|
+
return tableCall;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.transformLanguageExtensionCallExpression = transformLanguageExtensionCallExpression;
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -2,4 +2,4 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as lua from "../../../LuaAST";
|
|
3
3
|
import { TransformationContext } from "../../context";
|
|
4
4
|
export declare function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier): boolean;
|
|
5
|
-
export declare function transformOperatorMappingExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression;
|
|
5
|
+
export declare function transformOperatorMappingExpression(context: TransformationContext, node: ts.CallExpression, isOptionalCall: boolean): lua.Expression | undefined;
|
|
@@ -77,9 +77,14 @@ function isOperatorMapping(context, node) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
exports.isOperatorMapping = isOperatorMapping;
|
|
80
|
-
function transformOperatorMappingExpression(context, node) {
|
|
80
|
+
function transformOperatorMappingExpression(context, node, isOptionalCall) {
|
|
81
81
|
const extensionKind = getOperatorMapExtensionKindForCall(context, node);
|
|
82
|
-
|
|
82
|
+
if (!extensionKind)
|
|
83
|
+
return undefined;
|
|
84
|
+
if (isOptionalCall) {
|
|
85
|
+
context.diagnostics.push((0, diagnostics_1.unsupportedBuiltinOptionalCall)(node));
|
|
86
|
+
return lua.createNilLiteral();
|
|
87
|
+
}
|
|
83
88
|
const isBefore53 = context.luaTarget === CompilerOptions_1.LuaTarget.Lua51 ||
|
|
84
89
|
context.luaTarget === CompilerOptions_1.LuaTarget.Lua52 ||
|
|
85
90
|
context.luaTarget === CompilerOptions_1.LuaTarget.LuaJIT ||
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import * as lua from "../../../LuaAST";
|
|
3
|
+
import { TransformationContext } from "../../context";
|
|
4
|
+
export declare function isPairsIterableExpression(context: TransformationContext, expression: ts.Expression): boolean;
|
|
5
|
+
export declare function transformForOfPairsIterableStatement(context: TransformationContext, statement: ts.ForOfStatement, block: lua.Block): lua.Statement;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformForOfPairsIterableStatement = exports.isPairsIterableExpression = void 0;
|
|
4
|
+
const ts = require("typescript");
|
|
5
|
+
const lua = require("../../../LuaAST");
|
|
6
|
+
const utils_1 = require("../../../utils");
|
|
7
|
+
const diagnostics_1 = require("../../utils/diagnostics");
|
|
8
|
+
const extensions = require("../../utils/language-extensions");
|
|
9
|
+
const utils_2 = require("../loops/utils");
|
|
10
|
+
const variable_declaration_1 = require("../variable-declaration");
|
|
11
|
+
function isPairsIterableType(type) {
|
|
12
|
+
return extensions.isExtensionType(type, extensions.ExtensionKind.PairsIterableType);
|
|
13
|
+
}
|
|
14
|
+
function isPairsIterableExpression(context, expression) {
|
|
15
|
+
const type = context.checker.getTypeAtLocation(expression);
|
|
16
|
+
return isPairsIterableType(type);
|
|
17
|
+
}
|
|
18
|
+
exports.isPairsIterableExpression = isPairsIterableExpression;
|
|
19
|
+
function transformForOfPairsIterableStatement(context, statement, block) {
|
|
20
|
+
const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [
|
|
21
|
+
context.transformExpression(statement.expression),
|
|
22
|
+
]);
|
|
23
|
+
let identifiers = [];
|
|
24
|
+
if (ts.isVariableDeclarationList(statement.initializer)) {
|
|
25
|
+
// Variables declared in for loop
|
|
26
|
+
// for key, value in iterable do
|
|
27
|
+
const binding = (0, utils_2.getVariableDeclarationBinding)(context, statement.initializer);
|
|
28
|
+
if (ts.isArrayBindingPattern(binding)) {
|
|
29
|
+
identifiers = binding.elements.map(e => (0, variable_declaration_1.transformArrayBindingElement)(context, e));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
context.diagnostics.push((0, diagnostics_1.invalidPairsIterableWithoutDestructuring)(binding));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (ts.isArrayLiteralExpression(statement.initializer)) {
|
|
36
|
+
// Variables NOT declared in for loop - catch iterator values in temps and assign
|
|
37
|
+
// for ____key, ____value in iterable do
|
|
38
|
+
// key, value = ____key, ____value
|
|
39
|
+
identifiers = statement.initializer.elements.map(e => context.createTempNameForNode(e));
|
|
40
|
+
if (identifiers.length > 0) {
|
|
41
|
+
block.statements.unshift(lua.createAssignmentStatement(statement.initializer.elements.map(e => (0, utils_1.cast)(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression)), identifiers));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
context.diagnostics.push((0, diagnostics_1.invalidPairsIterableWithoutDestructuring)(statement.initializer));
|
|
46
|
+
}
|
|
47
|
+
if (identifiers.length === 0) {
|
|
48
|
+
identifiers.push(lua.createAnonymousIdentifier());
|
|
49
|
+
}
|
|
50
|
+
return lua.createForInStatement(block, identifiers, [pairsCall], statement);
|
|
51
|
+
}
|
|
52
|
+
exports.transformForOfPairsIterableStatement = transformForOfPairsIterableStatement;
|
|
53
|
+
//# sourceMappingURL=pairsIterable.js.map
|
|
@@ -2,12 +2,5 @@ import * as ts from "typescript";
|
|
|
2
2
|
import * as lua from "../../../LuaAST";
|
|
3
3
|
import { TransformationContext } from "../../context";
|
|
4
4
|
export declare function isTableExtensionIdentifier(context: TransformationContext, node: ts.Identifier): boolean;
|
|
5
|
-
export declare function isTableDeleteCall(context: TransformationContext, node: ts.CallExpression): boolean;
|
|
6
|
-
export declare function isTableGetCall(context: TransformationContext, node: ts.CallExpression): boolean;
|
|
7
|
-
export declare function isTableHasCall(context: TransformationContext, node: ts.CallExpression): boolean;
|
|
8
|
-
export declare function isTableSetCall(context: TransformationContext, node: ts.CallExpression): boolean;
|
|
9
5
|
export declare function isTableNewCall(context: TransformationContext, node: ts.NewExpression): boolean;
|
|
10
|
-
export declare function
|
|
11
|
-
export declare function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression;
|
|
12
|
-
export declare function transformTableHasExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression;
|
|
13
|
-
export declare function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement;
|
|
6
|
+
export declare function transformTableExtensionCall(context: TransformationContext, node: ts.CallExpression, isOptionalCall: boolean): lua.Expression | undefined;
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.transformTableExtensionCall = exports.isTableNewCall = exports.isTableExtensionIdentifier = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
6
|
const extensions = require("../../utils/language-extensions");
|
|
7
7
|
const typescript_1 = require("../../utils/typescript");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const expression_list_1 = require("../expression-list");
|
|
9
|
+
const diagnostics_1 = require("../../utils/diagnostics");
|
|
10
|
+
const tableCallExtensions = [
|
|
10
11
|
extensions.ExtensionKind.TableDeleteType,
|
|
11
12
|
extensions.ExtensionKind.TableDeleteMethodType,
|
|
13
|
+
extensions.ExtensionKind.TableGetType,
|
|
14
|
+
extensions.ExtensionKind.TableGetMethodType,
|
|
15
|
+
extensions.ExtensionKind.TableHasType,
|
|
16
|
+
extensions.ExtensionKind.TableHasMethodType,
|
|
17
|
+
extensions.ExtensionKind.TableSetType,
|
|
18
|
+
extensions.ExtensionKind.TableSetMethodType,
|
|
12
19
|
];
|
|
13
|
-
const
|
|
14
|
-
const tableHasExtensions = [extensions.ExtensionKind.TableHasType, extensions.ExtensionKind.TableHasMethodType];
|
|
15
|
-
const tableSetExtensions = [extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType];
|
|
16
|
-
const tableExtensions = [
|
|
17
|
-
extensions.ExtensionKind.TableNewType,
|
|
18
|
-
...tableDeleteExtensions,
|
|
19
|
-
...tableGetExtensions,
|
|
20
|
-
...tableHasExtensions,
|
|
21
|
-
...tableSetExtensions,
|
|
22
|
-
];
|
|
20
|
+
const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableCallExtensions];
|
|
23
21
|
function getTableExtensionKindForCall(context, node, validExtensions) {
|
|
24
22
|
const type = (0, typescript_1.getFunctionTypeForCall)(context, node);
|
|
25
23
|
return type && validExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind));
|
|
@@ -29,79 +27,83 @@ function isTableExtensionIdentifier(context, node) {
|
|
|
29
27
|
return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind));
|
|
30
28
|
}
|
|
31
29
|
exports.isTableExtensionIdentifier = isTableExtensionIdentifier;
|
|
32
|
-
function isTableDeleteCall(context, node) {
|
|
33
|
-
return getTableExtensionKindForCall(context, node, tableDeleteExtensions) !== undefined;
|
|
34
|
-
}
|
|
35
|
-
exports.isTableDeleteCall = isTableDeleteCall;
|
|
36
|
-
function isTableGetCall(context, node) {
|
|
37
|
-
return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined;
|
|
38
|
-
}
|
|
39
|
-
exports.isTableGetCall = isTableGetCall;
|
|
40
|
-
function isTableHasCall(context, node) {
|
|
41
|
-
return getTableExtensionKindForCall(context, node, tableHasExtensions) !== undefined;
|
|
42
|
-
}
|
|
43
|
-
exports.isTableHasCall = isTableHasCall;
|
|
44
|
-
function isTableSetCall(context, node) {
|
|
45
|
-
return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined;
|
|
46
|
-
}
|
|
47
|
-
exports.isTableSetCall = isTableSetCall;
|
|
48
30
|
function isTableNewCall(context, node) {
|
|
49
31
|
const type = context.checker.getTypeAtLocation(node.expression);
|
|
50
32
|
return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType);
|
|
51
33
|
}
|
|
52
34
|
exports.isTableNewCall = isTableNewCall;
|
|
53
|
-
function
|
|
54
|
-
const
|
|
55
|
-
|
|
35
|
+
function transformTableExtensionCall(context, node, isOptionalCall) {
|
|
36
|
+
const extensionType = getTableExtensionKindForCall(context, node, tableCallExtensions);
|
|
37
|
+
if (!extensionType)
|
|
38
|
+
return;
|
|
39
|
+
if (isOptionalCall) {
|
|
40
|
+
context.diagnostics.push((0, diagnostics_1.unsupportedBuiltinOptionalCall)(node));
|
|
41
|
+
return lua.createNilLiteral();
|
|
42
|
+
}
|
|
43
|
+
if (extensionType === extensions.ExtensionKind.TableDeleteType ||
|
|
44
|
+
extensionType === extensions.ExtensionKind.TableDeleteMethodType) {
|
|
45
|
+
return transformTableDeleteExpression(context, node, extensionType);
|
|
46
|
+
}
|
|
47
|
+
if (extensionType === extensions.ExtensionKind.TableGetType ||
|
|
48
|
+
extensionType === extensions.ExtensionKind.TableGetMethodType) {
|
|
49
|
+
return transformTableGetExpression(context, node, extensionType);
|
|
50
|
+
}
|
|
51
|
+
if (extensionType === extensions.ExtensionKind.TableHasType ||
|
|
52
|
+
extensionType === extensions.ExtensionKind.TableHasMethodType) {
|
|
53
|
+
return transformTableHasExpression(context, node, extensionType);
|
|
54
|
+
}
|
|
55
|
+
if (extensionType === extensions.ExtensionKind.TableSetType ||
|
|
56
|
+
extensionType === extensions.ExtensionKind.TableSetMethodType) {
|
|
57
|
+
return transformTableSetExpression(context, node, extensionType);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.transformTableExtensionCall = transformTableExtensionCall;
|
|
61
|
+
function transformTableDeleteExpression(context, node, extensionKind) {
|
|
56
62
|
const args = node.arguments.slice();
|
|
57
|
-
if (
|
|
63
|
+
if (extensionKind === extensions.ExtensionKind.TableDeleteMethodType &&
|
|
58
64
|
(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) {
|
|
59
65
|
// In case of method (no table argument), push method owner to front of args list
|
|
60
66
|
args.unshift(node.expression.expression);
|
|
61
67
|
}
|
|
62
68
|
// arg0[arg1] = nil
|
|
63
|
-
|
|
69
|
+
const [table, accessExpression] = (0, expression_list_1.transformExpressionList)(context, args);
|
|
70
|
+
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), lua.createNilLiteral(), node));
|
|
71
|
+
return lua.createBooleanLiteral(true);
|
|
64
72
|
}
|
|
65
|
-
|
|
66
|
-
function transformTableGetExpression(context, node) {
|
|
67
|
-
const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions);
|
|
68
|
-
(0, utils_1.assert)(extensionKind);
|
|
73
|
+
function transformTableGetExpression(context, node, extensionKind) {
|
|
69
74
|
const args = node.arguments.slice();
|
|
70
|
-
if (
|
|
75
|
+
if (extensionKind === extensions.ExtensionKind.TableGetMethodType &&
|
|
71
76
|
(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) {
|
|
72
77
|
// In case of method (no table argument), push method owner to front of args list
|
|
73
78
|
args.unshift(node.expression.expression);
|
|
74
79
|
}
|
|
80
|
+
const [table, accessExpression] = (0, expression_list_1.transformExpressionList)(context, args);
|
|
75
81
|
// arg0[arg1]
|
|
76
|
-
return lua.createTableIndexExpression(
|
|
82
|
+
return lua.createTableIndexExpression(table, accessExpression, node);
|
|
77
83
|
}
|
|
78
|
-
|
|
79
|
-
function transformTableHasExpression(context, node) {
|
|
80
|
-
const extensionKind = getTableExtensionKindForCall(context, node, tableHasExtensions);
|
|
81
|
-
(0, utils_1.assert)(extensionKind);
|
|
84
|
+
function transformTableHasExpression(context, node, extensionKind) {
|
|
82
85
|
const args = node.arguments.slice();
|
|
83
|
-
if (
|
|
86
|
+
if (extensionKind === extensions.ExtensionKind.TableHasMethodType &&
|
|
84
87
|
(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) {
|
|
85
88
|
// In case of method (no table argument), push method owner to front of args list
|
|
86
89
|
args.unshift(node.expression.expression);
|
|
87
90
|
}
|
|
88
91
|
// arg0[arg1]
|
|
89
|
-
const
|
|
92
|
+
const [table, accessExpression] = (0, expression_list_1.transformExpressionList)(context, args);
|
|
93
|
+
const tableIndexExpression = lua.createTableIndexExpression(table, accessExpression);
|
|
90
94
|
// arg0[arg1] ~= nil
|
|
91
95
|
return lua.createBinaryExpression(tableIndexExpression, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator, node);
|
|
92
96
|
}
|
|
93
|
-
|
|
94
|
-
function transformTableSetExpression(context, node) {
|
|
95
|
-
const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions);
|
|
96
|
-
(0, utils_1.assert)(extensionKind);
|
|
97
|
+
function transformTableSetExpression(context, node, extensionKind) {
|
|
97
98
|
const args = node.arguments.slice();
|
|
98
|
-
if (
|
|
99
|
+
if (extensionKind === extensions.ExtensionKind.TableSetMethodType &&
|
|
99
100
|
(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) {
|
|
100
101
|
// In case of method (no table argument), push method owner to front of args list
|
|
101
102
|
args.unshift(node.expression.expression);
|
|
102
103
|
}
|
|
103
104
|
// arg0[arg1] = arg2
|
|
104
|
-
|
|
105
|
+
const [table, accessExpression, value] = (0, expression_list_1.transformExpressionList)(context, args);
|
|
106
|
+
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), value, node));
|
|
107
|
+
return lua.createNilLiteral();
|
|
105
108
|
}
|
|
106
|
-
exports.transformTableSetExpression = transformTableSetExpression;
|
|
107
109
|
//# sourceMappingURL=table.js.map
|
|
@@ -8,6 +8,7 @@ const diagnostics_1 = require("../../utils/diagnostics");
|
|
|
8
8
|
const lualib_1 = require("../../utils/lualib");
|
|
9
9
|
const typescript_1 = require("../../utils/typescript");
|
|
10
10
|
const iterable_1 = require("../language-extensions/iterable");
|
|
11
|
+
const pairsIterable_1 = require("../language-extensions/pairsIterable");
|
|
11
12
|
const range_1 = require("../language-extensions/range");
|
|
12
13
|
const utils_1 = require("./utils");
|
|
13
14
|
function transformForOfArrayStatement(context, statement, block) {
|
|
@@ -33,6 +34,9 @@ const transformForOfStatement = (node, context) => {
|
|
|
33
34
|
else if ((0, iterable_1.isIterableExpression)(context, node.expression)) {
|
|
34
35
|
return (0, iterable_1.transformForOfIterableStatement)(context, node, body);
|
|
35
36
|
}
|
|
37
|
+
else if ((0, pairsIterable_1.isPairsIterableExpression)(context, node.expression)) {
|
|
38
|
+
return (0, pairsIterable_1.transformForOfPairsIterableStatement)(context, node, body);
|
|
39
|
+
}
|
|
36
40
|
else if ((0, annotations_1.isLuaIteratorType)(context, node.expression)) {
|
|
37
41
|
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node.expression, annotations_1.AnnotationKind.LuaIterator));
|
|
38
42
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.invertCondition = exports.transformForInitializer = exports.getVariableDeclarationBinding = exports.transformLoopBody = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../../LuaAST");
|
|
6
|
+
const preceding_statements_1 = require("../../utils/preceding-statements");
|
|
6
7
|
const scope_1 = require("../../utils/scope");
|
|
7
8
|
const typescript_1 = require("../../utils/typescript");
|
|
8
9
|
const assignments_1 = require("../binary-expression/assignments");
|
|
@@ -34,14 +35,17 @@ function getVariableDeclarationBinding(context, node) {
|
|
|
34
35
|
exports.getVariableDeclarationBinding = getVariableDeclarationBinding;
|
|
35
36
|
function transformForInitializer(context, initializer, block) {
|
|
36
37
|
const valueVariable = lua.createIdentifier("____value");
|
|
38
|
+
(0, scope_1.pushScope)(context, scope_1.ScopeType.LoopInitializer);
|
|
37
39
|
if (ts.isVariableDeclarationList(initializer)) {
|
|
38
40
|
// Declaration of new variable
|
|
39
41
|
const binding = getVariableDeclarationBinding(context, initializer);
|
|
40
42
|
if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) {
|
|
41
|
-
|
|
43
|
+
const [precedingStatements, bindings] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, binding, valueVariable));
|
|
44
|
+
block.statements.unshift(...precedingStatements, ...bindings);
|
|
42
45
|
}
|
|
43
46
|
else {
|
|
44
47
|
// Single variable declared in for loop
|
|
48
|
+
(0, scope_1.popScope)(context);
|
|
45
49
|
return (0, identifier_1.transformIdentifier)(context, binding);
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -51,6 +55,7 @@ function transformForInitializer(context, initializer, block) {
|
|
|
51
55
|
? (0, destructuring_assignments_1.transformAssignmentPattern)(context, initializer, valueVariable, false)
|
|
52
56
|
: (0, assignments_1.transformAssignment)(context, initializer, valueVariable)));
|
|
53
57
|
}
|
|
58
|
+
(0, scope_1.popScope)(context);
|
|
54
59
|
return valueVariable;
|
|
55
60
|
}
|
|
56
61
|
exports.transformForInitializer = transformForInitializer;
|
|
@@ -13,7 +13,7 @@ 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 && (0, safe_names_1.isUnsafeName)(moduleSymbol.name)) {
|
|
16
|
+
if (moduleSymbol !== undefined && (0, safe_names_1.isUnsafeName)(moduleSymbol.name, context.options)) {
|
|
17
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?
|
|
@@ -11,9 +11,15 @@ const typescript_1 = require("../utils/typescript");
|
|
|
11
11
|
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
|
+
function skipOuterExpressionParents(node) {
|
|
15
|
+
while (ts.isOuterExpression(node)) {
|
|
16
|
+
node = node.parent;
|
|
17
|
+
}
|
|
18
|
+
return node;
|
|
19
|
+
}
|
|
14
20
|
function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
15
21
|
var _a;
|
|
16
|
-
if (!ts.isSpreadElement(identifier.parent)) {
|
|
22
|
+
if (!ts.isSpreadElement(skipOuterExpressionParents(identifier.parent))) {
|
|
17
23
|
return false;
|
|
18
24
|
}
|
|
19
25
|
// Walk up, stopping at any scope types which could stop optimization
|
|
@@ -51,19 +57,20 @@ function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
|
51
57
|
exports.isOptimizedVarArgSpread = isOptimizedVarArgSpread;
|
|
52
58
|
// TODO: Currently it's also used as an array member
|
|
53
59
|
const transformSpreadElement = (node, context) => {
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
const tsInnerExpression = ts.skipOuterExpressions(node.expression);
|
|
61
|
+
if (ts.isIdentifier(tsInnerExpression)) {
|
|
62
|
+
if ((0, annotations_1.isVarargType)(context, tsInnerExpression)) {
|
|
56
63
|
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.Vararg));
|
|
57
64
|
}
|
|
58
|
-
const symbol = context.checker.getSymbolAtLocation(
|
|
59
|
-
if (symbol && isOptimizedVarArgSpread(context, symbol,
|
|
65
|
+
const symbol = context.checker.getSymbolAtLocation(tsInnerExpression);
|
|
66
|
+
if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) {
|
|
60
67
|
return lua.createDotsLiteral(node);
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
const innerExpression = context.transformExpression(node.expression);
|
|
64
|
-
if ((0, multi_1.isMultiReturnCall)(context,
|
|
71
|
+
if ((0, multi_1.isMultiReturnCall)(context, tsInnerExpression))
|
|
65
72
|
return innerExpression;
|
|
66
|
-
const type = context.checker.getTypeAtLocation(node.expression);
|
|
73
|
+
const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts
|
|
67
74
|
if ((0, typescript_1.isArrayType)(context, type)) {
|
|
68
75
|
return (0, lua_ast_1.createUnpackCall)(context, innerExpression, node);
|
|
69
76
|
}
|