@@ -1027,7 +1027,8 @@ function getTypeReferenceResolutionName<T extends FileReference | string>(entry:
1027
1027
return ! isString ( entry ) ? entry . fileName : entry ;
1028
1028
}
1029
1029
1030
- const typeReferenceResolutionNameAndModeGetter : ResolutionNameAndModeGetter < FileReference | string , SourceFile | undefined > = {
1030
+ /** @internal */
1031
+ export const typeReferenceResolutionNameAndModeGetter : ResolutionNameAndModeGetter < FileReference | string , SourceFile | undefined > = {
1031
1032
getName : getTypeReferenceResolutionName ,
1032
1033
getMode : ( entry , file ) => getModeForFileReference ( entry , file ?. impliedNodeFormat ) ,
1033
1034
} ;
@@ -1625,6 +1626,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1625
1626
options : CompilerOptions ,
1626
1627
containingSourceFile : SourceFile ,
1627
1628
reusedNames : readonly StringLiteralLike [ ] | undefined ,
1629
+ ambientModuleNames : readonly StringLiteralLike [ ] | undefined ,
1628
1630
) => readonly ResolvedModuleWithFailedLookupLocations [ ] ;
1629
1631
const hasInvalidatedResolutions = host . hasInvalidatedResolutions || returnFalse ;
1630
1632
if ( host . resolveModuleNameLiterals ) {
@@ -1832,6 +1834,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
1832
1834
}
1833
1835
tracing ?. pop ( ) ;
1834
1836
}
1837
+ else {
1838
+ host . onReusedTypeReferenceDirectiveResolutions ?.( /*reusedNames*/ undefined , /*containingSourceFile*/ undefined , /*redirectedReference*/ undefined , options ) ;
1839
+ }
1835
1840
1836
1841
// Do not process the default library if:
1837
1842
// - The '--noLib' flag is used.
@@ -2125,6 +2130,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2125
2130
moduleNames : readonly StringLiteralLike [ ] ,
2126
2131
containingFile : SourceFile ,
2127
2132
reusedNames : readonly StringLiteralLike [ ] | undefined ,
2133
+ ambientModuleNames : readonly StringLiteralLike [ ] | undefined ,
2128
2134
) : readonly ResolvedModuleWithFailedLookupLocations [ ] {
2129
2135
const containingFileName = getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) ;
2130
2136
const redirectedReference = getRedirectReferenceForResolution ( containingFile ) ;
@@ -2137,6 +2143,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2137
2143
options ,
2138
2144
containingFile ,
2139
2145
reusedNames ,
2146
+ ambientModuleNames ,
2140
2147
) ;
2141
2148
performance . mark ( "afterResolveModule" ) ;
2142
2149
performance . measure ( "ResolveModule" , "beforeResolveModule" , "afterResolveModule" ) ;
@@ -2253,6 +2260,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2253
2260
redirectedReference : getRedirectReferenceForResolution ( containingFile ) ,
2254
2261
nameAndModeGetter : moduleResolutionNameAndModeGetter ,
2255
2262
resolutionWorker : resolveModuleNamesWorker ,
2263
+ onReusedResolutions : maybeBind ( host , host . onReusedModuleResolutions ) ,
2256
2264
getResolutionFromOldProgram : ( name , mode ) => oldProgram ?. getResolvedModule ( containingFile , name , mode ) ,
2257
2265
getResolved : getResolvedModuleFromResolution ,
2258
2266
canReuseResolutionsInFile : ( ) =>
@@ -2315,6 +2323,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2315
2323
redirectedReference : containingSourceFile && getRedirectReferenceForResolution ( containingSourceFile ) ,
2316
2324
nameAndModeGetter : typeReferenceResolutionNameAndModeGetter ,
2317
2325
resolutionWorker : resolveTypeReferenceDirectiveNamesWorker ,
2326
+ onReusedResolutions : maybeBind ( host , host . onReusedTypeReferenceDirectiveResolutions ) ,
2318
2327
getResolutionFromOldProgram : ( name , mode ) =>
2319
2328
containingSourceFile ?
2320
2329
oldProgram ?. getResolvedTypeReferenceDirective ( containingSourceFile , name , mode ) :
@@ -2337,7 +2346,17 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2337
2346
entries : readonly Entry [ ] ,
2338
2347
containingFile : SourceFileOrString ,
2339
2348
reusedNames : readonly Entry [ ] | undefined ,
2349
+ ambientEntries : readonly Entry [ ] | undefined ,
2340
2350
) => readonly Resolution [ ] ;
2351
+ onReusedResolutions :
2352
+ | ( (
2353
+ resuedEntries : readonly Entry [ ] | undefined ,
2354
+ containingSourceFile : SourceFileOrUndefined ,
2355
+ redirectedReference : ResolvedProjectReference | undefined ,
2356
+ options : CompilerOptions ,
2357
+ ambientEntries : readonly Entry [ ] | undefined ,
2358
+ ) => void )
2359
+ | undefined ;
2341
2360
getResolutionFromOldProgram : ( name : string , mode : ResolutionMode ) => Resolution | undefined ;
2342
2361
getResolved : ( oldResolution : Resolution ) => ResolutionWithResolvedFileName | undefined ;
2343
2362
canReuseResolutionsInFile : ( ) => boolean ;
@@ -2351,19 +2370,24 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2351
2370
redirectedReference,
2352
2371
nameAndModeGetter,
2353
2372
resolutionWorker,
2373
+ onReusedResolutions,
2354
2374
getResolutionFromOldProgram,
2355
2375
getResolved,
2356
2376
canReuseResolutionsInFile,
2357
2377
isEntryResolvingToAmbientModule,
2358
2378
} : ResolveNamesReusingOldStateInput < Entry , SourceFileOrString , SourceFileOrUndefined , Resolution > ) : readonly Resolution [ ] {
2359
- if ( ! entries . length ) return emptyArray ;
2379
+ if ( ! entries . length ) {
2380
+ onReusedResolutions ?.( entries , containingSourceFile , redirectedReference , options , /*ambientEntries*/ undefined ) ;
2381
+ return emptyArray ;
2382
+ }
2360
2383
if ( structureIsReused === StructureIsReused . Not && ( ! isEntryResolvingToAmbientModule || ! containingSourceFile ! . ambientModuleNames . length ) ) {
2361
2384
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
2362
2385
// the best we can do is fallback to the default logic.
2363
2386
return resolutionWorker (
2364
2387
entries ,
2365
2388
containingFile ,
2366
2389
/*reusedNames*/ undefined ,
2390
+ /*ambientEntries*/ undefined ,
2367
2391
) ;
2368
2392
}
2369
2393
@@ -2372,6 +2396,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2372
2396
let unknownEntryIndices : number [ ] | undefined ;
2373
2397
let result : Resolution [ ] | undefined ;
2374
2398
let reusedNames : Entry [ ] | undefined ;
2399
+ let ambientEntries : Entry [ ] | undefined ;
2375
2400
const reuseResolutions = canReuseResolutionsInFile ( ) ;
2376
2401
for ( let i = 0 ; i < entries . length ; i ++ ) {
2377
2402
const entry = entries [ i ] ;
@@ -2403,6 +2428,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2403
2428
}
2404
2429
}
2405
2430
if ( isEntryResolvingToAmbientModule ?.( entry , containingFile ) ) {
2431
+ ( ambientEntries ??= [ ] ) . push ( entry ) ;
2406
2432
( result ??= new Array ( entries . length ) ) [ i ] = emptyResolution ;
2407
2433
}
2408
2434
else {
@@ -2412,8 +2438,16 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2412
2438
}
2413
2439
}
2414
2440
2415
- if ( ! unknownEntries ) return result ! ;
2416
- const resolutions = resolutionWorker ( unknownEntries , containingFile , reusedNames ) ;
2441
+ if ( ! unknownEntries ) {
2442
+ onReusedResolutions ?.( reusedNames , containingSourceFile , redirectedReference , options , ambientEntries ) ;
2443
+ return result ! ;
2444
+ }
2445
+ const resolutions = resolutionWorker (
2446
+ unknownEntries ,
2447
+ containingFile ,
2448
+ reusedNames ,
2449
+ ambientEntries ,
2450
+ ) ;
2417
2451
if ( ! result ) return resolutions ;
2418
2452
resolutions . forEach ( ( resolution , index ) => result [ unknownEntryIndices ! [ index ] ] = resolution ) ;
2419
2453
return result ;
@@ -3986,7 +4020,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
3986
4020
3987
4021
function processTypeReferenceDirectives ( file : SourceFile ) {
3988
4022
const typeDirectives = file . typeReferenceDirectives ;
3989
- if ( ! typeDirectives . length ) return ;
4023
+ if ( ! typeDirectives . length ) {
4024
+ host . onReusedTypeReferenceDirectiveResolutions ?.( /*reusedNames*/ undefined , file , getRedirectReferenceForResolution ( file ) , options ) ;
4025
+ return ;
4026
+ }
3990
4027
3991
4028
const resolutions = resolvedTypeReferenceDirectiveNamesProcessing ?. get ( file . path ) ||
3992
4029
resolveTypeReferenceDirectiveNamesReusingOldState ( typeDirectives , file ) ;
@@ -4111,13 +4148,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4111
4148
4112
4149
function processImportedModules ( file : SourceFile ) {
4113
4150
collectExternalModuleReferences ( file ) ;
4151
+ const redirectedReference = getRedirectReferenceForResolution ( file ) ;
4114
4152
if ( file . imports . length || file . moduleAugmentations . length ) {
4115
4153
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
4116
4154
const moduleNames = getModuleNames ( file ) ;
4117
4155
const resolutions = resolvedModulesProcessing ?. get ( file . path ) ||
4118
4156
resolveModuleNamesReusingOldState ( moduleNames , file ) ;
4119
4157
Debug . assert ( resolutions . length === moduleNames . length ) ;
4120
- const optionsForFile = getRedirectReferenceForResolution ( file ) ?. commandLine . options || options ;
4158
+ const optionsForFile = redirectedReference ?. commandLine . options || options ;
4121
4159
const resolutionsInFile = createModeAwareCache < ResolutionWithFailedLookupLocations > ( ) ;
4122
4160
( resolvedModules ??= new Map ( ) ) . set ( file . path , resolutionsInFile ) ;
4123
4161
for ( let index = 0 ; index < moduleNames . length ; index ++ ) {
@@ -4175,6 +4213,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4175
4213
}
4176
4214
}
4177
4215
}
4216
+ else {
4217
+ host . onReusedModuleResolutions ?.( /*reusedNames*/ undefined , file , redirectedReference , options , /*ambientModuleNames*/ undefined ) ;
4218
+ }
4178
4219
}
4179
4220
4180
4221
function checkSourceFilesBelongToPath ( sourceFiles : readonly SourceFile [ ] , rootDirectory : string ) : boolean {
0 commit comments