@@ -14,8 +14,8 @@ use once_cell::sync::OnceCell as OnceLock;
1414use rustc_hash:: FxHasher ;
1515
1616use crate :: {
17- context:: ResolveContext as Ctx , package_json:: PackageJson , path :: PathUtil , FileMetadata ,
18- FileSystem , ResolveError , ResolveOptions , TsConfig ,
17+ context:: ResolveContext as Ctx , package_json:: PackageJson , FileMetadata , FileSystem ,
18+ ResolveError , ResolveOptions , TsConfig ,
1919} ;
2020
2121thread_local ! {
@@ -136,39 +136,17 @@ impl CacheKey for CachedPath {
136136 }
137137}
138138
139- pub struct CachedPathImpl {
140- hash : u64 ,
141- path : Box < Path > ,
142- parent : Option < CachedPath > ,
143- meta : OnceLock < Option < FileMetadata > > ,
144- canonicalized : OnceLock < Option < PathBuf > > ,
145- node_modules : OnceLock < Option < CachedPath > > ,
146- package_json : OnceLock < Option < Arc < PackageJson > > > ,
147- }
148-
149- impl CachedPathImpl {
150- const fn new ( hash : u64 , path : Box < Path > , parent : Option < CachedPath > ) -> Self {
151- Self {
152- hash,
153- path,
154- parent,
155- meta : OnceLock :: new ( ) ,
156- canonicalized : OnceLock :: new ( ) ,
157- node_modules : OnceLock :: new ( ) ,
158- package_json : OnceLock :: new ( ) ,
159- }
160- }
161-
162- pub const fn path ( & self ) -> & Path {
163- & self . path
139+ impl CachedPath {
140+ pub fn path ( & self ) -> & Path {
141+ & self . 0 . path
164142 }
165143
166144 pub fn to_path_buf ( & self ) -> PathBuf {
167145 self . path . to_path_buf ( )
168146 }
169147
170- pub const fn parent ( & self ) -> Option < & CachedPath > {
171- self . parent . as_ref ( )
148+ pub fn parent ( & self ) -> Option < & Self > {
149+ self . 0 . parent . as_ref ( )
172150 }
173151
174152 fn meta < Fs : FileSystem > ( & self , fs : & Fs ) -> Option < FileMetadata > {
@@ -195,30 +173,31 @@ impl CachedPathImpl {
195173 )
196174 }
197175
198- pub fn realpath < Fs : FileSystem > ( & self , fs : & Fs ) -> io:: Result < PathBuf > {
176+ pub fn realpath < Fs : FileSystem > ( & self , cache : & Cache < Fs > ) -> io:: Result < Self > {
199177 self . canonicalized
200178 . get_or_try_init ( || {
201- if fs. symlink_metadata ( & self . path ) . is_ok_and ( |m| m. is_symlink ) {
202- return fs. canonicalize ( & self . path ) . map ( Some ) ;
179+ if cache. fs . symlink_metadata ( & self . path ) . is_ok_and ( |m| m. is_symlink ) {
180+ let canonicalized = cache. fs . canonicalize ( & self . path ) ?;
181+ return Ok ( Some ( cache. value ( & canonicalized) ) ) ;
203182 }
204183 if let Some ( parent) = self . parent ( ) {
205- let parent_path = parent. realpath ( fs ) ?;
206- return Ok ( Some (
207- parent_path . normalize_with ( self . path . strip_prefix ( & parent. path ) . unwrap ( ) ) ,
208- ) ) ;
184+ let parent_path = parent. realpath ( cache ) ?;
185+ let normalized = parent_path
186+ . normalize_with ( self . path . strip_prefix ( & parent. path ) . unwrap ( ) , cache ) ;
187+ return Ok ( Some ( normalized ) ) ;
209188 } ;
210189 Ok ( None )
211190 } )
212191 . cloned ( )
213- . map ( |r| r. unwrap_or_else ( || self . path . clone ( ) . to_path_buf ( ) ) )
192+ . map ( |r| r. unwrap_or_else ( || self . clone ( ) ) )
214193 }
215194
216195 pub fn module_directory < Fs : FileSystem > (
217196 & self ,
218197 module_name : & str ,
219198 cache : & Cache < Fs > ,
220199 ctx : & mut Ctx ,
221- ) -> Option < CachedPath > {
200+ ) -> Option < Self > {
222201 let cached_path = cache. value ( & self . path . join ( module_name) ) ;
223202 cached_path. is_dir ( & cache. fs , ctx) . then_some ( cached_path)
224203 }
@@ -227,61 +206,31 @@ impl CachedPathImpl {
227206 & self ,
228207 cache : & Cache < Fs > ,
229208 ctx : & mut Ctx ,
230- ) -> Option < CachedPath > {
209+ ) -> Option < Self > {
231210 self . node_modules . get_or_init ( || self . module_directory ( "node_modules" , cache, ctx) ) . clone ( )
232211 }
233212
234- /// Find package.json of a path by traversing parent directories.
235- ///
236- /// # Errors
237- ///
238- /// * [ResolveError::JSON]
239- pub fn find_package_json < Fs : FileSystem > (
240- & self ,
241- fs : & Fs ,
242- options : & ResolveOptions ,
243- ctx : & mut Ctx ,
244- ) -> Result < Option < Arc < PackageJson > > , ResolveError > {
245- let mut cache_value = self ;
246- // Go up directories when the querying path is not a directory
247- while !cache_value. is_dir ( fs, ctx) {
248- if let Some ( cv) = & cache_value. parent {
249- cache_value = cv. as_ref ( ) ;
250- } else {
251- break ;
252- }
253- }
254- let mut cache_value = Some ( cache_value) ;
255- while let Some ( cv) = cache_value {
256- if let Some ( package_json) = cv. package_json ( fs, options, ctx) ? {
257- return Ok ( Some ( Arc :: clone ( & package_json) ) ) ;
258- }
259- cache_value = cv. parent . as_deref ( ) ;
260- }
261- Ok ( None )
262- }
263-
264213 /// Get package.json of the given path.
265214 ///
266215 /// # Errors
267216 ///
268217 /// * [ResolveError::JSON]
269218 pub fn package_json < Fs : FileSystem > (
270219 & self ,
271- fs : & Fs ,
272220 options : & ResolveOptions ,
221+ cache : & Cache < Fs > ,
273222 ctx : & mut Ctx ,
274223 ) -> Result < Option < Arc < PackageJson > > , ResolveError > {
275224 // Change to `std::sync::OnceLock::get_or_try_init` when it is stable.
276225 let result = self
277226 . package_json
278227 . get_or_try_init ( || {
279228 let package_json_path = self . path . join ( "package.json" ) ;
280- let Ok ( package_json_string) = fs. read_to_string ( & package_json_path) else {
229+ let Ok ( package_json_string) = cache . fs . read_to_string ( & package_json_path) else {
281230 return Ok ( None ) ;
282231 } ;
283232 let real_path = if options. symlinks {
284- self . realpath ( fs ) ? . join ( "package.json" )
233+ self . realpath ( cache ) ? . path ( ) . join ( "package.json" )
285234 } else {
286235 package_json_path. clone ( )
287236 } ;
@@ -311,7 +260,37 @@ impl CachedPathImpl {
311260 result
312261 }
313262
314- pub fn add_extension < Fs : FileSystem > ( & self , ext : & str , cache : & Cache < Fs > ) -> CachedPath {
263+ /// Find package.json of a path by traversing parent directories.
264+ ///
265+ /// # Errors
266+ ///
267+ /// * [ResolveError::JSON]
268+ pub fn find_package_json < Fs : FileSystem > (
269+ & self ,
270+ options : & ResolveOptions ,
271+ cache : & Cache < Fs > ,
272+ ctx : & mut Ctx ,
273+ ) -> Result < Option < Arc < PackageJson > > , ResolveError > {
274+ let mut cache_value = self ;
275+ // Go up directories when the querying path is not a directory
276+ while !cache_value. is_dir ( & cache. fs , ctx) {
277+ if let Some ( cv) = & cache_value. parent {
278+ cache_value = cv;
279+ } else {
280+ break ;
281+ }
282+ }
283+ let mut cache_value = Some ( cache_value) ;
284+ while let Some ( cv) = cache_value {
285+ if let Some ( package_json) = cv. package_json ( options, cache, ctx) ? {
286+ return Ok ( Some ( Arc :: clone ( & package_json) ) ) ;
287+ }
288+ cache_value = cv. parent . as_ref ( ) ;
289+ }
290+ Ok ( None )
291+ }
292+
293+ pub fn add_extension < Fs : FileSystem > ( & self , ext : & str , cache : & Cache < Fs > ) -> Self {
315294 SCRATCH_PATH . with ( |path| {
316295 // SAFETY: ???
317296 let path = unsafe { & mut * path. get ( ) } ;
@@ -323,7 +302,7 @@ impl CachedPathImpl {
323302 } )
324303 }
325304
326- pub fn replace_extension < Fs : FileSystem > ( & self , ext : & str , cache : & Cache < Fs > ) -> CachedPath {
305+ pub fn replace_extension < Fs : FileSystem > ( & self , ext : & str , cache : & Cache < Fs > ) -> Self {
327306 SCRATCH_PATH . with ( |path| {
328307 // SAFETY: ???
329308 let path = unsafe { & mut * path. get ( ) } ;
@@ -342,7 +321,7 @@ impl CachedPathImpl {
342321 }
343322
344323 /// Returns a new path by resolving the given subpath (including "." and ".." components) with this path.
345- pub fn normalize_with < P , Fs > ( & self , subpath : P , cache : & Cache < Fs > ) -> CachedPath
324+ pub fn normalize_with < P , Fs > ( & self , subpath : P , cache : & Cache < Fs > ) -> Self
346325 where
347326 P : AsRef < Path > ,
348327 Fs : FileSystem ,
@@ -378,6 +357,30 @@ impl CachedPathImpl {
378357 }
379358}
380359
360+ pub struct CachedPathImpl {
361+ hash : u64 ,
362+ path : Box < Path > ,
363+ parent : Option < CachedPath > ,
364+ meta : OnceLock < Option < FileMetadata > > ,
365+ canonicalized : OnceLock < Option < CachedPath > > ,
366+ node_modules : OnceLock < Option < CachedPath > > ,
367+ package_json : OnceLock < Option < Arc < PackageJson > > > ,
368+ }
369+
370+ impl CachedPathImpl {
371+ const fn new ( hash : u64 , path : Box < Path > , parent : Option < CachedPath > ) -> Self {
372+ Self {
373+ hash,
374+ path,
375+ parent,
376+ meta : OnceLock :: new ( ) ,
377+ canonicalized : OnceLock :: new ( ) ,
378+ node_modules : OnceLock :: new ( ) ,
379+ package_json : OnceLock :: new ( ) ,
380+ }
381+ }
382+ }
383+
381384/// Memoized cache key, code adapted from <https://stackoverflow.com/a/50478038>.
382385trait CacheKey {
383386 fn tuple ( & self ) -> ( u64 , & Path ) ;
0 commit comments