typescript-to-lua 1.16.2 → 1.16.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.
@@ -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.getChildren())) {
14
+ else if (ts.isBlock(s) && containsBreakOrReturn(s.statements)) {
15
15
  return true;
16
16
  }
17
- else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) {
18
- return true;
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 = path.join(relativeTo, dependencyPath);
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.16.2",
3
+ "version": "1.16.3",
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/",