@@ -28,6 +28,7 @@ namespace ts {
28
28
interface ResolutionWithFailedLookupLocations {
29
29
readonly failedLookupLocations : ReadonlyArray < string > ;
30
30
isInvalidated ?: boolean ;
31
+ refCount ?: number ;
31
32
}
32
33
33
34
interface ResolutionWithResolvedFileName {
@@ -257,17 +258,11 @@ namespace ts {
257
258
perDirectoryResolution . set ( name , resolution ) ;
258
259
}
259
260
resolutionsInFile . set ( name , resolution ) ;
260
- if ( resolution . failedLookupLocations ) {
261
- if ( existingResolution && existingResolution . failedLookupLocations ) {
262
- watchAndStopWatchDiffFailedLookupLocations ( resolution , existingResolution ) ;
263
- }
264
- else {
265
- watchFailedLookupLocationOfResolution ( resolution , 0 ) ;
266
- }
267
- }
268
- else if ( existingResolution ) {
261
+ watchFailedLookupLocationOfResolution ( resolution ) ;
262
+ if ( existingResolution ) {
269
263
stopWatchFailedLookupLocationOfResolution ( existingResolution ) ;
270
264
}
265
+
271
266
if ( logChanges && filesWithChangedSetOfUnresolvedImports && ! resolutionIsEqualTo ( existingResolution , resolution ) ) {
272
267
filesWithChangedSetOfUnresolvedImports . push ( path ) ;
273
268
// reset log changes to avoid recording the same file multiple times
@@ -399,80 +394,98 @@ namespace ts {
399
394
return fileExtensionIsOneOf ( path , failedLookupDefaultExtensions ) ;
400
395
}
401
396
402
- function watchAndStopWatchDiffFailedLookupLocations ( resolution : ResolutionWithFailedLookupLocations , existingResolution : ResolutionWithFailedLookupLocations ) {
403
- const failedLookupLocations = resolution . failedLookupLocations ;
404
- const existingFailedLookupLocations = existingResolution . failedLookupLocations ;
405
- for ( let index = 0 ; index < failedLookupLocations . length ; index ++ ) {
406
- if ( index === existingFailedLookupLocations . length ) {
407
- // Additional failed lookup locations, watch from this index
408
- watchFailedLookupLocationOfResolution ( resolution , index ) ;
409
- return ;
410
- }
411
- else if ( failedLookupLocations [ index ] !== existingFailedLookupLocations [ index ] ) {
412
- // Different failed lookup locations,
413
- // Watch new resolution failed lookup locations from this index and
414
- // stop watching existing resolutions from this index
415
- watchFailedLookupLocationOfResolution ( resolution , index ) ;
416
- stopWatchFailedLookupLocationOfResolutionFrom ( existingResolution , index ) ;
417
- return ;
418
- }
397
+ function watchFailedLookupLocationOfResolution ( resolution : ResolutionWithFailedLookupLocations ) {
398
+ // No need to set the resolution refCount
399
+ if ( ! resolution . failedLookupLocations || ! resolution . failedLookupLocations . length ) {
400
+ return ;
419
401
}
420
402
421
- // All new failed lookup locations are already watched (and are same),
422
- // Stop watching failed lookup locations of existing resolution after failed lookup locations length
423
- stopWatchFailedLookupLocationOfResolutionFrom ( existingResolution , failedLookupLocations . length ) ;
424
- }
403
+ if ( resolution . refCount !== undefined ) {
404
+ resolution . refCount ++ ;
405
+ return ;
406
+ }
425
407
426
- function watchFailedLookupLocationOfResolution ( { failedLookupLocations } : ResolutionWithFailedLookupLocations , startIndex : number ) {
427
- for ( let i = startIndex ; i < failedLookupLocations . length ; i ++ ) {
428
- const failedLookupLocation = failedLookupLocations [ i ] ;
408
+ resolution . refCount = 1 ;
409
+ const { failedLookupLocations } = resolution ;
410
+ let setAtRoot = false ;
411
+ for ( const failedLookupLocation of failedLookupLocations ) {
429
412
const failedLookupLocationPath = resolutionHost . toPath ( failedLookupLocation ) ;
430
- // If the failed lookup location path is not one of the supported extensions,
431
- // store it in the custom path
432
- if ( ! isPathWithDefaultFailedLookupExtension ( failedLookupLocationPath ) ) {
433
- const refCount = customFailedLookupPaths . get ( failedLookupLocationPath ) || 0 ;
434
- customFailedLookupPaths . set ( failedLookupLocationPath , refCount + 1 ) ;
435
- }
436
413
const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation ( failedLookupLocation , failedLookupLocationPath ) ;
437
414
if ( ! ignore ) {
438
- const dirWatcher = directoryWatchesOfFailedLookups . get ( dirPath ) ;
439
- if ( dirWatcher ) {
440
- dirWatcher . refCount ++ ;
415
+ // If the failed lookup location path is not one of the supported extensions,
416
+ // store it in the custom path
417
+ if ( ! isPathWithDefaultFailedLookupExtension ( failedLookupLocationPath ) ) {
418
+ const refCount = customFailedLookupPaths . get ( failedLookupLocationPath ) || 0 ;
419
+ customFailedLookupPaths . set ( failedLookupLocationPath , refCount + 1 ) ;
420
+ }
421
+ if ( dirPath === rootPath ) {
422
+ setAtRoot = true ;
441
423
}
442
424
else {
443
- directoryWatchesOfFailedLookups . set ( dirPath , { watcher : createDirectoryWatcher ( dir , dirPath ) , refCount : 1 } ) ;
425
+ setDirectoryWatcher ( dir , dirPath ) ;
444
426
}
445
427
}
446
428
}
429
+
430
+ if ( setAtRoot ) {
431
+ setDirectoryWatcher ( rootDir , rootPath ) ;
432
+ }
447
433
}
448
434
449
- function stopWatchFailedLookupLocationOfResolution ( resolution : ResolutionWithFailedLookupLocations ) {
450
- if ( resolution . failedLookupLocations ) {
451
- stopWatchFailedLookupLocationOfResolutionFrom ( resolution , 0 ) ;
435
+ function setDirectoryWatcher ( dir : string , dirPath : Path ) {
436
+ const dirWatcher = directoryWatchesOfFailedLookups . get ( dirPath ) ;
437
+ if ( dirWatcher ) {
438
+ dirWatcher . refCount ++ ;
439
+ }
440
+ else {
441
+ directoryWatchesOfFailedLookups . set ( dirPath , { watcher : createDirectoryWatcher ( dir , dirPath ) , refCount : 1 } ) ;
452
442
}
453
443
}
454
444
455
- function stopWatchFailedLookupLocationOfResolutionFrom ( { failedLookupLocations } : ResolutionWithFailedLookupLocations , startIndex : number ) {
456
- for ( let i = startIndex ; i < failedLookupLocations . length ; i ++ ) {
457
- const failedLookupLocation = failedLookupLocations [ i ] ;
445
+ function stopWatchFailedLookupLocationOfResolution ( resolution : ResolutionWithFailedLookupLocations ) {
446
+ if ( ! resolution . failedLookupLocations || ! resolution . failedLookupLocations . length ) {
447
+ return ;
448
+ }
449
+
450
+ resolution . refCount ! -- ;
451
+ if ( resolution . refCount ) {
452
+ return ;
453
+ }
454
+
455
+ const { failedLookupLocations } = resolution ;
456
+ let removeAtRoot = false ;
457
+ for ( const failedLookupLocation of failedLookupLocations ) {
458
458
const failedLookupLocationPath = resolutionHost . toPath ( failedLookupLocation ) ;
459
- const refCount = customFailedLookupPaths . get ( failedLookupLocationPath ) ;
460
- if ( refCount ) {
461
- if ( refCount === 1 ) {
462
- customFailedLookupPaths . delete ( failedLookupLocationPath ) ;
459
+ const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation ( failedLookupLocation , failedLookupLocationPath ) ;
460
+ if ( ! ignore ) {
461
+ const refCount = customFailedLookupPaths . get ( failedLookupLocationPath ) ;
462
+ if ( refCount ) {
463
+ if ( refCount === 1 ) {
464
+ customFailedLookupPaths . delete ( failedLookupLocationPath ) ;
465
+ }
466
+ else {
467
+ Debug . assert ( refCount > 1 ) ;
468
+ customFailedLookupPaths . set ( failedLookupLocationPath , refCount - 1 ) ;
469
+ }
470
+ }
471
+
472
+ if ( dirPath === rootPath ) {
473
+ removeAtRoot = true ;
463
474
}
464
475
else {
465
- Debug . assert ( refCount > 1 ) ;
466
- customFailedLookupPaths . set ( failedLookupLocationPath , refCount - 1 ) ;
476
+ removeDirectoryWatcher ( dirPath ) ;
467
477
}
468
478
}
469
- const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation ( failedLookupLocation , failedLookupLocationPath ) ;
470
- if ( ! ignore ) {
471
- const dirWatcher = directoryWatchesOfFailedLookups . get ( dirPath ) ;
472
- // Do not close the watcher yet since it might be needed by other failed lookup locations.
473
- dirWatcher . refCount -- ;
474
- }
475
479
}
480
+ if ( removeAtRoot ) {
481
+ removeDirectoryWatcher ( rootPath ) ;
482
+ }
483
+ }
484
+
485
+ function removeDirectoryWatcher ( dirPath : string ) {
486
+ const dirWatcher = directoryWatchesOfFailedLookups . get ( dirPath ) ;
487
+ // Do not close the watcher yet since it might be needed by other failed lookup locations.
488
+ dirWatcher . refCount -- ;
476
489
}
477
490
478
491
function createDirectoryWatcher ( directory : string , dirPath : Path ) {
0 commit comments