typescript-to-lua 1.16.2 → 1.17.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/transformation/utils/language-extensions.d.ts +3 -1
- package/dist/transformation/utils/language-extensions.js +3 -25
- package/dist/transformation/visitors/language-extensions/table.js +11 -0
- package/dist/transformation/visitors/switch.js +9 -3
- package/dist/transpilation/plugins.d.ts +1 -0
- package/dist/transpilation/resolve.d.ts +2 -1
- package/dist/transpilation/resolve.js +47 -11
- package/dist/transpilation/transpiler.d.ts +2 -1
- package/dist/transpilation/transpiler.js +3 -3
- package/package.json +1 -1
|
@@ -50,7 +50,9 @@ export declare enum ExtensionKind {
|
|
|
50
50
|
TableSetType = "TableSet",
|
|
51
51
|
TableSetMethodType = "TableSetMethod",
|
|
52
52
|
TableAddKeyType = "TableAddKey",
|
|
53
|
-
TableAddKeyMethodType = "TableAddKeyMethod"
|
|
53
|
+
TableAddKeyMethodType = "TableAddKeyMethod",
|
|
54
|
+
TableIsEmptyType = "TableIsEmpty",
|
|
55
|
+
TableIsEmptyMethodType = "TableIsEmptyMethod"
|
|
54
56
|
}
|
|
55
57
|
export declare function getExtensionKindForType(context: TransformationContext, type: ts.Type): ExtensionKind | undefined;
|
|
56
58
|
export declare function getExtensionKindForNode(context: TransformationContext, node: ts.Node): ExtensionKind | undefined;
|
|
@@ -55,6 +55,8 @@ var ExtensionKind;
|
|
|
55
55
|
ExtensionKind["TableSetMethodType"] = "TableSetMethod";
|
|
56
56
|
ExtensionKind["TableAddKeyType"] = "TableAddKey";
|
|
57
57
|
ExtensionKind["TableAddKeyMethodType"] = "TableAddKeyMethod";
|
|
58
|
+
ExtensionKind["TableIsEmptyType"] = "TableIsEmpty";
|
|
59
|
+
ExtensionKind["TableIsEmptyMethodType"] = "TableIsEmptyMethod";
|
|
58
60
|
})(ExtensionKind || (exports.ExtensionKind = ExtensionKind = {}));
|
|
59
61
|
const extensionValues = new Set(Object.values(ExtensionKind));
|
|
60
62
|
function getExtensionKindForType(context, type) {
|
|
@@ -113,31 +115,7 @@ function getIterableExtensionKindForNode(context, node) {
|
|
|
113
115
|
return getIterableExtensionTypeForType(context, type);
|
|
114
116
|
}
|
|
115
117
|
exports.getIterableExtensionKindForNode = getIterableExtensionKindForNode;
|
|
116
|
-
exports.methodExtensionKinds = new Set(
|
|
117
|
-
ExtensionKind.AdditionOperatorMethodType,
|
|
118
|
-
ExtensionKind.SubtractionOperatorMethodType,
|
|
119
|
-
ExtensionKind.MultiplicationOperatorMethodType,
|
|
120
|
-
ExtensionKind.DivisionOperatorMethodType,
|
|
121
|
-
ExtensionKind.ModuloOperatorMethodType,
|
|
122
|
-
ExtensionKind.PowerOperatorMethodType,
|
|
123
|
-
ExtensionKind.FloorDivisionOperatorMethodType,
|
|
124
|
-
ExtensionKind.BitwiseAndOperatorMethodType,
|
|
125
|
-
ExtensionKind.BitwiseOrOperatorMethodType,
|
|
126
|
-
ExtensionKind.BitwiseExclusiveOrOperatorMethodType,
|
|
127
|
-
ExtensionKind.BitwiseLeftShiftOperatorMethodType,
|
|
128
|
-
ExtensionKind.BitwiseRightShiftOperatorMethodType,
|
|
129
|
-
ExtensionKind.ConcatOperatorMethodType,
|
|
130
|
-
ExtensionKind.LessThanOperatorMethodType,
|
|
131
|
-
ExtensionKind.GreaterThanOperatorMethodType,
|
|
132
|
-
ExtensionKind.NegationOperatorMethodType,
|
|
133
|
-
ExtensionKind.BitwiseNotOperatorMethodType,
|
|
134
|
-
ExtensionKind.LengthOperatorMethodType,
|
|
135
|
-
ExtensionKind.TableDeleteMethodType,
|
|
136
|
-
ExtensionKind.TableGetMethodType,
|
|
137
|
-
ExtensionKind.TableHasMethodType,
|
|
138
|
-
ExtensionKind.TableSetMethodType,
|
|
139
|
-
ExtensionKind.TableAddKeyMethodType,
|
|
140
|
-
]);
|
|
118
|
+
exports.methodExtensionKinds = new Set(Object.values(ExtensionKind).filter(key => key.endsWith("Method")));
|
|
141
119
|
function getNaryCallExtensionArgs(context, node, kind, numArgs) {
|
|
142
120
|
let expressions;
|
|
143
121
|
if (node.arguments.some(ts.isSpreadElement)) {
|
|
@@ -20,6 +20,8 @@ exports.tableExtensionTransformers = {
|
|
|
20
20
|
[language_extensions_1.ExtensionKind.TableSetMethodType]: transformTableSetExpression,
|
|
21
21
|
[language_extensions_1.ExtensionKind.TableAddKeyType]: transformTableAddKeyExpression,
|
|
22
22
|
[language_extensions_1.ExtensionKind.TableAddKeyMethodType]: transformTableAddKeyExpression,
|
|
23
|
+
[language_extensions_1.ExtensionKind.TableIsEmptyType]: transformTableIsEmptyExpression,
|
|
24
|
+
[language_extensions_1.ExtensionKind.TableIsEmptyMethodType]: transformTableIsEmptyExpression,
|
|
23
25
|
};
|
|
24
26
|
function transformTableDeleteExpression(context, node, extensionKind) {
|
|
25
27
|
const args = (0, language_extensions_1.getBinaryCallExtensionArgs)(context, node, extensionKind);
|
|
@@ -71,4 +73,13 @@ function transformTableAddKeyExpression(context, node, extensionKind) {
|
|
|
71
73
|
context.addPrecedingStatements(lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createBooleanLiteral(true), node));
|
|
72
74
|
return lua.createNilLiteral();
|
|
73
75
|
}
|
|
76
|
+
function transformTableIsEmptyExpression(context, node, extensionKind) {
|
|
77
|
+
const args = (0, language_extensions_1.getUnaryCallExtensionArg)(context, node, extensionKind);
|
|
78
|
+
if (!args) {
|
|
79
|
+
return lua.createNilLiteral();
|
|
80
|
+
}
|
|
81
|
+
const table = context.transformExpression(args);
|
|
82
|
+
// next(arg0) == nil
|
|
83
|
+
return lua.createBinaryExpression(lua.createCallExpression(lua.createIdentifier("next"), [table], node), lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator, node);
|
|
84
|
+
}
|
|
74
85
|
//# sourceMappingURL=table.js.map
|
|
@@ -11,11 +11,17 @@ const containsBreakOrReturn = (nodes) => {
|
|
|
11
11
|
if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) {
|
|
12
12
|
return true;
|
|
13
13
|
}
|
|
14
|
-
else if (ts.isBlock(s) && containsBreakOrReturn(s.
|
|
14
|
+
else if (ts.isBlock(s) && containsBreakOrReturn(s.statements)) {
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
-
else if (s.kind === ts.SyntaxKind.SyntaxList
|
|
18
|
-
|
|
17
|
+
else if (s.kind === ts.SyntaxKind.SyntaxList) {
|
|
18
|
+
// We cannot use getChildren() because that breaks when using synthetic nodes from transformers
|
|
19
|
+
// So get children the long way
|
|
20
|
+
const children = [];
|
|
21
|
+
ts.forEachChild(s, c => children.push(c));
|
|
22
|
+
if (containsBreakOrReturn(children)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
}
|
|
21
27
|
return false;
|
|
@@ -29,6 +29,7 @@ export interface Plugin {
|
|
|
29
29
|
* This function is called after translating the input program to Lua, after resolving dependencies and after bundling.
|
|
30
30
|
*/
|
|
31
31
|
beforeEmit?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost, result: EmitFile[]) => ts.Diagnostic[] | void;
|
|
32
|
+
moduleResolution?: (moduleIdentifier: string, requiringFile: string, options: CompilerOptions, emitHost: EmitHost) => string | undefined;
|
|
32
33
|
}
|
|
33
34
|
export declare function getPlugins(program: ts.Program): {
|
|
34
35
|
diagnostics: ts.Diagnostic[];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
import { EmitHost, ProcessedFile } from "./utils";
|
|
3
|
+
import { Plugin } from "./plugins";
|
|
3
4
|
interface ResolutionResult {
|
|
4
5
|
resolvedFiles: ProcessedFile[];
|
|
5
6
|
diagnostics: ts.Diagnostic[];
|
|
6
7
|
}
|
|
7
|
-
export declare function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult;
|
|
8
|
+
export declare function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost, plugins: Plugin[]): ResolutionResult;
|
|
8
9
|
export {};
|
|
@@ -19,10 +19,11 @@ const resolver = resolve.ResolverFactory.createResolver({
|
|
|
19
19
|
symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection)
|
|
20
20
|
});
|
|
21
21
|
class ResolutionContext {
|
|
22
|
-
constructor(program, options, emitHost) {
|
|
22
|
+
constructor(program, options, emitHost, plugins) {
|
|
23
23
|
this.program = program;
|
|
24
24
|
this.options = options;
|
|
25
25
|
this.emitHost = emitHost;
|
|
26
|
+
this.plugins = plugins;
|
|
26
27
|
this.diagnostics = [];
|
|
27
28
|
this.resolvedFiles = new Map();
|
|
28
29
|
this.processedDependencies = new Set();
|
|
@@ -52,6 +53,7 @@ class ResolutionContext {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
resolveImport(file, required) {
|
|
56
|
+
var _a;
|
|
55
57
|
// Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages
|
|
56
58
|
if (required.requirePath === "lualib_bundle") {
|
|
57
59
|
this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" });
|
|
@@ -63,7 +65,7 @@ class ResolutionContext {
|
|
|
63
65
|
}
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
|
-
const dependencyPath = this.resolveDependencyPath(file, required.requirePath);
|
|
68
|
+
const dependencyPath = (_a = this.resolveDependencyPathsWithPlugins(file, required.requirePath)) !== null && _a !== void 0 ? _a : this.resolveDependencyPath(file, required.requirePath);
|
|
67
69
|
if (!dependencyPath)
|
|
68
70
|
return this.couldNotResolveImport(required, file);
|
|
69
71
|
if (this.options.tstlVerbose) {
|
|
@@ -77,6 +79,46 @@ class ResolutionContext {
|
|
|
77
79
|
replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
82
|
+
resolveDependencyPathsWithPlugins(requiringFile, dependency) {
|
|
83
|
+
const requiredFromLuaFile = requiringFile.fileName.endsWith(".lua");
|
|
84
|
+
for (const plugin of this.plugins) {
|
|
85
|
+
if (plugin.moduleResolution != null) {
|
|
86
|
+
const pluginResolvedPath = plugin.moduleResolution(dependency, requiringFile.fileName, this.options, this.emitHost);
|
|
87
|
+
if (pluginResolvedPath !== undefined) {
|
|
88
|
+
// If lua file is in node_module
|
|
89
|
+
if (requiredFromLuaFile && isNodeModulesFile(requiringFile.fileName)) {
|
|
90
|
+
// If requiring file is in lua module, try to resolve sibling in that file first
|
|
91
|
+
const resolvedNodeModulesFile = this.resolveLuaDependencyPathFromNodeModules(requiringFile, pluginResolvedPath);
|
|
92
|
+
if (resolvedNodeModulesFile) {
|
|
93
|
+
if (this.options.tstlVerbose) {
|
|
94
|
+
console.log(`Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.`);
|
|
95
|
+
}
|
|
96
|
+
return resolvedNodeModulesFile;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const resolvedPath = this.formatPathToFile(pluginResolvedPath, requiringFile);
|
|
100
|
+
const fileFromPath = this.getFileFromPath(resolvedPath);
|
|
101
|
+
if (fileFromPath) {
|
|
102
|
+
if (this.options.tstlVerbose) {
|
|
103
|
+
console.log(`Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.`);
|
|
104
|
+
}
|
|
105
|
+
return fileFromPath;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
formatPathToFile(targetPath, required) {
|
|
112
|
+
var _a;
|
|
113
|
+
const isRelative = ["/", "./", "../"].some(p => targetPath.startsWith(p));
|
|
114
|
+
// // If the import is relative, always resolve it relative to the requiring file
|
|
115
|
+
// // If the import is not relative, resolve it relative to options.baseUrl if it is set
|
|
116
|
+
const fileDirectory = path.dirname(required.fileName);
|
|
117
|
+
const relativeTo = isRelative ? fileDirectory : (_a = this.options.baseUrl) !== null && _a !== void 0 ? _a : fileDirectory;
|
|
118
|
+
// // Check if file is a file in the project
|
|
119
|
+
const resolvedPath = path.join(relativeTo, targetPath);
|
|
120
|
+
return resolvedPath;
|
|
121
|
+
}
|
|
80
122
|
processDependency(dependencyPath) {
|
|
81
123
|
if (this.processedDependencies.has(dependencyPath))
|
|
82
124
|
return;
|
|
@@ -102,7 +144,6 @@ class ResolutionContext {
|
|
|
102
144
|
this.diagnostics.push((0, diagnostics_1.couldNotResolveRequire)(required.requirePath, path.relative((0, transpiler_1.getProjectRoot)(this.program), file.fileName)));
|
|
103
145
|
}
|
|
104
146
|
resolveDependencyPath(requiringFile, dependency) {
|
|
105
|
-
var _a;
|
|
106
147
|
const fileDirectory = path.dirname(requiringFile.fileName);
|
|
107
148
|
if (this.options.tstlVerbose) {
|
|
108
149
|
console.log(`Resolving "${dependency}" from ${(0, utils_1.normalizeSlashes)(requiringFile.fileName)}`);
|
|
@@ -115,13 +156,8 @@ class ResolutionContext {
|
|
|
115
156
|
if (resolvedNodeModulesFile)
|
|
116
157
|
return resolvedNodeModulesFile;
|
|
117
158
|
}
|
|
118
|
-
// Check if the import is relative
|
|
119
|
-
const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p));
|
|
120
|
-
// If the import is relative, always resolve it relative to the requiring file
|
|
121
|
-
// If the import is not relative, resolve it relative to options.baseUrl if it is set
|
|
122
|
-
const relativeTo = isRelative ? fileDirectory : (_a = this.options.baseUrl) !== null && _a !== void 0 ? _a : fileDirectory;
|
|
123
159
|
// Check if file is a file in the project
|
|
124
|
-
const resolvedPath =
|
|
160
|
+
const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile);
|
|
125
161
|
const fileFromPath = this.getFileFromPath(resolvedPath);
|
|
126
162
|
if (fileFromPath)
|
|
127
163
|
return fileFromPath;
|
|
@@ -235,9 +271,9 @@ class ResolutionContext {
|
|
|
235
271
|
}
|
|
236
272
|
}
|
|
237
273
|
}
|
|
238
|
-
function resolveDependencies(program, files, emitHost) {
|
|
274
|
+
function resolveDependencies(program, files, emitHost, plugins) {
|
|
239
275
|
const options = program.getCompilerOptions();
|
|
240
|
-
const resolutionContext = new ResolutionContext(program, options, emitHost);
|
|
276
|
+
const resolutionContext = new ResolutionContext(program, options, emitHost, plugins);
|
|
241
277
|
// Resolve dependencies for all processed files
|
|
242
278
|
for (const file of files) {
|
|
243
279
|
if (options.tstlVerbose) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
|
+
import { Plugin } from "./plugins";
|
|
2
3
|
import { TranspileOptions } from "./transpile";
|
|
3
4
|
import { EmitFile, EmitHost, ProcessedFile } from "./utils";
|
|
4
5
|
export interface TranspilerOptions {
|
|
@@ -16,7 +17,7 @@ export declare class Transpiler {
|
|
|
16
17
|
constructor({ emitHost }?: TranspilerOptions);
|
|
17
18
|
emit(emitOptions: EmitOptions): EmitResult;
|
|
18
19
|
private emitFiles;
|
|
19
|
-
protected getEmitPlan(program: ts.Program, diagnostics: ts.Diagnostic[], files: ProcessedFile[]): {
|
|
20
|
+
protected getEmitPlan(program: ts.Program, diagnostics: ts.Diagnostic[], files: ProcessedFile[], plugins: Plugin[]): {
|
|
20
21
|
emitPlan: EmitFile[];
|
|
21
22
|
};
|
|
22
23
|
private getLuaLibBundleContent;
|
|
@@ -23,7 +23,7 @@ class Transpiler {
|
|
|
23
23
|
...emitOptions,
|
|
24
24
|
plugins,
|
|
25
25
|
});
|
|
26
|
-
const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles);
|
|
26
|
+
const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles, plugins);
|
|
27
27
|
const emitDiagnostics = this.emitFiles(program, plugins, emitPlan, writeFile);
|
|
28
28
|
return {
|
|
29
29
|
diagnostics: getPluginsDiagnostics.concat(transpileDiagnostics, emitDiagnostics),
|
|
@@ -60,14 +60,14 @@ class Transpiler {
|
|
|
60
60
|
performance.endSection("emit");
|
|
61
61
|
return diagnostics;
|
|
62
62
|
}
|
|
63
|
-
getEmitPlan(program, diagnostics, files) {
|
|
63
|
+
getEmitPlan(program, diagnostics, files, plugins) {
|
|
64
64
|
performance.startSection("getEmitPlan");
|
|
65
65
|
const options = program.getCompilerOptions();
|
|
66
66
|
if (options.tstlVerbose) {
|
|
67
67
|
console.log("Constructing emit plan");
|
|
68
68
|
}
|
|
69
69
|
// Resolve imported modules and modify output Lua requires
|
|
70
|
-
const resolutionResult = (0, resolve_1.resolveDependencies)(program, files, this.emitHost);
|
|
70
|
+
const resolutionResult = (0, resolve_1.resolveDependencies)(program, files, this.emitHost, plugins);
|
|
71
71
|
diagnostics.push(...resolutionResult.diagnostics);
|
|
72
72
|
const lualibRequired = resolutionResult.resolvedFiles.some(f => f.fileName === "lualib_bundle");
|
|
73
73
|
if (lualibRequired) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typescript-to-lua",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.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/",
|