@@ -10,43 +10,52 @@ import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics";
1010
1111const resolver = resolve . ResolverFactory . createResolver ( {
1212 extensions : [ ".lua" ] ,
13- enforceExtension : true , // Must be a lua file
13+ enforceExtension : true , // Resolved file must be a lua file
1414 fileSystem : { ...new resolve . CachedInputFileSystem ( fs ) } ,
1515 useSyncFileSystemCalls : true ,
1616} ) ;
1717
18- const projectFiles = new Map < string , string > ( ) ;
19-
2018interface ResolutionResult {
2119 resolvedFiles : ProcessedFile [ ] ;
2220 diagnostics : ts . Diagnostic [ ] ;
2321}
2422
23+ // Cache for getting source files from the program
24+ const projectFileCache = new Set < string > ( ) ;
25+ function isProjectFile ( file : string ) : boolean {
26+ // Check if file is in the project ts.program
27+ return projectFileCache . has ( path . normalize ( file ) ) ;
28+ }
29+
2530export function resolveDependencies ( program : ts . Program , files : ProcessedFile [ ] , emitHost : EmitHost ) : ResolutionResult {
26- const outFiles : ProcessedFile [ ] = [ ] ;
31+ const outFiles : ProcessedFile [ ] = [ ... files ] ;
2732 const diagnostics : ts . Diagnostic [ ] = [ ] ;
2833
34+ // Add files to project cache
2935 const projectRoot = getProjectRoot ( program ) ;
3036 for ( const sourceFile of program . getSourceFiles ( ) ) {
3137 const filePath = path . isAbsolute ( sourceFile . fileName )
3238 ? path . normalize ( sourceFile . fileName )
3339 : path . resolve ( projectRoot , sourceFile . fileName ) ;
34- projectFiles . set ( filePath , sourceFile . text ) ;
40+ projectFileCache . add ( filePath ) ;
3541 }
3642
43+ // Resolve dependencies for all processed files
3744 for ( const file of files ) {
3845 const resolutionResult = resolveFileDependencies ( file , program , emitHost ) ;
39- outFiles . push ( file , ...resolutionResult . resolvedFiles ) ;
46+ outFiles . push ( ...resolutionResult . resolvedFiles ) ;
4047 diagnostics . push ( ...resolutionResult . diagnostics ) ;
4148 }
4249
4350 return { resolvedFiles : outFiles , diagnostics } ;
4451}
4552
4653function resolveFileDependencies ( file : ProcessedFile , program : ts . Program , emitHost : EmitHost ) : ResolutionResult {
47- const projectRootDir = getSourceDir ( program ) ;
4854 const dependencies : ProcessedFile [ ] = [ ] ;
4955 const diagnostics : ts . Diagnostic [ ] = [ ] ;
56+
57+ const projectRootDir = getSourceDir ( program ) ;
58+
5059 for ( const required of findRequiredPaths ( file . code ) ) {
5160 // Do no resolve lualib
5261 if ( required === "lualib_bundle" ) {
@@ -63,23 +72,23 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH
6372
6473 // Try to resolve the import starting from the directory `file` is in
6574 const fileDir = path . dirname ( file . fileName ) ;
66- const resolvedDependency = resolveDependency ( fileDir , projectRootDir , required ) ;
75+ const resolvedDependency = resolveDependency ( fileDir , projectRootDir , required , emitHost ) ;
6776 if ( resolvedDependency ) {
68- // If dependency resolved successfully, read its content
69- const dependencyContent = projectFiles . get ( resolvedDependency ) ?? emitHost . readFile ( resolvedDependency ) ;
70- if ( dependencyContent === undefined ) {
71- diagnostics . push ( couldNotReadDependency ( resolvedDependency ) ) ;
72- continue ;
73- }
74-
7577 // Figure out resolved require path and dependency output path
7678 const resolvedRequire = getEmitPathRelativeToOutDir ( resolvedDependency , program ) ;
7779
7880 replaceRequireInCode ( file , required , resolvedRequire ) ;
7981 replaceRequireInSourceMap ( file , required , resolvedRequire ) ;
8082
81- // If dependency is not part of sources, add dependency to output and resolve its dependencies recursively
82- if ( ! projectFiles . has ( resolvedDependency ) ) {
83+ // If dependency is not part of project, add dependency to output and resolve its dependencies recursively
84+ if ( ! isProjectFile ( resolvedDependency ) ) {
85+ // If dependency resolved successfully, read its content
86+ const dependencyContent = emitHost . readFile ( resolvedDependency ) ;
87+ if ( dependencyContent === undefined ) {
88+ diagnostics . push ( couldNotReadDependency ( resolvedDependency ) ) ;
89+ continue ;
90+ }
91+
8392 const dependency = {
8493 fileName : resolvedDependency ,
8594 code : dependencyContent ,
@@ -100,12 +109,12 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH
100109 return { resolvedFiles : dependencies , diagnostics } ;
101110}
102111
103- function replaceRequireInCode ( file : ProcessedFile , originalRequire : string , newRequire : string ) {
112+ function replaceRequireInCode ( file : ProcessedFile , originalRequire : string , newRequire : string ) : void {
104113 const requirePath = formatPathToLuaPath ( newRequire . replace ( ".lua" , "" ) ) ;
105114 file . code = file . code . replace ( `require("${ originalRequire } ")` , `require("${ requirePath } ")` ) ;
106115}
107116
108- function replaceRequireInSourceMap ( file : ProcessedFile , originalRequire : string , newRequire : string ) {
117+ function replaceRequireInSourceMap ( file : ProcessedFile , originalRequire : string , newRequire : string ) : void {
109118 const requirePath = formatPathToLuaPath ( newRequire . replace ( ".lua" , "" ) ) ;
110119 if ( file . sourceMapNode ) {
111120 replaceInSourceMap ( file . sourceMapNode , file . sourceMapNode , `"${ originalRequire } "` , `"${ requirePath } "` ) ;
@@ -142,20 +151,32 @@ function findRequiredPaths(code: string): string[] {
142151 return paths ;
143152}
144153
145- function resolveDependency ( fileDirectory : string , rootDirectory : string , dependency : string ) : string | undefined {
146- // Check if file is a TS file in the project
154+ function resolveDependency (
155+ fileDirectory : string ,
156+ rootDirectory : string ,
157+ dependency : string ,
158+ emitHost : EmitHost
159+ ) : string | undefined {
160+ // Check if file is a file in the project
147161 const resolvedPath = path . resolve ( fileDirectory , dependency ) ;
148162
149163 const resolvedFile = resolvedPath + ".ts" ;
150- if ( projectFiles . has ( resolvedFile ) ) {
164+ if ( isProjectFile ( resolvedFile ) ) {
151165 return resolvedFile ;
152166 }
153167
154168 const projectIndexPath = path . resolve ( resolvedPath , "index.ts" ) ;
155- if ( projectFiles . has ( projectIndexPath ) ) {
169+ if ( isProjectFile ( projectIndexPath ) ) {
156170 return projectIndexPath ;
157171 }
158172
173+ // Check if this is a sibling of a required lua file
174+ const luaFilePath = path . resolve ( fileDirectory , dependency + ".lua" ) ;
175+ if ( emitHost . fileExists ( luaFilePath ) ) {
176+ return luaFilePath ;
177+ }
178+
179+ // Not a TS file in our project sources, use resolver to check if we can find dependency
159180 try {
160181 const resolveResult = resolver . resolveSync ( { } , rootDirectory , dependency ) ;
161182 if ( resolveResult ) {
0 commit comments