@@ -57,6 +57,7 @@ import {
5757 hasProperty ,
5858 hasTrailingDirectorySeparator ,
5959 hostGetCanonicalFileName ,
60+ identity ,
6061 inferredTypesContainingFile ,
6162 isArray ,
6263 isDeclarationFileName ,
@@ -1074,6 +1075,7 @@ function createPerDirectoryResolutionCache<T>(
10741075 getCanonicalFileName : GetCanonicalFileName ,
10751076 options : CompilerOptions | undefined ,
10761077 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1078+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
10771079) : PerDirectoryResolutionCache < T > {
10781080 const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < T > > ( options , optionsToRedirectsKey ) ;
10791081 return {
@@ -1099,7 +1101,7 @@ function createPerDirectoryResolutionCache<T>(
10991101
11001102 function getFromDirectoryCache ( name : string , mode : ResolutionMode , directoryName : string , redirectedReference : ResolvedProjectReference | undefined ) {
11011103 const path = toPath ( directoryName , currentDirectory , getCanonicalFileName ) ;
1102- return directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ;
1104+ return getValidResolution ( directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ) ;
11031105 }
11041106}
11051107
@@ -1163,6 +1165,7 @@ function createNonRelativeNameResolutionCache<T>(
11631165 options : CompilerOptions | undefined ,
11641166 getResolvedFileName : ( result : T ) => string | undefined ,
11651167 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1168+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
11661169) : NonRelativeNameResolutionCache < T > {
11671170 const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerNonRelativeNameCache < T > > ( options , optionsToRedirectsKey ) ;
11681171 return {
@@ -1182,12 +1185,19 @@ function createNonRelativeNameResolutionCache<T>(
11821185
11831186 function getFromNonRelativeNameCache ( nonRelativeModuleName : string , mode : ResolutionMode , directoryName : string , redirectedReference ?: ResolvedProjectReference ) : T | undefined {
11841187 Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1185- return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( createModeAwareCacheKey ( nonRelativeModuleName , mode ) ) ?. get ( directoryName ) ;
1188+ return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get (
1189+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1190+ ) ?. get ( directoryName ) ;
11861191 }
11871192
11881193 function getOrCreateCacheForNonRelativeName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerNonRelativeNameCache < T > {
11891194 Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1190- return getOrCreateCache ( moduleNameToDirectoryMap , redirectedReference , createModeAwareCacheKey ( nonRelativeModuleName , mode ) , createPerModuleNameCache ) ;
1195+ return getOrCreateCache (
1196+ moduleNameToDirectoryMap ,
1197+ redirectedReference ,
1198+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1199+ createPerModuleNameCache ,
1200+ ) ;
11911201 }
11921202
11931203 function createPerModuleNameCache ( ) : PerNonRelativeNameCache < T > {
@@ -1196,7 +1206,11 @@ function createNonRelativeNameResolutionCache<T>(
11961206 return { get, set } ;
11971207
11981208 function get ( directory : string ) : T | undefined {
1199- return directoryPathMap . get ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1209+ return getByPath ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1210+ }
1211+
1212+ function getByPath ( directoryPath : Path ) : T | undefined {
1213+ return getValidResolution ( directoryPathMap . get ( directoryPath ) ) ;
12001214 }
12011215
12021216 /**
@@ -1213,32 +1227,45 @@ function createNonRelativeNameResolutionCache<T>(
12131227 function set ( directory : string , result : T ) : void {
12141228 const path = toPath ( directory , currentDirectory , getCanonicalFileName ) ;
12151229 // if entry is already in cache do nothing
1216- if ( directoryPathMap . has ( path ) ) {
1230+ if ( getByPath ( path ) ) {
12171231 return ;
12181232 }
1233+
1234+ const existing = directoryPathMap . get ( path ) ;
1235+ // Remove invalidated result from parent
1236+ if ( existing ) {
1237+ const existingCommonPrefix = getCommonPrefix ( path , existing ) ;
1238+ withCommonPrefix ( path , existingCommonPrefix , parent => directoryPathMap . delete ( parent ) ) ;
1239+ }
1240+
12191241 directoryPathMap . set ( path , result ) ;
12201242
1221- const resolvedFileName = getResolvedFileName ( result ) ;
12221243 // find common prefix between directory and resolved file name
12231244 // this common prefix should be the shortest path that has the same resolution
12241245 // directory: /a/b/c/d/e
12251246 // resolvedFileName: /a/b/foo.d.ts
12261247 // commonPrefix: /a/b
12271248 // for failed lookups cache the result for every directory up to root
1228- const commonPrefix = resolvedFileName && getCommonPrefix ( path , resolvedFileName ) ;
1249+ const commonPrefix = getCommonPrefix ( path , result ) ;
1250+ withCommonPrefix ( path , commonPrefix , parent => directoryPathMap . set ( parent , result ) ) ;
1251+ }
1252+
1253+ function withCommonPrefix ( path : Path , commonPrefix : Path | undefined , action : ( parent : Path ) => void ) {
12291254 let current = path ;
12301255 while ( current !== commonPrefix ) {
12311256 const parent = getDirectoryPath ( current ) ;
1232- if ( parent === current || directoryPathMap . has ( parent ) ) {
1257+ if ( parent === current || getByPath ( parent ) ) {
12331258 break ;
12341259 }
1235- directoryPathMap . set ( parent , result ) ;
1260+ action ( parent ) ;
12361261 current = parent ;
12371262 }
12381263 }
12391264
1240- function getCommonPrefix ( directory : Path , resolution : string ) {
1241- const resolutionDirectory = toPath ( getDirectoryPath ( resolution ) , currentDirectory , getCanonicalFileName ) ;
1265+ function getCommonPrefix ( directory : Path , resolution : T ) {
1266+ const resolvedFileName = getResolvedFileName ( resolution ) ;
1267+ if ( ! resolvedFileName ) return undefined ;
1268+ const resolutionDirectory = toPath ( getDirectoryPath ( resolvedFileName ) , currentDirectory , getCanonicalFileName ) ;
12421269
12431270 // find first position where directory and resolution differs
12441271 let i = 0 ;
@@ -1257,7 +1284,7 @@ function createNonRelativeNameResolutionCache<T>(
12571284 if ( sep === - 1 ) {
12581285 return undefined ;
12591286 }
1260- return directory . substr ( 0 , Math . max ( sep , rootLength ) ) ;
1287+ return directory . substr ( 0 , Math . max ( sep , rootLength ) ) as Path ;
12611288 }
12621289 }
12631290}
@@ -1274,20 +1301,24 @@ function createModuleOrTypeReferenceResolutionCache<T>(
12741301 packageJsonInfoCache : PackageJsonInfoCache | undefined ,
12751302 getResolvedFileName : ( result : T ) => string | undefined ,
12761303 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > | undefined ,
1304+ getValidResolution : ( ( resolution : T | undefined ) => T | undefined ) | undefined ,
12771305) : ModuleOrTypeReferenceResolutionCache < T > {
12781306 optionsToRedirectsKey ??= new Map ( ) ;
1307+ getValidResolution ??= identity ;
12791308 const perDirectoryResolutionCache = createPerDirectoryResolutionCache < T > (
12801309 currentDirectory ,
12811310 getCanonicalFileName ,
12821311 options ,
12831312 optionsToRedirectsKey ,
1313+ getValidResolution ,
12841314 ) ;
12851315 const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache (
12861316 currentDirectory ,
12871317 getCanonicalFileName ,
12881318 options ,
12891319 getResolvedFileName ,
12901320 optionsToRedirectsKey ,
1321+ getValidResolution ,
12911322 ) ;
12921323 packageJsonInfoCache ??= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
12931324
@@ -1330,14 +1361,18 @@ export function createModuleResolutionCache(
13301361 getCanonicalFileName : ( s : string ) => string ,
13311362 options ?: CompilerOptions ,
13321363 packageJsonInfoCache ?: PackageJsonInfoCache ,
1333- optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > , // eslint-disable-line @typescript-eslint/unified-signatures
1364+ optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1365+ getValidResolution ?: ( // eslint-disable-line @typescript-eslint/unified-signatures
1366+ resolution : ResolvedModuleWithFailedLookupLocations | undefined ,
1367+ ) => ResolvedModuleWithFailedLookupLocations | undefined ,
13341368) : ModuleResolutionCache ;
13351369export function createModuleResolutionCache (
13361370 currentDirectory : string ,
13371371 getCanonicalFileName : ( s : string ) => string ,
13381372 options ?: CompilerOptions ,
13391373 packageJsonInfoCache ?: PackageJsonInfoCache ,
13401374 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1375+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
13411376) : ModuleResolutionCache {
13421377 const result = createModuleOrTypeReferenceResolutionCache (
13431378 currentDirectory ,
@@ -1346,6 +1381,7 @@ export function createModuleResolutionCache(
13461381 packageJsonInfoCache ,
13471382 getOriginalOrResolvedModuleFileName ,
13481383 optionsToRedirectsKey ,
1384+ getValidResolution ,
13491385 ) as ModuleResolutionCache ;
13501386 result . getOrCreateCacheForModuleName = ( nonRelativeName , mode , redirectedReference ) => result . getOrCreateCacheForNonRelativeName ( nonRelativeName , mode , redirectedReference ) ;
13511387 return result ;
@@ -1363,14 +1399,18 @@ export function createTypeReferenceDirectiveResolutionCache(
13631399 getCanonicalFileName : ( s : string ) => string ,
13641400 options ?: CompilerOptions ,
13651401 packageJsonInfoCache ?: PackageJsonInfoCache ,
1366- optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > , // eslint-disable-line @typescript-eslint/unified-signatures
1402+ optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1403+ getValidResolution ?: ( // eslint-disable-line @typescript-eslint/unified-signatures
1404+ resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1405+ ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
13671406) : TypeReferenceDirectiveResolutionCache ;
13681407export function createTypeReferenceDirectiveResolutionCache (
13691408 currentDirectory : string ,
13701409 getCanonicalFileName : ( s : string ) => string ,
13711410 options ?: CompilerOptions ,
13721411 packageJsonInfoCache ?: PackageJsonInfoCache ,
13731412 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1413+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
13741414) : TypeReferenceDirectiveResolutionCache {
13751415 return createModuleOrTypeReferenceResolutionCache (
13761416 currentDirectory ,
@@ -1379,6 +1419,7 @@ export function createTypeReferenceDirectiveResolutionCache(
13791419 packageJsonInfoCache ,
13801420 getOriginalOrResolvedTypeReferenceFileName ,
13811421 optionsToRedirectsKey ,
1422+ getValidResolution ,
13821423 ) ;
13831424}
13841425
0 commit comments