@@ -58,6 +58,7 @@ import {
58
58
hasProperty ,
59
59
hasTrailingDirectorySeparator ,
60
60
hostGetCanonicalFileName ,
61
+ identity ,
61
62
inferredTypesContainingFile ,
62
63
isArray ,
63
64
isDeclarationFileName ,
@@ -1064,6 +1065,7 @@ function createPerDirectoryResolutionCache<T>(
1064
1065
getCanonicalFileName : GetCanonicalFileName ,
1065
1066
options : CompilerOptions | undefined ,
1066
1067
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1068
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1067
1069
) : PerDirectoryResolutionCache < T > {
1068
1070
const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < T > > ( options , optionsToRedirectsKey ) ;
1069
1071
return {
@@ -1089,7 +1091,7 @@ function createPerDirectoryResolutionCache<T>(
1089
1091
1090
1092
function getFromDirectoryCache ( name : string , mode : ResolutionMode , directoryName : string , redirectedReference : ResolvedProjectReference | undefined ) {
1091
1093
const path = toPath ( directoryName , currentDirectory , getCanonicalFileName ) ;
1092
- return directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ;
1094
+ return getValidResolution ( directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ) ;
1093
1095
}
1094
1096
}
1095
1097
@@ -1153,6 +1155,7 @@ function createNonRelativeNameResolutionCache<T>(
1153
1155
options : CompilerOptions | undefined ,
1154
1156
getResolvedFileName : ( result : T ) => string | undefined ,
1155
1157
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1158
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1156
1159
) : NonRelativeNameResolutionCache < T > {
1157
1160
const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerNonRelativeNameCache < T > > ( options , optionsToRedirectsKey ) ;
1158
1161
return {
@@ -1172,12 +1175,19 @@ function createNonRelativeNameResolutionCache<T>(
1172
1175
1173
1176
function getFromNonRelativeNameCache ( nonRelativeModuleName : string , mode : ResolutionMode , directoryName : string , redirectedReference ?: ResolvedProjectReference ) : T | undefined {
1174
1177
Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1175
- return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( createModeAwareCacheKey ( nonRelativeModuleName , mode ) ) ?. get ( directoryName ) ;
1178
+ return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get (
1179
+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1180
+ ) ?. get ( directoryName ) ;
1176
1181
}
1177
1182
1178
1183
function getOrCreateCacheForNonRelativeName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerNonRelativeNameCache < T > {
1179
1184
Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1180
- return getOrCreateCache ( moduleNameToDirectoryMap , redirectedReference , createModeAwareCacheKey ( nonRelativeModuleName , mode ) , createPerModuleNameCache ) ;
1185
+ return getOrCreateCache (
1186
+ moduleNameToDirectoryMap ,
1187
+ redirectedReference ,
1188
+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1189
+ createPerModuleNameCache ,
1190
+ ) ;
1181
1191
}
1182
1192
1183
1193
function createPerModuleNameCache ( ) : PerNonRelativeNameCache < T > {
@@ -1186,7 +1196,11 @@ function createNonRelativeNameResolutionCache<T>(
1186
1196
return { get, set } ;
1187
1197
1188
1198
function get ( directory : string ) : T | undefined {
1189
- return directoryPathMap . get ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1199
+ return getByPath ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1200
+ }
1201
+
1202
+ function getByPath ( directoryPath : Path ) : T | undefined {
1203
+ return getValidResolution ( directoryPathMap . get ( directoryPath ) ) ;
1190
1204
}
1191
1205
1192
1206
/**
@@ -1203,32 +1217,45 @@ function createNonRelativeNameResolutionCache<T>(
1203
1217
function set ( directory : string , result : T ) : void {
1204
1218
const path = toPath ( directory , currentDirectory , getCanonicalFileName ) ;
1205
1219
// if entry is already in cache do nothing
1206
- if ( directoryPathMap . has ( path ) ) {
1220
+ if ( getByPath ( path ) ) {
1207
1221
return ;
1208
1222
}
1223
+
1224
+ const existing = directoryPathMap . get ( path ) ;
1225
+ // Remove invalidated result from parent
1226
+ if ( existing ) {
1227
+ const existingCommonPrefix = getCommonPrefix ( path , existing ) ;
1228
+ withCommonPrefix ( path , existingCommonPrefix , parent => directoryPathMap . delete ( parent ) ) ;
1229
+ }
1230
+
1209
1231
directoryPathMap . set ( path , result ) ;
1210
1232
1211
- const resolvedFileName = getResolvedFileName ( result ) ;
1212
1233
// find common prefix between directory and resolved file name
1213
1234
// this common prefix should be the shortest path that has the same resolution
1214
1235
// directory: /a/b/c/d/e
1215
1236
// resolvedFileName: /a/b/foo.d.ts
1216
1237
// commonPrefix: /a/b
1217
1238
// for failed lookups cache the result for every directory up to root
1218
- const commonPrefix = resolvedFileName && getCommonPrefix ( path , resolvedFileName ) ;
1239
+ const commonPrefix = getCommonPrefix ( path , result ) ;
1240
+ withCommonPrefix ( path , commonPrefix , parent => directoryPathMap . set ( parent , result ) ) ;
1241
+ }
1242
+
1243
+ function withCommonPrefix ( path : Path , commonPrefix : Path | undefined , action : ( parent : Path ) => void ) {
1219
1244
let current = path ;
1220
1245
while ( current !== commonPrefix ) {
1221
1246
const parent = getDirectoryPath ( current ) ;
1222
- if ( parent === current || directoryPathMap . has ( parent ) ) {
1247
+ if ( parent === current || getByPath ( parent ) ) {
1223
1248
break ;
1224
1249
}
1225
- directoryPathMap . set ( parent , result ) ;
1250
+ action ( parent ) ;
1226
1251
current = parent ;
1227
1252
}
1228
1253
}
1229
1254
1230
- function getCommonPrefix ( directory : Path , resolution : string ) {
1231
- const resolutionDirectory = toPath ( getDirectoryPath ( resolution ) , currentDirectory , getCanonicalFileName ) ;
1255
+ function getCommonPrefix ( directory : Path , resolution : T ) {
1256
+ const resolvedFileName = getResolvedFileName ( resolution ) ;
1257
+ if ( ! resolvedFileName ) return undefined ;
1258
+ const resolutionDirectory = toPath ( getDirectoryPath ( resolvedFileName ) , currentDirectory , getCanonicalFileName ) ;
1232
1259
1233
1260
// find first position where directory and resolution differs
1234
1261
let i = 0 ;
@@ -1247,7 +1274,7 @@ function createNonRelativeNameResolutionCache<T>(
1247
1274
if ( sep === - 1 ) {
1248
1275
return undefined ;
1249
1276
}
1250
- return directory . substr ( 0 , Math . max ( sep , rootLength ) ) ;
1277
+ return directory . substr ( 0 , Math . max ( sep , rootLength ) ) as Path ;
1251
1278
}
1252
1279
}
1253
1280
}
@@ -1264,20 +1291,24 @@ function createModuleOrTypeReferenceResolutionCache<T>(
1264
1291
packageJsonInfoCache : PackageJsonInfoCache | undefined ,
1265
1292
getResolvedFileName : ( result : T ) => string | undefined ,
1266
1293
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > | undefined ,
1294
+ getValidResolution : ( ( resolution : T | undefined ) => T | undefined ) | undefined ,
1267
1295
) : ModuleOrTypeReferenceResolutionCache < T > {
1268
1296
optionsToRedirectsKey ??= new Map ( ) ;
1297
+ getValidResolution ??= identity ;
1269
1298
const perDirectoryResolutionCache = createPerDirectoryResolutionCache < T > (
1270
1299
currentDirectory ,
1271
1300
getCanonicalFileName ,
1272
1301
options ,
1273
1302
optionsToRedirectsKey ,
1303
+ getValidResolution ,
1274
1304
) ;
1275
1305
const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache (
1276
1306
currentDirectory ,
1277
1307
getCanonicalFileName ,
1278
1308
options ,
1279
1309
getResolvedFileName ,
1280
1310
optionsToRedirectsKey ,
1311
+ getValidResolution ,
1281
1312
) ;
1282
1313
packageJsonInfoCache ??= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
1283
1314
@@ -1321,13 +1352,15 @@ export function createModuleResolutionCache(
1321
1352
options ?: CompilerOptions ,
1322
1353
packageJsonInfoCache ?: PackageJsonInfoCache ,
1323
1354
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1355
+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
1324
1356
) : ModuleResolutionCache ;
1325
1357
export function createModuleResolutionCache (
1326
1358
currentDirectory : string ,
1327
1359
getCanonicalFileName : ( s : string ) => string ,
1328
1360
options ?: CompilerOptions ,
1329
1361
packageJsonInfoCache ?: PackageJsonInfoCache ,
1330
1362
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1363
+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
1331
1364
) : ModuleResolutionCache {
1332
1365
const result = createModuleOrTypeReferenceResolutionCache (
1333
1366
currentDirectory ,
@@ -1336,6 +1369,7 @@ export function createModuleResolutionCache(
1336
1369
packageJsonInfoCache ,
1337
1370
getOriginalOrResolvedModuleFileName ,
1338
1371
optionsToRedirectsKey ,
1372
+ getValidResolution ,
1339
1373
) as ModuleResolutionCache ;
1340
1374
result . getOrCreateCacheForModuleName = ( nonRelativeName , mode , redirectedReference ) => result . getOrCreateCacheForNonRelativeName ( nonRelativeName , mode , redirectedReference ) ;
1341
1375
return result ;
@@ -1354,13 +1388,15 @@ export function createTypeReferenceDirectiveResolutionCache(
1354
1388
options ?: CompilerOptions ,
1355
1389
packageJsonInfoCache ?: PackageJsonInfoCache ,
1356
1390
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1391
+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1357
1392
) : TypeReferenceDirectiveResolutionCache ;
1358
1393
export function createTypeReferenceDirectiveResolutionCache (
1359
1394
currentDirectory : string ,
1360
1395
getCanonicalFileName : ( s : string ) => string ,
1361
1396
options ?: CompilerOptions ,
1362
1397
packageJsonInfoCache ?: PackageJsonInfoCache ,
1363
1398
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1399
+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1364
1400
) : TypeReferenceDirectiveResolutionCache {
1365
1401
return createModuleOrTypeReferenceResolutionCache (
1366
1402
currentDirectory ,
@@ -1369,6 +1405,7 @@ export function createTypeReferenceDirectiveResolutionCache(
1369
1405
packageJsonInfoCache ,
1370
1406
getOriginalOrResolvedTypeReferenceFileName ,
1371
1407
optionsToRedirectsKey ,
1408
+ getValidResolution ,
1372
1409
) ;
1373
1410
}
1374
1411
0 commit comments