typescript-to-lua 1.6.3 → 1.7.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 +1 -0
- package/dist/cli/parse.js +5 -0
- package/dist/lualib/ArraySlice.lua +10 -2
- package/dist/lualib/ArraySplice.lua +5 -1
- package/dist/lualib/Generator.lua +8 -1
- package/dist/lualib/ParseFloat.lua +5 -1
- package/dist/lualib/SparseArraySpread.lua +5 -1
- package/dist/lualib/StringCharCodeAt.lua +5 -1
- package/dist/lualib/lualib_bundle.lua +38 -7
- package/dist/lualib-build/plugin.js +1 -2
- package/dist/measure-performance.d.ts +15 -0
- package/dist/measure-performance.js +83 -0
- package/dist/transformation/builtins/array.js +2 -1
- package/dist/transformation/builtins/function.js +1 -1
- package/dist/transformation/builtins/global.d.ts +1 -1
- package/dist/transformation/builtins/global.js +13 -12
- package/dist/transformation/builtins/index.d.ts +2 -2
- package/dist/transformation/builtins/index.js +87 -89
- package/dist/transformation/builtins/object.d.ts +1 -1
- package/dist/transformation/builtins/object.js +4 -4
- package/dist/transformation/builtins/promise.js +4 -2
- package/dist/transformation/builtins/string.js +2 -0
- package/dist/transformation/context/context.d.ts +15 -0
- package/dist/transformation/context/context.js +66 -24
- package/dist/transformation/context/visitors.d.ts +1 -1
- package/dist/transformation/index.js +6 -5
- package/dist/transformation/utils/annotations.d.ts +1 -17
- package/dist/transformation/utils/annotations.js +48 -88
- package/dist/transformation/utils/assignment-validation.js +27 -23
- package/dist/transformation/utils/diagnostics.d.ts +1 -4
- package/dist/transformation/utils/diagnostics.js +2 -3
- package/dist/transformation/utils/function-context.d.ts +1 -1
- package/dist/transformation/utils/function-context.js +57 -51
- package/dist/transformation/utils/language-extensions.d.ts +57 -51
- package/dist/transformation/utils/language-extensions.js +99 -119
- package/dist/transformation/utils/lualib.d.ts +0 -1
- package/dist/transformation/utils/lualib.js +2 -8
- package/dist/transformation/utils/safe-names.d.ts +1 -1
- package/dist/transformation/utils/safe-names.js +3 -6
- package/dist/transformation/utils/scope.d.ts +0 -2
- package/dist/transformation/utils/scope.js +10 -27
- package/dist/transformation/utils/symbols.d.ts +1 -1
- package/dist/transformation/utils/symbols.js +7 -20
- package/dist/transformation/utils/typescript/index.d.ts +1 -0
- package/dist/transformation/utils/typescript/index.js +2 -1
- package/dist/transformation/utils/typescript/types.d.ts +2 -5
- package/dist/transformation/utils/typescript/types.js +27 -37
- package/dist/transformation/visitors/access.js +1 -4
- package/dist/transformation/visitors/block.js +4 -4
- package/dist/transformation/visitors/call.js +7 -18
- package/dist/transformation/visitors/class/index.js +8 -20
- package/dist/transformation/visitors/class/members/constructor.js +2 -2
- package/dist/transformation/visitors/class/new.js +2 -5
- package/dist/transformation/visitors/class/setup.d.ts +1 -1
- package/dist/transformation/visitors/class/setup.js +4 -4
- package/dist/transformation/visitors/class/utils.d.ts +1 -1
- package/dist/transformation/visitors/class/utils.js +2 -9
- package/dist/transformation/visitors/conditional.js +4 -4
- package/dist/transformation/visitors/function.d.ts +1 -1
- package/dist/transformation/visitors/function.js +8 -16
- package/dist/transformation/visitors/identifier.d.ts +1 -0
- package/dist/transformation/visitors/identifier.js +40 -44
- package/dist/transformation/visitors/language-extensions/call-extension.d.ts +10 -0
- package/dist/transformation/visitors/language-extensions/call-extension.js +23 -0
- package/dist/transformation/visitors/language-extensions/identifier.d.ts +5 -0
- package/dist/transformation/visitors/language-extensions/identifier.js +27 -0
- package/dist/transformation/visitors/language-extensions/iterable.d.ts +2 -3
- package/dist/transformation/visitors/language-extensions/iterable.js +21 -22
- package/dist/transformation/visitors/language-extensions/multi.d.ts +0 -1
- package/dist/transformation/visitors/language-extensions/multi.js +10 -24
- package/dist/transformation/visitors/language-extensions/operators.d.ts +2 -5
- package/dist/transformation/visitors/language-extensions/operators.js +89 -96
- package/dist/transformation/visitors/language-extensions/range.js +4 -2
- package/dist/transformation/visitors/language-extensions/table.d.ts +6 -3
- package/dist/transformation/visitors/language-extensions/table.js +46 -75
- package/dist/transformation/visitors/language-extensions/vararg.js +7 -3
- package/dist/transformation/visitors/literal.js +2 -23
- package/dist/transformation/visitors/loops/for-of.js +18 -18
- package/dist/transformation/visitors/loops/utils.js +5 -5
- package/dist/transformation/visitors/namespace.js +5 -14
- package/dist/transformation/visitors/return.js +2 -3
- package/dist/transformation/visitors/sourceFile.js +3 -4
- package/dist/transformation/visitors/spread.js +0 -5
- package/dist/transformation/visitors/switch.js +2 -2
- package/dist/transformation/visitors/variable-declaration.js +1 -1
- package/dist/transpilation/plugins.js +3 -0
- package/dist/transpilation/resolve.js +144 -161
- package/dist/transpilation/transpile.js +10 -0
- package/dist/transpilation/transpiler.d.ts +1 -0
- package/dist/transpilation/transpiler.js +18 -5
- package/dist/tstl.js +21 -0
- package/language-extensions/index.d.ts +156 -67
- package/package.json +2 -2
- package/dist/transformation/visitors/language-extensions/index.d.ts +0 -4
- package/dist/transformation/visitors/language-extensions/index.js +0 -17
- package/dist/transformation/visitors/language-extensions/pairsIterable.d.ts +0 -5
- package/dist/transformation/visitors/language-extensions/pairsIterable.js +0 -53
|
@@ -60,7 +60,6 @@ const transformReturnStatement = (statement, context) => {
|
|
|
60
60
|
};
|
|
61
61
|
exports.transformReturnStatement = transformReturnStatement;
|
|
62
62
|
function createReturnStatement(context, values, node) {
|
|
63
|
-
const results = [...values];
|
|
64
63
|
if ((0, typescript_1.isInAsyncFunction)(node)) {
|
|
65
64
|
return lua.createReturnStatement([
|
|
66
65
|
lua.createCallExpression(lua.createIdentifier("____awaiter_resolve"), [lua.createNilLiteral(), ...values]),
|
|
@@ -68,9 +67,9 @@ function createReturnStatement(context, values, node) {
|
|
|
68
67
|
}
|
|
69
68
|
if (isInTryCatch(context)) {
|
|
70
69
|
// Bubble up explicit return flag and check if we're inside a try/catch block
|
|
71
|
-
|
|
70
|
+
values = [lua.createBooleanLiteral(true), ...values];
|
|
72
71
|
}
|
|
73
|
-
return lua.createReturnStatement(
|
|
72
|
+
return lua.createReturnStatement(values, node);
|
|
74
73
|
}
|
|
75
74
|
exports.createReturnStatement = createReturnStatement;
|
|
76
75
|
function isInTryCatch(context) {
|
|
@@ -5,7 +5,6 @@ const ts = require("typescript");
|
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
7
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
8
|
-
const lualib_1 = require("../utils/lualib");
|
|
9
8
|
const preceding_statements_1 = require("../utils/preceding-statements");
|
|
10
9
|
const scope_1 = require("../utils/scope");
|
|
11
10
|
const typescript_1 = require("../utils/typescript");
|
|
@@ -28,9 +27,9 @@ const transformSourceFileNode = (node, context) => {
|
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
else {
|
|
31
|
-
|
|
30
|
+
context.pushScope(scope_1.ScopeType.File);
|
|
32
31
|
statements = (0, scope_1.performHoisting)(context, context.transformStatements(node.statements));
|
|
33
|
-
|
|
32
|
+
context.popScope();
|
|
34
33
|
if (context.isModule) {
|
|
35
34
|
// If export equals was not used. Create the exports table.
|
|
36
35
|
// local ____exports = {}
|
|
@@ -42,7 +41,7 @@ const transformSourceFileNode = (node, context) => {
|
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
const trivia = (_b = (_a = node.getFullText().match(/^#!.*\r?\n/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "";
|
|
45
|
-
return lua.createFile(statements,
|
|
44
|
+
return lua.createFile(statements, context.usedLuaLibFeatures, trivia, node);
|
|
46
45
|
};
|
|
47
46
|
exports.transformSourceFileNode = transformSourceFileNode;
|
|
48
47
|
//# sourceMappingURL=sourceFile.js.map
|
|
@@ -3,13 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.transformSpreadElement = exports.isOptimizedVarArgSpread = void 0;
|
|
4
4
|
const ts = require("typescript");
|
|
5
5
|
const lua = require("../../LuaAST");
|
|
6
|
-
const annotations_1 = require("../utils/annotations");
|
|
7
6
|
const lua_ast_1 = require("../utils/lua-ast");
|
|
8
7
|
const lualib_1 = require("../utils/lualib");
|
|
9
8
|
const scope_1 = require("../utils/scope");
|
|
10
9
|
const typescript_1 = require("../utils/typescript");
|
|
11
10
|
const multi_1 = require("./language-extensions/multi");
|
|
12
|
-
const diagnostics_1 = require("../utils/diagnostics");
|
|
13
11
|
const vararg_1 = require("./language-extensions/vararg");
|
|
14
12
|
function isOptimizedVarArgSpread(context, symbol, identifier) {
|
|
15
13
|
var _a;
|
|
@@ -53,9 +51,6 @@ exports.isOptimizedVarArgSpread = isOptimizedVarArgSpread;
|
|
|
53
51
|
const transformSpreadElement = (node, context) => {
|
|
54
52
|
const tsInnerExpression = ts.skipOuterExpressions(node.expression);
|
|
55
53
|
if (ts.isIdentifier(tsInnerExpression)) {
|
|
56
|
-
if ((0, annotations_1.isVarargType)(context, tsInnerExpression)) {
|
|
57
|
-
context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.Vararg));
|
|
58
|
-
}
|
|
59
54
|
const symbol = context.checker.getSymbolAtLocation(tsInnerExpression);
|
|
60
55
|
if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) {
|
|
61
56
|
return lua.createDotsLiteral(node);
|
|
@@ -39,7 +39,7 @@ const coalesceCondition = (condition, conditionPrecedingStatements, switchVariab
|
|
|
39
39
|
return [[...conditionPrecedingStatements, ...precedingStatements], comparison];
|
|
40
40
|
};
|
|
41
41
|
const transformSwitchStatement = (statement, context) => {
|
|
42
|
-
const scope =
|
|
42
|
+
const scope = context.pushScope(scope_1.ScopeType.Switch);
|
|
43
43
|
// Give the switch and condition accumulator a unique name to prevent nested switches from acting up.
|
|
44
44
|
const switchName = `____switch${scope.id}`;
|
|
45
45
|
const conditionName = `____cond${scope.id}`;
|
|
@@ -158,7 +158,7 @@ const transformSwitchStatement = (statement, context) => {
|
|
|
158
158
|
if (hoistedIdentifiers.length > 0) {
|
|
159
159
|
statements.unshift(lua.createVariableDeclarationStatement(hoistedIdentifiers));
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
context.popScope();
|
|
162
162
|
// Add the switch expression after hoisting
|
|
163
163
|
const expression = context.transformExpression(statement.expression);
|
|
164
164
|
statements.unshift(lua.createVariableDeclarationStatement(switchVariable, expression));
|
|
@@ -201,7 +201,7 @@ function transformVariableDeclaration(context, statement) {
|
|
|
201
201
|
// Skip named function expressions because they will have been wrapped already
|
|
202
202
|
if (ts.isFunctionExpression(initializer) && initializer.name)
|
|
203
203
|
return false;
|
|
204
|
-
return (0, function_1.isFunctionTypeWithProperties)(context.checker.getTypeAtLocation(statement.name));
|
|
204
|
+
return (0, function_1.isFunctionTypeWithProperties)(context, context.checker.getTypeAtLocation(statement.name));
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
exports.transformVariableDeclaration = transformVariableDeclaration;
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getPlugins = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
|
+
const performance = require("../measure-performance");
|
|
5
6
|
function getPlugins(program) {
|
|
6
7
|
var _a;
|
|
8
|
+
performance.startSection("getPlugins");
|
|
7
9
|
const diagnostics = [];
|
|
8
10
|
const pluginsFromOptions = [];
|
|
9
11
|
const options = program.getCompilerOptions();
|
|
@@ -20,6 +22,7 @@ function getPlugins(program) {
|
|
|
20
22
|
if (options.tstlVerbose) {
|
|
21
23
|
console.log(`Loaded ${pluginsFromOptions.length} plugins`);
|
|
22
24
|
}
|
|
25
|
+
performance.endSection("getPlugins");
|
|
23
26
|
return { diagnostics, plugins: pluginsFromOptions };
|
|
24
27
|
}
|
|
25
28
|
exports.getPlugins = getPlugins;
|
|
@@ -21,79 +21,154 @@ class ResolutionContext {
|
|
|
21
21
|
this.program = program;
|
|
22
22
|
this.options = options;
|
|
23
23
|
this.emitHost = emitHost;
|
|
24
|
-
this.
|
|
24
|
+
this.diagnostics = [];
|
|
25
|
+
this.resolvedFiles = new Map();
|
|
26
|
+
this.processedDependencies = new Set();
|
|
27
|
+
// value is false if already searched but not found
|
|
28
|
+
this.pathToFile = new Map();
|
|
25
29
|
this.noResolvePaths = new Set(options.noResolvePaths);
|
|
26
30
|
}
|
|
27
|
-
|
|
31
|
+
addAndResolveDependencies(file) {
|
|
32
|
+
if (this.resolvedFiles.has(file.fileName))
|
|
33
|
+
return;
|
|
34
|
+
this.resolvedFiles.set(file.fileName, file);
|
|
35
|
+
for (const required of findRequiredPaths(file.code)) {
|
|
36
|
+
// Do not resolve noResolution paths
|
|
37
|
+
if (required.startsWith("@NoResolution:")) {
|
|
38
|
+
// Remove @NoResolution prefix if not building in library mode
|
|
39
|
+
if (!isBuildModeLibrary(this.program)) {
|
|
40
|
+
const path = required.replace("@NoResolution:", "");
|
|
41
|
+
replaceRequireInCode(file, required, path);
|
|
42
|
+
replaceRequireInSourceMap(file, required, path);
|
|
43
|
+
}
|
|
44
|
+
// Skip
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Try to resolve the import starting from the directory `file` is in
|
|
48
|
+
this.resolveImport(file, required);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
resolveImport(file, required) {
|
|
52
|
+
// Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages
|
|
53
|
+
if (required === "lualib_bundle") {
|
|
54
|
+
this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
28
57
|
if (this.noResolvePaths.has(required)) {
|
|
29
58
|
if (this.options.tstlVerbose) {
|
|
30
59
|
console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`);
|
|
31
60
|
}
|
|
32
|
-
return
|
|
61
|
+
return;
|
|
33
62
|
}
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
const dependencyPath = this.resolveDependencyPath(file, required);
|
|
64
|
+
if (!dependencyPath)
|
|
65
|
+
return this.couldNotResolveImport(required, file);
|
|
66
|
+
if (this.options.tstlVerbose) {
|
|
67
|
+
console.log(`Resolved ${required} to ${(0, utils_1.normalizeSlashes)(dependencyPath)}`);
|
|
68
|
+
}
|
|
69
|
+
this.processDependency(dependencyPath);
|
|
70
|
+
// Figure out resolved require path and dependency output path
|
|
71
|
+
if (shouldRewriteRequires(dependencyPath, this.program)) {
|
|
72
|
+
const resolvedRequire = (0, transpiler_1.getEmitPathRelativeToOutDir)(dependencyPath, this.program);
|
|
73
|
+
replaceRequireInCode(file, required, resolvedRequire);
|
|
74
|
+
replaceRequireInSourceMap(file, required, resolvedRequire);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
processDependency(dependencyPath) {
|
|
78
|
+
if (this.processedDependencies.has(dependencyPath))
|
|
79
|
+
return;
|
|
80
|
+
this.processedDependencies.add(dependencyPath);
|
|
81
|
+
if (!shouldIncludeDependency(dependencyPath, this.program))
|
|
82
|
+
return;
|
|
83
|
+
// If dependency is not part of project, add dependency to output and resolve its dependencies recursively
|
|
84
|
+
const dependencyContent = this.emitHost.readFile(dependencyPath);
|
|
85
|
+
if (dependencyContent === undefined) {
|
|
86
|
+
this.diagnostics.push((0, diagnostics_1.couldNotReadDependency)(dependencyPath));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const dependency = {
|
|
90
|
+
fileName: dependencyPath,
|
|
91
|
+
code: dependencyContent,
|
|
92
|
+
};
|
|
93
|
+
this.addAndResolveDependencies(dependency);
|
|
94
|
+
}
|
|
95
|
+
couldNotResolveImport(required, file) {
|
|
96
|
+
const fallbackRequire = fallbackResolve(required, (0, transpiler_1.getSourceDir)(this.program), path.dirname(file.fileName));
|
|
97
|
+
replaceRequireInCode(file, required, fallbackRequire);
|
|
98
|
+
replaceRequireInSourceMap(file, required, fallbackRequire);
|
|
99
|
+
this.diagnostics.push((0, diagnostics_1.couldNotResolveRequire)(required, path.relative((0, transpiler_1.getProjectRoot)(this.program), file.fileName)));
|
|
100
|
+
}
|
|
101
|
+
resolveDependencyPath(requiringFile, dependency) {
|
|
102
|
+
var _a;
|
|
103
|
+
const fileDirectory = path.dirname(requiringFile.fileName);
|
|
104
|
+
if (this.options.tstlVerbose) {
|
|
105
|
+
console.log(`Resolving "${dependency}" from ${(0, utils_1.normalizeSlashes)(requiringFile.fileName)}`);
|
|
106
|
+
}
|
|
107
|
+
// Check if the import is relative
|
|
108
|
+
const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p));
|
|
109
|
+
// If the import is relative, always resolve it relative to the requiring file
|
|
110
|
+
// If the import is not relative, resolve it relative to options.baseUrl if it is set
|
|
111
|
+
const relativeTo = isRelative ? fileDirectory : (_a = this.options.baseUrl) !== null && _a !== void 0 ? _a : fileDirectory;
|
|
112
|
+
// Check if file is a file in the project
|
|
113
|
+
const resolvedPath = path.join(relativeTo, dependency);
|
|
114
|
+
const fileFromPath = this.getFileFromPath(resolvedPath);
|
|
115
|
+
if (fileFromPath)
|
|
116
|
+
return fileFromPath;
|
|
117
|
+
// Check if this is a sibling of a required lua file
|
|
118
|
+
if (requiringFile.fileName.endsWith(".lua")) {
|
|
119
|
+
const luaFilePath = resolveLuaPath(fileDirectory, dependency, this.emitHost);
|
|
120
|
+
if (luaFilePath) {
|
|
121
|
+
return luaFilePath;
|
|
71
122
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
123
|
+
}
|
|
124
|
+
// Not a TS file in our project sources, use resolver to check if we can find dependency
|
|
125
|
+
try {
|
|
126
|
+
const resolveResult = resolver.resolveSync({}, fileDirectory, dependency);
|
|
127
|
+
if (resolveResult)
|
|
128
|
+
return resolveResult;
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
// resolveSync errors if it fails to resolve
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
getFileFromPath(resolvedPath) {
|
|
136
|
+
const existingFile = this.pathToFile.get(resolvedPath);
|
|
137
|
+
if (existingFile)
|
|
138
|
+
return existingFile;
|
|
139
|
+
if (existingFile === false)
|
|
140
|
+
return undefined;
|
|
141
|
+
const file = this.searchForFileFromPath(resolvedPath);
|
|
142
|
+
this.pathToFile.set(resolvedPath, file !== null && file !== void 0 ? file : false);
|
|
143
|
+
return file;
|
|
144
|
+
}
|
|
145
|
+
searchForFileFromPath(resolvedPath) {
|
|
146
|
+
const possibleProjectFiles = [
|
|
147
|
+
resolvedPath,
|
|
148
|
+
resolvedPath + ".ts",
|
|
149
|
+
path.join(resolvedPath, "index.ts"),
|
|
150
|
+
resolvedPath + ".tsx",
|
|
151
|
+
path.join(resolvedPath, "index.tsx"), // tsx index
|
|
152
|
+
];
|
|
153
|
+
for (const possibleFile of possibleProjectFiles) {
|
|
154
|
+
if (isProjectFile(possibleFile, this.program)) {
|
|
155
|
+
return possibleFile;
|
|
79
156
|
}
|
|
80
157
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
158
|
+
// Check if this is a lua file in the project sources
|
|
159
|
+
const possibleLuaProjectFiles = [
|
|
160
|
+
resolvedPath + ".lua",
|
|
161
|
+
path.join(resolvedPath, "index.lua"),
|
|
162
|
+
path.join(resolvedPath, "init.lua"), // lua looks for <require>/init.lua if it cannot find <require>.lua
|
|
163
|
+
];
|
|
164
|
+
for (const possibleFile of possibleLuaProjectFiles) {
|
|
165
|
+
if (this.emitHost.fileExists(possibleFile)) {
|
|
166
|
+
return possibleFile;
|
|
167
|
+
}
|
|
91
168
|
}
|
|
92
169
|
}
|
|
93
170
|
}
|
|
94
171
|
function resolveDependencies(program, files, emitHost) {
|
|
95
|
-
const outFiles = [...files];
|
|
96
|
-
const diagnostics = [];
|
|
97
172
|
const options = program.getCompilerOptions();
|
|
98
173
|
const resolutionContext = new ResolutionContext(program, options, emitHost);
|
|
99
174
|
// Resolve dependencies for all processed files
|
|
@@ -101,99 +176,11 @@ function resolveDependencies(program, files, emitHost) {
|
|
|
101
176
|
if (options.tstlVerbose) {
|
|
102
177
|
console.log(`Resolving dependencies for ${(0, utils_1.normalizeSlashes)(file.fileName)}`);
|
|
103
178
|
}
|
|
104
|
-
|
|
105
|
-
outFiles.push(...resolutionResult.resolvedFiles);
|
|
106
|
-
diagnostics.push(...resolutionResult.diagnostics);
|
|
179
|
+
resolutionContext.addAndResolveDependencies(file);
|
|
107
180
|
}
|
|
108
|
-
return { resolvedFiles:
|
|
181
|
+
return { resolvedFiles: [...resolutionContext.resolvedFiles.values()], diagnostics: resolutionContext.diagnostics };
|
|
109
182
|
}
|
|
110
183
|
exports.resolveDependencies = resolveDependencies;
|
|
111
|
-
function deduplicateResolvedFiles(files) {
|
|
112
|
-
return [...new Map(files.map(f => [f.fileName, f])).values()];
|
|
113
|
-
}
|
|
114
|
-
function resolveFileDependencies(file, context) {
|
|
115
|
-
const dependencies = [];
|
|
116
|
-
const diagnostics = [];
|
|
117
|
-
for (const required of findRequiredPaths(file.code)) {
|
|
118
|
-
// Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages
|
|
119
|
-
if (required === "lualib_bundle") {
|
|
120
|
-
dependencies.push({ fileName: "lualib_bundle", code: "" });
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
// Do not resolve noResolution paths
|
|
124
|
-
if (required.startsWith("@NoResolution:")) {
|
|
125
|
-
// Remove @NoResolution prefix if not building in library mode
|
|
126
|
-
if (!isBuildModeLibrary(context.program)) {
|
|
127
|
-
const path = required.replace("@NoResolution:", "");
|
|
128
|
-
replaceRequireInCode(file, required, path);
|
|
129
|
-
replaceRequireInSourceMap(file, required, path);
|
|
130
|
-
}
|
|
131
|
-
// Skip
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
// Try to resolve the import starting from the directory `file` is in
|
|
135
|
-
const resolvedDependency = context.resolve(file, required);
|
|
136
|
-
dependencies.push(...resolvedDependency.resolvedFiles);
|
|
137
|
-
diagnostics.push(...resolvedDependency.diagnostics);
|
|
138
|
-
}
|
|
139
|
-
return { resolvedFiles: deduplicateResolvedFiles(dependencies), diagnostics };
|
|
140
|
-
}
|
|
141
|
-
function resolveDependency(requiringFile, dependency, program, emitHost) {
|
|
142
|
-
var _a;
|
|
143
|
-
const options = program.getCompilerOptions();
|
|
144
|
-
const fileDirectory = path.dirname(requiringFile.fileName);
|
|
145
|
-
if (options.tstlVerbose) {
|
|
146
|
-
console.log(`Resolving "${dependency}" from ${(0, utils_1.normalizeSlashes)(requiringFile.fileName)}`);
|
|
147
|
-
}
|
|
148
|
-
// Check if the import is relative
|
|
149
|
-
const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p));
|
|
150
|
-
// If the import is relative, always resolve it relative to the requiring file
|
|
151
|
-
// If the import is not relative, resolve it relative to options.baseUrl if it is set
|
|
152
|
-
const relativeTo = isRelative ? fileDirectory : (_a = options.baseUrl) !== null && _a !== void 0 ? _a : fileDirectory;
|
|
153
|
-
// Check if file is a file in the project
|
|
154
|
-
const resolvedPath = path.join(relativeTo, dependency);
|
|
155
|
-
const possibleProjectFiles = [
|
|
156
|
-
resolvedPath,
|
|
157
|
-
resolvedPath + ".ts",
|
|
158
|
-
path.join(resolvedPath, "index.ts"),
|
|
159
|
-
resolvedPath + ".tsx",
|
|
160
|
-
path.join(resolvedPath, "index.tsx"), // tsx index
|
|
161
|
-
];
|
|
162
|
-
for (const possibleFile of possibleProjectFiles) {
|
|
163
|
-
if (isProjectFile(possibleFile, program)) {
|
|
164
|
-
return possibleFile;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
// Check if this is a lua file in the project sources
|
|
168
|
-
const possibleLuaProjectFiles = [
|
|
169
|
-
resolvedPath + ".lua",
|
|
170
|
-
path.join(resolvedPath, "index.lua"),
|
|
171
|
-
path.join(resolvedPath, "init.lua"), // lua looks for <require>/init.lua if it cannot find <require>.lua
|
|
172
|
-
];
|
|
173
|
-
for (const possibleFile of possibleLuaProjectFiles) {
|
|
174
|
-
if (emitHost.fileExists(possibleFile)) {
|
|
175
|
-
return possibleFile;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// Check if this is a sibling of a required lua file
|
|
179
|
-
if (requiringFile.fileName.endsWith(".lua")) {
|
|
180
|
-
const luaFilePath = resolveLuaPath(fileDirectory, dependency, emitHost);
|
|
181
|
-
if (luaFilePath) {
|
|
182
|
-
return luaFilePath;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// Not a TS file in our project sources, use resolver to check if we can find dependency
|
|
186
|
-
try {
|
|
187
|
-
const resolveResult = resolver.resolveSync({}, fileDirectory, dependency);
|
|
188
|
-
if (resolveResult) {
|
|
189
|
-
return resolveResult;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
catch (e) {
|
|
193
|
-
// resolveSync errors if it fails to resolve
|
|
194
|
-
}
|
|
195
|
-
return undefined;
|
|
196
|
-
}
|
|
197
184
|
function resolveLuaPath(fromPath, dependency, emitHost) {
|
|
198
185
|
const splitDependency = dependency.split(".");
|
|
199
186
|
if (splitDependency.length === 1) {
|
|
@@ -223,21 +210,17 @@ function walkUpFileTreeUntil(fromDirectory, predicate) {
|
|
|
223
210
|
return undefined;
|
|
224
211
|
}
|
|
225
212
|
function shouldRewriteRequires(resolvedDependency, program) {
|
|
226
|
-
return !
|
|
213
|
+
return !isBuildModeLibrary(program) || !isNodeModulesFile(resolvedDependency);
|
|
227
214
|
}
|
|
228
215
|
function shouldIncludeDependency(resolvedDependency, program) {
|
|
229
216
|
// Never include lua files (again) that are transpiled from project sources
|
|
230
|
-
if (
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return !isBuildModeLibrary(program);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return false;
|
|
217
|
+
if (hasSourceFileInProject(resolvedDependency, program))
|
|
218
|
+
return false;
|
|
219
|
+
// Always include lua files not in node_modules (internal lua sources)
|
|
220
|
+
if (!isNodeModulesFile(resolvedDependency))
|
|
221
|
+
return true;
|
|
222
|
+
// Only include node_modules files if not in library mode
|
|
223
|
+
return !isBuildModeLibrary(program);
|
|
241
224
|
}
|
|
242
225
|
function isBuildModeLibrary(program) {
|
|
243
226
|
return program.getCompilerOptions().buildMode === CompilerOptions_1.BuildMode.Library;
|
|
@@ -8,8 +8,10 @@ const LuaPrinter_1 = require("../LuaPrinter");
|
|
|
8
8
|
const transformation_1 = require("../transformation");
|
|
9
9
|
const utils_1 = require("../utils");
|
|
10
10
|
const transformers_1 = require("./transformers");
|
|
11
|
+
const performance = require("../measure-performance");
|
|
11
12
|
function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins = [] }) {
|
|
12
13
|
var _a, _b;
|
|
14
|
+
performance.startSection("beforeTransform");
|
|
13
15
|
const options = program.getCompilerOptions();
|
|
14
16
|
if (options.tstlVerbose) {
|
|
15
17
|
console.log("Parsing project settings");
|
|
@@ -36,6 +38,7 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
36
38
|
preEmitDiagnostics.push(...program.getDeclarationDiagnostics());
|
|
37
39
|
}
|
|
38
40
|
if (preEmitDiagnostics.length > 0) {
|
|
41
|
+
performance.endSection("beforeTransform");
|
|
39
42
|
return { diagnostics: preEmitDiagnostics, transpiledFiles };
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -51,9 +54,12 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
51
54
|
if (options.tstlVerbose) {
|
|
52
55
|
console.log(`Transforming ${sourceFile.fileName}`);
|
|
53
56
|
}
|
|
57
|
+
performance.startSection("transpile");
|
|
54
58
|
const { file, diagnostics: transformDiagnostics } = (0, transformation_1.transformSourceFile)(program, sourceFile, visitorMap);
|
|
55
59
|
diagnostics.push(...transformDiagnostics);
|
|
60
|
+
performance.endSection("transpile");
|
|
56
61
|
if (!options.noEmit && !options.emitDeclarationOnly) {
|
|
62
|
+
performance.startSection("print");
|
|
57
63
|
if (options.tstlVerbose) {
|
|
58
64
|
console.log(`Printing ${sourceFile.fileName}`);
|
|
59
65
|
}
|
|
@@ -64,6 +70,7 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
64
70
|
luaAst: file,
|
|
65
71
|
...printResult,
|
|
66
72
|
});
|
|
73
|
+
performance.endSection("print");
|
|
67
74
|
}
|
|
68
75
|
};
|
|
69
76
|
const transformers = (0, transformers_1.getTransformers)(program, diagnostics, customTransformers, processSourceFile);
|
|
@@ -78,6 +85,7 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
78
85
|
writeFileResult(fileName, ...rest);
|
|
79
86
|
}
|
|
80
87
|
};
|
|
88
|
+
performance.endSection("beforeTransform");
|
|
81
89
|
if (targetSourceFiles) {
|
|
82
90
|
for (const file of targetSourceFiles) {
|
|
83
91
|
if (isEmittableJsonFile(file)) {
|
|
@@ -93,6 +101,7 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
93
101
|
// JSON files don't get through transformers and aren't written when outDir is the same as rootDir
|
|
94
102
|
program.getSourceFiles().filter(isEmittableJsonFile).forEach(processSourceFile);
|
|
95
103
|
}
|
|
104
|
+
performance.startSection("afterPrint");
|
|
96
105
|
options.noEmit = oldNoEmit;
|
|
97
106
|
if (options.noEmit || (options.noEmitOnError && diagnostics.length > 0)) {
|
|
98
107
|
transpiledFiles = [];
|
|
@@ -103,6 +112,7 @@ function getProgramTranspileResult(emitHost, writeFileResult, { program, sourceF
|
|
|
103
112
|
diagnostics.push(...pluginDiagnostics);
|
|
104
113
|
}
|
|
105
114
|
}
|
|
115
|
+
performance.endSection("afterPrint");
|
|
106
116
|
return { diagnostics, transpiledFiles };
|
|
107
117
|
}
|
|
108
118
|
exports.getProgramTranspileResult = getProgramTranspileResult;
|
|
@@ -15,6 +15,7 @@ export declare class Transpiler {
|
|
|
15
15
|
protected emitHost: EmitHost;
|
|
16
16
|
constructor({ emitHost }?: TranspilerOptions);
|
|
17
17
|
emit(emitOptions: EmitOptions): EmitResult;
|
|
18
|
+
private emitFiles;
|
|
18
19
|
protected getEmitPlan(program: ts.Program, diagnostics: ts.Diagnostic[], files: ProcessedFile[]): {
|
|
19
20
|
emitPlan: EmitFile[];
|
|
20
21
|
};
|
|
@@ -10,24 +10,34 @@ const bundle_1 = require("./bundle");
|
|
|
10
10
|
const plugins_1 = require("./plugins");
|
|
11
11
|
const resolve_1 = require("./resolve");
|
|
12
12
|
const transpile_1 = require("./transpile");
|
|
13
|
+
const performance = require("../measure-performance");
|
|
13
14
|
class Transpiler {
|
|
14
15
|
constructor({ emitHost = ts.sys } = {}) {
|
|
15
16
|
this.emitHost = emitHost;
|
|
16
17
|
}
|
|
17
18
|
emit(emitOptions) {
|
|
18
|
-
var _a, _b;
|
|
19
19
|
const { program, writeFile = this.emitHost.writeFile, plugins: optionsPlugins = [] } = emitOptions;
|
|
20
|
-
const options = program.getCompilerOptions();
|
|
21
20
|
const { diagnostics: getPluginsDiagnostics, plugins: configPlugins } = (0, plugins_1.getPlugins)(program);
|
|
22
21
|
const plugins = [...optionsPlugins, ...configPlugins];
|
|
23
|
-
const { diagnostics, transpiledFiles: freshFiles } = (0, transpile_1.getProgramTranspileResult)(this.emitHost, writeFile, {
|
|
22
|
+
const { diagnostics: transpileDiagnostics, transpiledFiles: freshFiles } = (0, transpile_1.getProgramTranspileResult)(this.emitHost, writeFile, {
|
|
24
23
|
...emitOptions,
|
|
25
24
|
plugins,
|
|
26
25
|
});
|
|
27
|
-
const { emitPlan } = this.getEmitPlan(program,
|
|
26
|
+
const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles);
|
|
27
|
+
const emitDiagnostics = this.emitFiles(program, plugins, emitPlan, writeFile);
|
|
28
|
+
return {
|
|
29
|
+
diagnostics: getPluginsDiagnostics.concat(transpileDiagnostics, emitDiagnostics),
|
|
30
|
+
emitSkipped: emitPlan.length === 0,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
emitFiles(program, plugins, emitPlan, writeFile) {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
performance.startSection("emit");
|
|
36
|
+
const options = program.getCompilerOptions();
|
|
28
37
|
if (options.tstlVerbose) {
|
|
29
38
|
console.log("Emitting output");
|
|
30
39
|
}
|
|
40
|
+
const diagnostics = [];
|
|
31
41
|
for (const plugin of plugins) {
|
|
32
42
|
if (plugin.beforeEmit) {
|
|
33
43
|
const beforeEmitPluginDiagnostics = (_a = plugin.beforeEmit(program, options, this.emitHost, emitPlan)) !== null && _a !== void 0 ? _a : [];
|
|
@@ -47,9 +57,11 @@ class Transpiler {
|
|
|
47
57
|
if (options.tstlVerbose) {
|
|
48
58
|
console.log("Emit finished!");
|
|
49
59
|
}
|
|
50
|
-
|
|
60
|
+
performance.endSection("emit");
|
|
61
|
+
return diagnostics;
|
|
51
62
|
}
|
|
52
63
|
getEmitPlan(program, diagnostics, files) {
|
|
64
|
+
performance.startSection("getEmitPlan");
|
|
53
65
|
const options = program.getCompilerOptions();
|
|
54
66
|
if (options.tstlVerbose) {
|
|
55
67
|
console.log("Constructing emit plan");
|
|
@@ -80,6 +92,7 @@ class Transpiler {
|
|
|
80
92
|
outputPath: getEmitPath(file.fileName, program),
|
|
81
93
|
}));
|
|
82
94
|
}
|
|
95
|
+
performance.endSection("getEmitPlan");
|
|
83
96
|
return { emitPlan };
|
|
84
97
|
}
|
|
85
98
|
}
|