@@ -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 ,
@@ -1073,6 +1074,7 @@ function createPerDirectoryResolutionCache<T>(
1073
1074
getCanonicalFileName : GetCanonicalFileName ,
1074
1075
options : CompilerOptions | undefined ,
1075
1076
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1077
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1076
1078
) : PerDirectoryResolutionCache < T > {
1077
1079
const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < T > > ( options , optionsToRedirectsKey ) ;
1078
1080
return {
@@ -1098,7 +1100,7 @@ function createPerDirectoryResolutionCache<T>(
1098
1100
1099
1101
function getFromDirectoryCache ( name : string , mode : ResolutionMode , directoryName : string , redirectedReference : ResolvedProjectReference | undefined ) {
1100
1102
const path = toPath ( directoryName , currentDirectory , getCanonicalFileName ) ;
1101
- return directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ;
1103
+ return getValidResolution ( directoryToModuleNameMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( path ) ?. get ( name , mode ) ) ;
1102
1104
}
1103
1105
}
1104
1106
@@ -1162,6 +1164,7 @@ function createNonRelativeNameResolutionCache<T>(
1162
1164
options : CompilerOptions | undefined ,
1163
1165
getResolvedFileName : ( result : T ) => string | undefined ,
1164
1166
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > ,
1167
+ getValidResolution : ( resolution : T | undefined ) => T | undefined ,
1165
1168
) : NonRelativeNameResolutionCache < T > {
1166
1169
const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerNonRelativeNameCache < T > > ( options , optionsToRedirectsKey ) ;
1167
1170
return {
@@ -1181,12 +1184,19 @@ function createNonRelativeNameResolutionCache<T>(
1181
1184
1182
1185
function getFromNonRelativeNameCache ( nonRelativeModuleName : string , mode : ResolutionMode , directoryName : string , redirectedReference ?: ResolvedProjectReference ) : T | undefined {
1183
1186
Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1184
- return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get ( createModeAwareCacheKey ( nonRelativeModuleName , mode ) ) ?. get ( directoryName ) ;
1187
+ return moduleNameToDirectoryMap . getMapOfCacheRedirects ( redirectedReference ) ?. get (
1188
+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1189
+ ) ?. get ( directoryName ) ;
1185
1190
}
1186
1191
1187
1192
function getOrCreateCacheForNonRelativeName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerNonRelativeNameCache < T > {
1188
1193
Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
1189
- return getOrCreateCache ( moduleNameToDirectoryMap , redirectedReference , createModeAwareCacheKey ( nonRelativeModuleName , mode ) , createPerModuleNameCache ) ;
1194
+ return getOrCreateCache (
1195
+ moduleNameToDirectoryMap ,
1196
+ redirectedReference ,
1197
+ createModeAwareCacheKey ( nonRelativeModuleName , mode ) ,
1198
+ createPerModuleNameCache ,
1199
+ ) ;
1190
1200
}
1191
1201
1192
1202
function createPerModuleNameCache ( ) : PerNonRelativeNameCache < T > {
@@ -1195,7 +1205,11 @@ function createNonRelativeNameResolutionCache<T>(
1195
1205
return { get, set } ;
1196
1206
1197
1207
function get ( directory : string ) : T | undefined {
1198
- return directoryPathMap . get ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1208
+ return getByPath ( toPath ( directory , currentDirectory , getCanonicalFileName ) ) ;
1209
+ }
1210
+
1211
+ function getByPath ( directoryPath : Path ) : T | undefined {
1212
+ return getValidResolution ( directoryPathMap . get ( directoryPath ) ) ;
1199
1213
}
1200
1214
1201
1215
/**
@@ -1212,32 +1226,45 @@ function createNonRelativeNameResolutionCache<T>(
1212
1226
function set ( directory : string , result : T ) : void {
1213
1227
const path = toPath ( directory , currentDirectory , getCanonicalFileName ) ;
1214
1228
// if entry is already in cache do nothing
1215
- if ( directoryPathMap . has ( path ) ) {
1229
+ if ( getByPath ( path ) ) {
1216
1230
return ;
1217
1231
}
1232
+
1233
+ const existing = directoryPathMap . get ( path ) ;
1234
+ // Remove invalidated result from parent
1235
+ if ( existing ) {
1236
+ const existingCommonPrefix = getCommonPrefix ( path , existing ) ;
1237
+ withCommonPrefix ( path , existingCommonPrefix , parent => directoryPathMap . delete ( parent ) ) ;
1238
+ }
1239
+
1218
1240
directoryPathMap . set ( path , result ) ;
1219
1241
1220
- const resolvedFileName = getResolvedFileName ( result ) ;
1221
1242
// find common prefix between directory and resolved file name
1222
1243
// this common prefix should be the shortest path that has the same resolution
1223
1244
// directory: /a/b/c/d/e
1224
1245
// resolvedFileName: /a/b/foo.d.ts
1225
1246
// commonPrefix: /a/b
1226
1247
// for failed lookups cache the result for every directory up to root
1227
- const commonPrefix = resolvedFileName && getCommonPrefix ( path , resolvedFileName ) ;
1248
+ const commonPrefix = getCommonPrefix ( path , result ) ;
1249
+ withCommonPrefix ( path , commonPrefix , parent => directoryPathMap . set ( parent , result ) ) ;
1250
+ }
1251
+
1252
+ function withCommonPrefix ( path : Path , commonPrefix : Path | undefined , action : ( parent : Path ) => void ) {
1228
1253
let current = path ;
1229
1254
while ( current !== commonPrefix ) {
1230
1255
const parent = getDirectoryPath ( current ) ;
1231
- if ( parent === current || directoryPathMap . has ( parent ) ) {
1256
+ if ( parent === current || getByPath ( parent ) ) {
1232
1257
break ;
1233
1258
}
1234
- directoryPathMap . set ( parent , result ) ;
1259
+ action ( parent ) ;
1235
1260
current = parent ;
1236
1261
}
1237
1262
}
1238
1263
1239
- function getCommonPrefix ( directory : Path , resolution : string ) {
1240
- const resolutionDirectory = toPath ( getDirectoryPath ( resolution ) , currentDirectory , getCanonicalFileName ) ;
1264
+ function getCommonPrefix ( directory : Path , resolution : T ) {
1265
+ const resolvedFileName = getResolvedFileName ( resolution ) ;
1266
+ if ( ! resolvedFileName ) return undefined ;
1267
+ const resolutionDirectory = toPath ( getDirectoryPath ( resolvedFileName ) , currentDirectory , getCanonicalFileName ) ;
1241
1268
1242
1269
// find first position where directory and resolution differs
1243
1270
let i = 0 ;
@@ -1256,7 +1283,7 @@ function createNonRelativeNameResolutionCache<T>(
1256
1283
if ( sep === - 1 ) {
1257
1284
return undefined ;
1258
1285
}
1259
- return directory . substr ( 0 , Math . max ( sep , rootLength ) ) ;
1286
+ return directory . substr ( 0 , Math . max ( sep , rootLength ) ) as Path ;
1260
1287
}
1261
1288
}
1262
1289
}
@@ -1273,20 +1300,24 @@ function createModuleOrTypeReferenceResolutionCache<T>(
1273
1300
packageJsonInfoCache : PackageJsonInfoCache | undefined ,
1274
1301
getResolvedFileName : ( result : T ) => string | undefined ,
1275
1302
optionsToRedirectsKey : Map < CompilerOptions , RedirectsCacheKey > | undefined ,
1303
+ getValidResolution : ( ( resolution : T | undefined ) => T | undefined ) | undefined ,
1276
1304
) : ModuleOrTypeReferenceResolutionCache < T > {
1277
1305
optionsToRedirectsKey ??= new Map ( ) ;
1306
+ getValidResolution ??= identity ;
1278
1307
const perDirectoryResolutionCache = createPerDirectoryResolutionCache < T > (
1279
1308
currentDirectory ,
1280
1309
getCanonicalFileName ,
1281
1310
options ,
1282
1311
optionsToRedirectsKey ,
1312
+ getValidResolution ,
1283
1313
) ;
1284
1314
const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache (
1285
1315
currentDirectory ,
1286
1316
getCanonicalFileName ,
1287
1317
options ,
1288
1318
getResolvedFileName ,
1289
1319
optionsToRedirectsKey ,
1320
+ getValidResolution ,
1290
1321
) ;
1291
1322
packageJsonInfoCache ??= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
1292
1323
@@ -1329,14 +1360,18 @@ export function createModuleResolutionCache(
1329
1360
getCanonicalFileName : ( s : string ) => string ,
1330
1361
options ?: CompilerOptions ,
1331
1362
packageJsonInfoCache ?: PackageJsonInfoCache ,
1332
- optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > , // eslint-disable-line @typescript-eslint/unified-signatures
1363
+ optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1364
+ getValidResolution ?: ( // eslint-disable-line @typescript-eslint/unified-signatures
1365
+ resolution : ResolvedModuleWithFailedLookupLocations | undefined ,
1366
+ ) => ResolvedModuleWithFailedLookupLocations | undefined ,
1333
1367
) : ModuleResolutionCache ;
1334
1368
export function createModuleResolutionCache (
1335
1369
currentDirectory : string ,
1336
1370
getCanonicalFileName : ( s : string ) => string ,
1337
1371
options ?: CompilerOptions ,
1338
1372
packageJsonInfoCache ?: PackageJsonInfoCache ,
1339
1373
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1374
+ getValidResolution ?: ( resolution : ResolvedModuleWithFailedLookupLocations | undefined ) => ResolvedModuleWithFailedLookupLocations | undefined ,
1340
1375
) : ModuleResolutionCache {
1341
1376
const result = createModuleOrTypeReferenceResolutionCache (
1342
1377
currentDirectory ,
@@ -1345,6 +1380,7 @@ export function createModuleResolutionCache(
1345
1380
packageJsonInfoCache ,
1346
1381
getOriginalOrResolvedModuleFileName ,
1347
1382
optionsToRedirectsKey ,
1383
+ getValidResolution ,
1348
1384
) as ModuleResolutionCache ;
1349
1385
result . getOrCreateCacheForModuleName = ( nonRelativeName , mode , redirectedReference ) => result . getOrCreateCacheForNonRelativeName ( nonRelativeName , mode , redirectedReference ) ;
1350
1386
return result ;
@@ -1362,14 +1398,18 @@ export function createTypeReferenceDirectiveResolutionCache(
1362
1398
getCanonicalFileName : ( s : string ) => string ,
1363
1399
options ?: CompilerOptions ,
1364
1400
packageJsonInfoCache ?: PackageJsonInfoCache ,
1365
- optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > , // eslint-disable-line @typescript-eslint/unified-signatures
1401
+ optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1402
+ getValidResolution ?: ( // eslint-disable-line @typescript-eslint/unified-signatures
1403
+ resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1404
+ ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1366
1405
) : TypeReferenceDirectiveResolutionCache ;
1367
1406
export function createTypeReferenceDirectiveResolutionCache (
1368
1407
currentDirectory : string ,
1369
1408
getCanonicalFileName : ( s : string ) => string ,
1370
1409
options ?: CompilerOptions ,
1371
1410
packageJsonInfoCache ?: PackageJsonInfoCache ,
1372
1411
optionsToRedirectsKey ?: Map < CompilerOptions , RedirectsCacheKey > ,
1412
+ getValidResolution ?: ( resolution : ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ) => ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined ,
1373
1413
) : TypeReferenceDirectiveResolutionCache {
1374
1414
return createModuleOrTypeReferenceResolutionCache (
1375
1415
currentDirectory ,
@@ -1378,6 +1418,7 @@ export function createTypeReferenceDirectiveResolutionCache(
1378
1418
packageJsonInfoCache ,
1379
1419
getOriginalOrResolvedTypeReferenceFileName ,
1380
1420
optionsToRedirectsKey ,
1421
+ getValidResolution ,
1381
1422
) ;
1382
1423
}
1383
1424
0 commit comments