@@ -2,7 +2,7 @@ use std::{hash::BuildHasherDefault, sync::Arc};
22
33use camino:: { Utf8Path , Utf8PathBuf } ;
44use indexmap:: { IndexMap , IndexSet } ;
5- use rustc_hash:: { FxHashSet , FxHasher } ;
5+ use rustc_hash:: FxHasher ;
66use serde:: Deserialize ;
77
88use crate :: path:: PathUtil ;
@@ -43,6 +43,10 @@ pub struct TsConfig {
4343 /// Bubbled up project references with a reference to their tsconfig.
4444 #[ serde( default ) ]
4545 pub references : Vec < ProjectReference > ,
46+
47+ /// Flattened transitive project references in resolution order.
48+ #[ serde( skip) ]
49+ pub ( crate ) flattened_references : Vec < Arc < TsConfig > > ,
4650}
4751
4852/// Compiler Options
@@ -158,52 +162,18 @@ impl TsConfig {
158162 . base_url
159163 . clone_from ( & other_config. compiler_options . base_url ) ;
160164 }
161- Self :: extend_file_dependencies ( & mut self . file_dependencies , & other_config. file_dependencies ) ;
162- }
163-
164- pub ( crate ) fn extend_file_dependencies (
165- file_dependencies : & mut FileDependencies ,
166- dependencies : & FileDependencies ,
167- ) {
168- file_dependencies. extend ( dependencies. iter ( ) . cloned ( ) ) ;
165+ self
166+ . file_dependencies
167+ . extend ( other_config. file_dependencies . iter ( ) . cloned ( ) ) ;
169168 }
170169
171170 pub fn resolve ( & self , path : & Utf8Path , specifier : & str ) -> Vec < Utf8PathBuf > {
172- let mut visited = FxHashSet :: default ( ) ;
173- if let Some ( matched) = self . find_reference_paths ( path, specifier, & mut visited) {
174- return matched;
175- }
176- self . resolve_path_alias ( specifier)
177- }
178-
179- // Walks `references` recursively, returning the nearest reference whose
180- // `base_path` contains `path`. Used to honor transitive project references
181- // (A → B → C): a file inside C should resolve via C's own `paths` even
182- // when the entry tsconfig is A and only B is listed directly in A's
183- // references. Matches `tsc`'s "nearest tsconfig wins" semantics.
184- fn find_reference_paths < ' a > (
185- & ' a self ,
186- path : & Utf8Path ,
187- specifier : & str ,
188- visited : & mut FxHashSet < & ' a Utf8Path > ,
189- ) -> Option < Vec < Utf8PathBuf > > {
190- if !visited. insert ( self . path . as_path ( ) ) {
191- return None ;
192- }
193-
194- for tsconfig in self
195- . references
196- . iter ( )
197- . filter_map ( |reference| reference. tsconfig . as_ref ( ) )
198- {
199- if let Some ( nested) = tsconfig. find_reference_paths ( path, specifier, visited) {
200- return Some ( nested) ;
201- }
171+ for tsconfig in & self . flattened_references {
202172 if path. starts_with ( tsconfig. base_path ( ) ) {
203- return Some ( tsconfig. resolve_path_alias ( specifier) ) ;
173+ return tsconfig. resolve_path_alias ( specifier) ;
204174 }
205175 }
206- None
176+ self . resolve_path_alias ( specifier )
207177 }
208178
209179 // Copied from parcel
0 commit comments