77 CompilerOptions ,
88 createModeAwareCache ,
99 createModuleResolutionCache ,
10+ CreateSourceFileOptions ,
1011 createTypeReferenceDirectiveResolutionCache ,
1112 createTypeReferenceResolutionLoader ,
1213 Debug ,
@@ -53,7 +54,6 @@ import {
5354 noopFileWatcher ,
5455 normalizePath ,
5556 packageIdToString ,
56- PackageJsonInfoCacheEntry ,
5757 parseNodeModuleFromPath ,
5858 Path ,
5959 PathPathComponents ,
@@ -111,6 +111,7 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
111111 resolvedFileToResolution : Map < Path , Set < ResolutionWithFailedLookupLocations > > ;
112112 resolutionsWithFailedLookups : Set < ResolutionWithFailedLookupLocations > ;
113113 resolutionsWithOnlyAffectingLocations : Set < ResolutionWithFailedLookupLocations > ;
114+ packageJsonRefCount : Map < Path , number > ;
114115 directoryWatchesOfFailedLookups : Map < Path , DirectoryWatchesOfFailedLookup > ;
115116 fileWatchesOfAffectingLocations : Map < string , FileWatcherOfAffectingLocation > ;
116117 packageDirWatchers : Map < Path , PackageDirWatcher > ;
@@ -693,6 +694,8 @@ export function createResolutionCache(
693694 let resolutionsResolvedWithGlobalCache = 0 ;
694695 let resolutionsResolvedWithoutGlobalCache = 0 ;
695696
697+ const packageJsonRefCount = new Map < Path , number > ( ) ;
698+ let potentiallyUnwatchedPackageJsons : Set < Path > | undefined ;
696699 const directoryWatchesOfFailedLookups = new Map < Path , DirectoryWatchesOfFailedLookup > ( ) ;
697700 const fileWatchesOfAffectingLocations = new Map < string , FileWatcherOfAffectingLocation > ( ) ;
698701 const rootDir = getRootDirectoryOfResolutionCache ( rootDirForResolution , getCurrentDirectory ) ;
@@ -718,6 +721,7 @@ export function createResolutionCache(
718721 resolvedFileToResolution,
719722 resolutionsWithFailedLookups,
720723 resolutionsWithOnlyAffectingLocations,
724+ packageJsonRefCount,
721725 directoryWatchesOfFailedLookups,
722726 fileWatchesOfAffectingLocations,
723727 packageDirWatchers,
@@ -734,6 +738,7 @@ export function createResolutionCache(
734738 resolveTypeReferenceDirectiveReferences,
735739 onReusedModuleResolutions,
736740 onReusedTypeReferenceDirectiveResolutions,
741+ onSourceFileNotCreated,
737742 resolveLibrary,
738743 resolveSingleModuleNameWithoutWatching,
739744 removeResolutionsFromProjectReferenceRedirects,
@@ -754,9 +759,11 @@ export function createResolutionCache(
754759 function clear ( ) {
755760 potentiallyUnreferencedResolutions = undefined ;
756761 potentiallyUnreferencedDirWatchers = undefined ;
762+ potentiallyUnwatchedPackageJsons = undefined ;
757763 newUnresolvedResolutionCachePassResolutions = undefined ;
758764 clearMap ( directoryWatchesOfFailedLookups , closeFileWatcherOf ) ;
759765 clearMap ( fileWatchesOfAffectingLocations , closeFileWatcherOf ) ;
766+ packageJsonRefCount . clear ( ) ;
760767 isSymlinkCache . clear ( ) ;
761768 packageDirWatchers . clear ( ) ;
762769 dirPathToSymlinkPackageRefCount . clear ( ) ;
@@ -890,6 +897,8 @@ export function createResolutionCache(
890897 potentiallyUnreferencedResolutions = undefined ;
891898 }
892899 hasChangedAutomaticTypeDirectiveNames = false ;
900+ potentiallyUnwatchedPackageJsons ?. forEach ( releasePotentiallyUnwatchedPackageJson ) ;
901+ potentiallyUnwatchedPackageJsons = undefined ;
893902 if ( ! skipCacheCompact ) compactCaches ( newProgram ) ;
894903 moduleResolutionCache . isReadonly = true ;
895904 typeReferenceDirectiveResolutionCache . isReadonly = true ;
@@ -954,13 +963,37 @@ export function createResolutionCache(
954963 }
955964 }
956965
966+ function releasePotentiallyUnwatchedPackageJson ( path : Path ) {
967+ if ( ! packageJsonRefCount . has ( path ) ) moduleResolutionCache . getPackageJsonInfoCache ( ) . getInternalMap ( ) ?. delete ( path ) ;
968+ }
969+
970+ function releasePackageJsonCachePath ( path : Path ) {
971+ moduleResolutionCache . getPackageJsonInfoCache ( ) . getInternalMap ( ) ?. delete ( path ) ;
972+ packageJsonRefCount . delete ( path ) ;
973+ }
974+
975+ function releasePackageJson ( path : Path ) {
976+ const existing = packageJsonRefCount . get ( path ) ! ;
977+ if ( existing !== 1 ) packageJsonRefCount . set ( path , existing - 1 ) ;
978+ else releasePackageJsonCachePath ( path ) ;
979+ }
980+
981+ function addRefToPackageJson ( path : Path ) {
982+ packageJsonRefCount . set ( path , ( packageJsonRefCount . get ( path ) ?? 0 ) + 1 ) ;
983+ }
984+
957985 function closeFileWatcherOfAffectingLocation ( watcher : FileWatcherOfAffectingLocation , path : string ) {
958986 if ( watcher . files === 0 && watcher . resolutions === 0 && ! watcher . symlinks ?. size ) {
959987 fileWatchesOfAffectingLocations . delete ( path ) ;
988+ releasePackageJson ( resolutionHost . toPath ( path ) ) ;
960989 watcher . watcher . close ( ) ;
961990 }
962991 }
963992
993+ function onSourceFileNotCreated ( sourceFileOptions : CreateSourceFileOptions ) {
994+ sourceFileOptions . packageJsonLocations ?. forEach ( addToPotentiallyUnwatchedPackageJsons ) ;
995+ }
996+
964997 function getValidResolution < T extends ResolutionWithFailedLookupLocations > ( resolution : T | undefined ) {
965998 return isInvalidatedResolution ( resolution ) ? undefined : resolution ;
966999 }
@@ -1301,6 +1334,14 @@ export function createResolutionCache(
13011334 watchFailedLookupLocationOfResolution ( resolution ) ;
13021335 watchAffectingLocationsOfResolution ( resolution ) ;
13031336 if ( ! firstTime ) return ;
1337+ if ( resolution . globalCacheResolution && ! resolution . globalCacheResolution . resolution . resolvedModule ) {
1338+ // Add to potentially unreferenced resolutions
1339+ resolution . globalCacheResolution . resolution . failedLookupLocations ?. forEach (
1340+ addToPotentiallyUnwatchedPackageJsonsIfPackageJson ,
1341+ ) ;
1342+ if ( resolution . globalCacheResolution . resolution . alternateResult ) addToPotentiallyUnwatchedPackageJsonsIfPackageJson ( resolution . globalCacheResolution . resolution . alternateResult ) ;
1343+ resolution . globalCacheResolution . resolution . affectingLocations ?. forEach ( addToPotentiallyUnwatchedPackageJsons ) ;
1344+ }
13041345 if ( isResolvedWithGlobalCachePass ( resolution ) ) resolutionsResolvedWithGlobalCache ++ ;
13051346 else if ( isResolvedWithoutGlobalCachePass ( resolution ) ) resolutionsResolvedWithoutGlobalCache ++ ;
13061347 const resolved = getResolutionWithResolvedFileName ( resolution ) ;
@@ -1312,8 +1353,17 @@ export function createResolutionCache(
13121353 }
13131354 }
13141355
1356+ function addToPotentiallyUnwatchedPackageJsonsIfPackageJson ( location : string ) {
1357+ if ( endsWith ( location , "/package.json" ) ) addToPotentiallyUnwatchedPackageJsons ( location ) ;
1358+ }
1359+
1360+ function addToPotentiallyUnwatchedPackageJsons ( location : string ) {
1361+ ( potentiallyUnwatchedPackageJsons ??= new Set ( ) ) . add ( resolutionHost . toPath ( location ) ) ;
1362+ }
1363+
13151364 function watchFailedLookupLocation ( failedLookupLocation : string ) {
13161365 const failedLookupLocationPath = resolutionHost . toPath ( failedLookupLocation ) ;
1366+ if ( endsWith ( failedLookupLocationPath , "/package.json" ) ) addRefToPackageJson ( failedLookupLocationPath ) ;
13171367 const toWatch = getDirectoryToWatchFailedLookupLocation (
13181368 failedLookupLocation ,
13191369 failedLookupLocationPath ,
@@ -1398,14 +1448,15 @@ export function createResolutionCache(
13981448 watcher : canWatchAffectingLocation ( resolutionHost . toPath ( locationToWatch ) ) ?
13991449 resolutionHost . watchAffectingFileLocation ( locationToWatch , ( fileName , eventKind ) => {
14001450 cachedDirectoryStructureHost ?. addOrDeleteFile ( fileName , resolutionHost . toPath ( locationToWatch ) , eventKind ) ;
1401- invalidateAffectingFileWatcher ( locationToWatch , moduleResolutionCache . getPackageJsonInfoCache ( ) . getInternalMap ( ) ) ;
1451+ invalidateAffectingFileWatcher ( locationToWatch ) ;
14021452 resolutionHost . scheduleInvalidateResolutionsOfFailedLookupLocations ( ) ;
14031453 } ) : noopFileWatcher ,
14041454 resolutions : isSymlink ? 0 : resolutions ,
14051455 files : isSymlink ? 0 : files ,
14061456 symlinks : undefined ,
14071457 } ;
14081458 fileWatchesOfAffectingLocations . set ( locationToWatch , watcher ) ;
1459+ addRefToPackageJson ( resolutionHost . toPath ( locationToWatch ) ) ;
14091460 if ( isSymlink ) symlinkWatcher = watcher ;
14101461 }
14111462 if ( isSymlink ) {
@@ -1417,6 +1468,7 @@ export function createResolutionCache(
14171468 // Close symlink watcher if no ref
14181469 if ( symlinkWatcher ?. symlinks ?. delete ( affectingLocation ) && ! symlinkWatcher . symlinks . size && ! symlinkWatcher . resolutions && ! symlinkWatcher . files ) {
14191470 fileWatchesOfAffectingLocations . delete ( locationToWatch ) ;
1471+ releasePackageJson ( resolutionHost . toPath ( locationToWatch ) ) ;
14201472 symlinkWatcher . watcher . close ( ) ;
14211473 }
14221474 } ,
@@ -1426,16 +1478,17 @@ export function createResolutionCache(
14261478 symlinks : undefined ,
14271479 } ;
14281480 fileWatchesOfAffectingLocations . set ( affectingLocation , watcher ) ;
1481+ addRefToPackageJson ( resolutionHost . toPath ( affectingLocation ) ) ;
14291482 ( symlinkWatcher . symlinks ??= new Set ( ) ) . add ( affectingLocation ) ;
14301483 }
14311484 }
14321485
1433- function invalidateAffectingFileWatcher ( path : string , packageJsonMap : Map < Path , PackageJsonInfoCacheEntry > | undefined ) {
1486+ function invalidateAffectingFileWatcher ( path : string ) {
14341487 const watcher = fileWatchesOfAffectingLocations . get ( path ) ;
14351488 if ( watcher ?. resolutions ) ( affectingPathChecks ??= new Set ( ) ) . add ( path ) ;
14361489 if ( watcher ?. files ) ( affectingPathChecksForFile ??= new Set ( ) ) . add ( path ) ;
1437- watcher ?. symlinks ?. forEach ( path => invalidateAffectingFileWatcher ( path , packageJsonMap ) ) ;
1438- packageJsonMap ?. delete ( resolutionHost . toPath ( path ) ) ;
1490+ moduleResolutionCache . getPackageJsonInfoCache ( ) . getInternalMap ( ) ?. delete ( resolutionHost . toPath ( path ) ) ;
1491+ watcher ?. symlinks ?. forEach ( path => invalidateAffectingFileWatcher ( path ) ) ;
14391492 }
14401493
14411494 function createDirectoryWatcherForPackageDir (
@@ -1523,6 +1576,7 @@ export function createResolutionCache(
15231576
15241577 function stopWatchFailedLookupLocation ( failedLookupLocation : string ) {
15251578 const failedLookupLocationPath = resolutionHost . toPath ( failedLookupLocation ) ;
1579+ if ( endsWith ( failedLookupLocationPath , "/package.json" ) ) releasePackageJson ( failedLookupLocationPath ) ;
15261580 const toWatch = getDirectoryToWatchFailedLookupLocation (
15271581 failedLookupLocation ,
15281582 failedLookupLocationPath ,
0 commit comments