@@ -57,6 +57,7 @@ import {
57
57
hasProperty ,
58
58
hasTrailingDirectorySeparator ,
59
59
hostGetCanonicalFileName ,
60
+ identity ,
60
61
inferredTypesContainingFile ,
61
62
isArray ,
62
63
isDeclarationFileName ,
@@ -1074,6 +1075,7 @@ function createPerDirectoryResolutionCache<T>(
1074
1075
getCanonicalFileName : GetCanonicalFileName ,
1075
1076
options : CompilerOptions | undefined ,
1076
1077
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1078
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1077
1079
) : PerDirectoryResolutionCache < T > {
1078
1080
const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < T > > ( options , optionsToRedirectsKey ) ;
1079
1081
return {
@@ -1099,7 +1101,7 @@ function createPerDirectoryResolutionCache<T>(
1099
1101
1100
1102
function getFromDirectoryCache ( name : string , mode : ResolutionMode , directoryName : string , redirectedReference : ResolvedProjectReference | undefined ) {
1101
1103
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 ) ) ;
1103
1105
}
1104
1106
}
1105
1107
@@ -1163,6 +1165,7 @@ function createNonRelativeNameResolutionCache<T>(
1163
1165
options : CompilerOptions | undefined ,
1164
1166
getResolvedFileName : ( result : T ) => string | undefined ,
1165
1167
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1168
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1166
1169
) : NonRelativeNameResolutionCache < T > {
1167
1170
const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerNonRelativeNameCache < T > > ( options , optionsToRedirectsKey ) ;
1168
1171
return {
@@ -1182,12 +1185,19 @@ function createNonRelativeNameResolutionCache<T>(
1182
1185
1183
1186
function getFromNonRelativeNameCache ( nonRelativeModuleName : string , mode : ResolutionMode , directoryName : string , redirectedReference ?: ResolvedProjectReference ) : T | undefined {
1184
1187
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 ) ;
1186
1191
}
1187
1192
1188
1193
function getOrCreateCacheForNonRelativeName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerNonRelativeNameCache < T > {
1189
1194
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
+ ) ;
1191
1201
}
1192
1202
1193
1203
function createPerModuleNameCache ( ) : PerNonRelativeNameCache < T > {
@@ -1196,7 +1206,11 @@ function createNonRelativeNameResolutionCache<T>(
1196
1206
return { get, set } ;
1197
1207
1198
1208
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 ) ) ;
1200
1214
}
1201
1215
1202
1216
/**
@@ -1213,32 +1227,45 @@ function createNonRelativeNameResolutionCache<T>(
1213
1227
function set ( directory : string , result : T ) : void {
1214
1228
const path = toPath ( directory , currentDirectory , getCanonicalFileName ) ;
1215
1229
// if entry is already in cache do nothing
1216
- if ( directoryPathMap . has ( path ) ) {
1230
+ if ( getByPath ( path ) ) {
1217
1231
return ;
1218
1232
}
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
+
1219
1241
directoryPathMap . set ( path , result ) ;
1220
1242
1221
- const resolvedFileName = getResolvedFileName ( result ) ;
1222
1243
// find common prefix between directory and resolved file name
1223
1244
// this common prefix should be the shortest path that has the same resolution
1224
1245
// directory: /a/b/c/d/e
1225
1246
// resolvedFileName: /a/b/foo.d.ts
1226
1247
// commonPrefix: /a/b
1227
1248
// 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 ) {
1229
1254
let current = path ;
1230
1255
while ( current !== commonPrefix ) {
1231
1256
const parent = getDirectoryPath ( current ) ;
1232
- if ( parent === current || directoryPathMap . has ( parent ) ) {
1257
+ if ( parent === current || getByPath ( parent ) ) {
1233
1258
break ;
1234
1259
}
1235
- directoryPathMap . set ( parent , result ) ;
1260
+ action ( parent ) ;
1236
1261
current = parent ;
1237
1262
}
1238
1263
}
1239
1264
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 ) ;
1242
1269
1243
1270
// find first position where directory and resolution differs
1244
1271
let i = 0 ;
@@ -1257,7 +1284,7 @@ function createNonRelativeNameResolutionCache<T>(
1257
1284
if ( sep === - 1 ) {
1258
1285
return undefined ;
1259
1286
}
1260
- return directory . substr ( 0 , Math . max ( sep , rootLength ) ) ;
1287
+ return directory . substr ( 0 , Math . max ( sep , rootLength ) ) as Path ;
1261
1288
}
1262
1289
}
1263
1290
}
@@ -1274,20 +1301,24 @@ function createModuleOrTypeReferenceResolutionCache<T>(
1274
1301
packageJsonInfoCache : PackageJsonInfoCache | undefined ,
1275
1302
getResolvedFileName : ( result : T ) => string | undefined ,
1276
1303
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > | undefined ,
1304
+ getValidResolution : ( ( resolution : T | undefined ) => T | undefined ) | undefined ,
1277
1305
) : ModuleOrTypeReferenceResolutionCache < T > {
1278
1306
optionsToRedirectsKey ??= new Map ( ) ;
1307
+ getValidResolution ??= identity ;
1279
1308
const perDirectoryResolutionCache = createPerDirectoryResolutionCache < T > (
1280
1309
currentDirectory ,
1281
1310
getCanonicalFileName ,
1282
1311
options ,
1283
1312
optionsToRedirectsKey ,
1313
+ getValidResolution ,
1284
1314
) ;
1285
1315
const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache (
1286
1316
currentDirectory ,
1287
1317
getCanonicalFileName ,
1288
1318
options ,
1289
1319
getResolvedFileName ,
1290
1320
optionsToRedirectsKey ,
1321
+ getValidResolution ,
1291
1322
) ;
1292
1323
packageJsonInfoCache ??= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
1293
1324
@@ -1330,14 +1361,18 @@ export function createModuleResolutionCache(
1330
1361
getCanonicalFileName : ( s : string ) => string ,
1331
1362
options ?: CompilerOptions ,
1332
1363
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 ,
1334
1368
) : ModuleResolutionCache ;
1335
1369
export function createModuleResolutionCache (
1336
1370
currentDirectory : string ,
1337
1371
getCanonicalFileName : ( s : string ) => string ,
1338
1372
options ?: CompilerOptions ,
1339
1373
packageJsonInfoCache ?: PackageJsonInfoCache ,
1340
1374
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1375
+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
1341
1376
) : ModuleResolutionCache {
1342
1377
const result = createModuleOrTypeReferenceResolutionCache (
1343
1378
currentDirectory ,
@@ -1346,6 +1381,7 @@ export function createModuleResolutionCache(
1346
1381
packageJsonInfoCache ,
1347
1382
getOriginalOrResolvedModuleFileName ,
1348
1383
optionsToRedirectsKey ,
1384
+ getValidResolution ,
1349
1385
) as ModuleResolutionCache ;
1350
1386
result . getOrCreateCacheForModuleName = ( nonRelativeName , mode , redirectedReference ) => result . getOrCreateCacheForNonRelativeName ( nonRelativeName , mode , redirectedReference ) ;
1351
1387
return result ;
@@ -1363,14 +1399,18 @@ export function createTypeReferenceDirectiveResolutionCache(
1363
1399
getCanonicalFileName : ( s : string ) => string ,
1364
1400
options ?: CompilerOptions ,
1365
1401
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 ,
1367
1406
) : TypeReferenceDirectiveResolutionCache ;
1368
1407
export function createTypeReferenceDirectiveResolutionCache (
1369
1408
currentDirectory : string ,
1370
1409
getCanonicalFileName : ( s : string ) => string ,
1371
1410
options ?: CompilerOptions ,
1372
1411
packageJsonInfoCache ?: PackageJsonInfoCache ,
1373
1412
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1413
+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1374
1414
) : TypeReferenceDirectiveResolutionCache {
1375
1415
return createModuleOrTypeReferenceResolutionCache (
1376
1416
currentDirectory ,
@@ -1379,6 +1419,7 @@ export function createTypeReferenceDirectiveResolutionCache(
1379
1419
packageJsonInfoCache ,
1380
1420
getOriginalOrResolvedTypeReferenceFileName ,
1381
1421
optionsToRedirectsKey ,
1422
+ getValidResolution ,
1382
1423
) ;
1383
1424
}
1384
1425
0 commit comments