@@ -59,6 +59,7 @@ import {
5959 hasProperty ,
6060 hasTrailingDirectorySeparator ,
6161 hostGetCanonicalFileName ,
62+ identity ,
6263 inferredTypesContainingFile ,
6364 isArray ,
6465 isDeclarationFileName ,
@@ -1056,6 +1057,7 @@ function createPerDirectoryResolutionCache<T>(
10561057 getCanonicalFileName : GetCanonicalFileName ,
10571058 options : CompilerOptions | undefined ,
10581059 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1060+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
10591061) : PerDirectoryResolutionCache < T > {
10601062 const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < T > > ( options , optionsToRedirectsKey ) ;
10611063 return {
@@ -1081,7 +1083,7 @@ function createPerDirectoryResolutionCache<T>(
10811083
10821084 function getFromDirectoryCache ( name : string , mode : ResolutionMode , directoryName : string , redirectedReference : ResolvedProjectReference | undefined ) {
10831085 const path = toPath ( directoryName , currentDirectory , getCanonicalFileName ) ;
1084- return directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ;
1086+ return getValidResolution ( directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ) ;
10851087 }
10861088}
10871089
@@ -1145,6 +1147,7 @@ function createNonRelativeNameResolutionCache<T>(
11451147 options : CompilerOptions | undefined ,
11461148 getResolvedFileName : ( result : T ) => string | undefined ,
11471149 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1150+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
11481151) : NonRelativeNameResolutionCache < T > {
11491152 const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerNonRelativeNameCache < T > > ( options , optionsToRedirectsKey ) ;
11501153 return {
@@ -1164,12 +1167,19 @@ function createNonRelativeNameResolutionCache<T>(
11641167
11651168 function getFromNonRelativeNameCache ( nonRelativeModuleName : string , mode : ResolutionMode , directoryName : string , redirectedReference ?: ResolvedProjectReference ) : T | undefined {
11661169 Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1167- return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( createModeAwareCacheKey ( nonRelativeModuleName , mode ) ) ?. get ( directoryName ) ;
1170+ return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get (
1171+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1172+ ) ?. get ( directoryName ) ;
11681173 }
11691174
11701175 function getOrCreateCacheForNonRelativeName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerNonRelativeNameCache < T > {
11711176 Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1172- return getOrCreateCache ( moduleNameToDirectoryMap , redirectedReference , createModeAwareCacheKey ( nonRelativeModuleName , mode ) , createPerModuleNameCache ) ;
1177+ return getOrCreateCache (
1178+ moduleNameToDirectoryMap ,
1179+ redirectedReference ,
1180+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1181+ createPerModuleNameCache ,
1182+ ) ;
11731183 }
11741184
11751185 function createPerModuleNameCache ( ) : PerNonRelativeNameCache < T > {
@@ -1178,7 +1188,11 @@ function createNonRelativeNameResolutionCache<T>(
11781188 return { get, set } ;
11791189
11801190 function get ( directory : string ) : T | undefined {
1181- return directoryPathMap . get ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1191+ return getByPath ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1192+ }
1193+
1194+ function getByPath ( directoryPath : Path ) : T | undefined {
1195+ return getValidResolution ( directoryPathMap . get ( directoryPath ) ) ;
11821196 }
11831197
11841198 /**
@@ -1195,32 +1209,45 @@ function createNonRelativeNameResolutionCache<T>(
11951209 function set ( directory : string , result : T ) : void {
11961210 const path = toPath ( directory , currentDirectory , getCanonicalFileName ) ;
11971211 // if entry is already in cache do nothing
1198- if ( directoryPathMap . has ( path ) ) {
1212+ if ( getByPath ( path ) ) {
11991213 return ;
12001214 }
1215+
1216+ const existing = directoryPathMap . get ( path ) ;
1217+ // Remove invalidated result from parent
1218+ if ( existing ) {
1219+ const existingCommonPrefix = getCommonPrefix ( path , existing ) ;
1220+ withCommonPrefix ( path , existingCommonPrefix , parent => directoryPathMap . delete ( parent ) ) ;
1221+ }
1222+
12011223 directoryPathMap . set ( path , result ) ;
12021224
1203- const resolvedFileName = getResolvedFileName ( result ) ;
12041225 // find common prefix between directory and resolved file name
12051226 // this common prefix should be the shortest path that has the same resolution
12061227 // directory: /a/b/c/d/e
12071228 // resolvedFileName: /a/b/foo.d.ts
12081229 // commonPrefix: /a/b
12091230 // for failed lookups cache the result for every directory up to root
1210- const commonPrefix = resolvedFileName && getCommonPrefix ( path , resolvedFileName ) ;
1231+ const commonPrefix = getCommonPrefix ( path , result ) ;
1232+ withCommonPrefix ( path , commonPrefix , parent => directoryPathMap . set ( parent , result ) ) ;
1233+ }
1234+
1235+ function withCommonPrefix ( path : Path , commonPrefix : Path | undefined , action : ( parent : Path ) => void ) {
12111236 let current = path ;
12121237 while ( current !== commonPrefix ) {
12131238 const parent = getDirectoryPath ( current ) ;
1214- if ( parent === current || directoryPathMap . has ( parent ) ) {
1239+ if ( parent === current || getByPath ( parent ) ) {
12151240 break ;
12161241 }
1217- directoryPathMap . set ( parent , result ) ;
1242+ action ( parent ) ;
12181243 current = parent ;
12191244 }
12201245 }
12211246
1222- function getCommonPrefix ( directory : Path , resolution : string ) {
1223- const resolutionDirectory = toPath ( getDirectoryPath ( resolution ) , currentDirectory , getCanonicalFileName ) ;
1247+ function getCommonPrefix ( directory : Path , resolution : T ) {
1248+ const resolvedFileName = getResolvedFileName ( resolution ) ;
1249+ if ( ! resolvedFileName ) return undefined ;
1250+ const resolutionDirectory = toPath ( getDirectoryPath ( resolvedFileName ) , currentDirectory , getCanonicalFileName ) ;
12241251
12251252 // find first position where directory and resolution differs
12261253 let i = 0 ;
@@ -1239,7 +1266,7 @@ function createNonRelativeNameResolutionCache<T>(
12391266 if ( sep === - 1 ) {
12401267 return undefined ;
12411268 }
1242- return directory . substr ( 0 , Math . max ( sep , rootLength ) ) ;
1269+ return directory . substr ( 0 , Math . max ( sep , rootLength ) ) as Path ;
12431270 }
12441271 }
12451272}
@@ -1256,20 +1283,24 @@ function createModuleOrTypeReferenceResolutionCache<T>(
12561283 packageJsonInfoCache : PackageJsonInfoCache | undefined ,
12571284 getResolvedFileName : ( result : T ) => string | undefined ,
12581285 optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > | undefined ,
1286+ getValidResolution : ( ( resolution : T | undefined ) => T | undefined ) | undefined ,
12591287) : ModuleOrTypeReferenceResolutionCache < T > {
12601288 optionsToRedirectsKey ??= new Map ( ) ;
1289+ getValidResolution ??= identity ;
12611290 const perDirectoryResolutionCache = createPerDirectoryResolutionCache < T > (
12621291 currentDirectory ,
12631292 getCanonicalFileName ,
12641293 options ,
12651294 optionsToRedirectsKey ,
1295+ getValidResolution ,
12661296 ) ;
12671297 const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache (
12681298 currentDirectory ,
12691299 getCanonicalFileName ,
12701300 options ,
12711301 getResolvedFileName ,
12721302 optionsToRedirectsKey ,
1303+ getValidResolution ,
12731304 ) ;
12741305 packageJsonInfoCache ??= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
12751306
@@ -1313,13 +1344,15 @@ export function createModuleResolutionCache(
13131344 options ?: CompilerOptions ,
13141345 packageJsonInfoCache ?: PackageJsonInfoCache ,
13151346 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1347+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
13161348) : ModuleResolutionCache ;
13171349export function createModuleResolutionCache (
13181350 currentDirectory : string ,
13191351 getCanonicalFileName : ( s : string ) => string ,
13201352 options ?: CompilerOptions ,
13211353 packageJsonInfoCache ?: PackageJsonInfoCache ,
13221354 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1355+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
13231356) : ModuleResolutionCache {
13241357 const result = createModuleOrTypeReferenceResolutionCache (
13251358 currentDirectory ,
@@ -1328,6 +1361,7 @@ export function createModuleResolutionCache(
13281361 packageJsonInfoCache ,
13291362 getOriginalOrResolvedModuleFileName ,
13301363 optionsToRedirectsKey ,
1364+ getValidResolution ,
13311365 ) as ModuleResolutionCache ;
13321366 result . getOrCreateCacheForModuleName = ( nonRelativeName , mode , redirectedReference ) => result . getOrCreateCacheForNonRelativeName ( nonRelativeName , mode , redirectedReference ) ;
13331367 return result ;
@@ -1346,13 +1380,15 @@ export function createTypeReferenceDirectiveResolutionCache(
13461380 options ?: CompilerOptions ,
13471381 packageJsonInfoCache ?: PackageJsonInfoCache ,
13481382 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1383+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
13491384) : TypeReferenceDirectiveResolutionCache ;
13501385export function createTypeReferenceDirectiveResolutionCache (
13511386 currentDirectory : string ,
13521387 getCanonicalFileName : ( s : string ) => string ,
13531388 options ?: CompilerOptions ,
13541389 packageJsonInfoCache ?: PackageJsonInfoCache ,
13551390 optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1391+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
13561392) : TypeReferenceDirectiveResolutionCache {
13571393 return createModuleOrTypeReferenceResolutionCache (
13581394 currentDirectory ,
@@ -1361,6 +1397,7 @@ export function createTypeReferenceDirectiveResolutionCache(
13611397 packageJsonInfoCache ,
13621398 getOriginalOrResolvedTypeReferenceFileName ,
13631399 optionsToRedirectsKey ,
1400+ getValidResolution ,
13641401 ) ;
13651402}
13661403
0 commit comments