@@ -1027,7 +1027,8 @@ function getTypeReferenceResolutionName<T extends FileReference | string>(entry:
10271027 return ! isString ( entry ) ? entry . fileName : entry ;
10281028}
10291029
1030- const typeReferenceResolutionNameAndModeGetter : ResolutionNameAndModeGetter < FileReference | string , SourceFile | undefined > = {
1030+ /** @internal */
1031+ export const typeReferenceResolutionNameAndModeGetter : ResolutionNameAndModeGetter < FileReference | string , SourceFile | undefined > = {
10311032 getName : getTypeReferenceResolutionName ,
10321033 getMode : ( entry , file ) => getModeForFileReference ( entry , file ?. impliedNodeFormat ) ,
10331034} ;
@@ -1625,6 +1626,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
16251626 options : CompilerOptions ,
16261627 containingSourceFile : SourceFile ,
16271628 reusedNames : readonly StringLiteralLike [ ] | undefined ,
1629+ ambientModuleNames : readonly StringLiteralLike [ ] | undefined ,
16281630 ) => readonly ResolvedModuleWithFailedLookupLocations [ ] ;
16291631 const hasInvalidatedResolutions = host . hasInvalidatedResolutions || returnFalse ;
16301632 if ( host . resolveModuleNameLiterals ) {
@@ -1832,6 +1834,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
18321834 }
18331835 tracing ?. pop ( ) ;
18341836 }
1837+ else {
1838+ host . onReusedTypeReferenceDirectiveResolutions ?.( /*reusedNames*/ undefined , /*containingSourceFile*/ undefined , /*redirectedReference*/ undefined , options ) ;
1839+ }
18351840
18361841 // Do not process the default library if:
18371842 // - The '--noLib' flag is used.
@@ -2125,6 +2130,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
21252130 moduleNames : readonly StringLiteralLike [ ] ,
21262131 containingFile : SourceFile ,
21272132 reusedNames : readonly StringLiteralLike [ ] | undefined ,
2133+ ambientModuleNames : readonly StringLiteralLike [ ] | undefined ,
21282134 ) : readonly ResolvedModuleWithFailedLookupLocations [ ] {
21292135 const containingFileName = getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) ;
21302136 const redirectedReference = getRedirectReferenceForResolution ( containingFile ) ;
@@ -2137,6 +2143,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
21372143 options ,
21382144 containingFile ,
21392145 reusedNames ,
2146+ ambientModuleNames ,
21402147 ) ;
21412148 performance . mark ( "afterResolveModule" ) ;
21422149 performance . measure ( "ResolveModule" , "beforeResolveModule" , "afterResolveModule" ) ;
@@ -2253,6 +2260,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
22532260 redirectedReference : getRedirectReferenceForResolution ( containingFile ) ,
22542261 nameAndModeGetter : moduleResolutionNameAndModeGetter ,
22552262 resolutionWorker : resolveModuleNamesWorker ,
2263+ onReusedResolutions : maybeBind ( host , host . onReusedModuleResolutions ) ,
22562264 getResolutionFromOldProgram : ( name , mode ) => oldProgram ?. getResolvedModule ( containingFile , name , mode ) ,
22572265 getResolved : getResolvedModuleFromResolution ,
22582266 canReuseResolutionsInFile : ( ) =>
@@ -2315,6 +2323,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
23152323 redirectedReference : containingSourceFile && getRedirectReferenceForResolution ( containingSourceFile ) ,
23162324 nameAndModeGetter : typeReferenceResolutionNameAndModeGetter ,
23172325 resolutionWorker : resolveTypeReferenceDirectiveNamesWorker ,
2326+ onReusedResolutions : maybeBind ( host , host . onReusedTypeReferenceDirectiveResolutions ) ,
23182327 getResolutionFromOldProgram : ( name , mode ) =>
23192328 containingSourceFile ?
23202329 oldProgram ?. getResolvedTypeReferenceDirective ( containingSourceFile , name , mode ) :
@@ -2337,7 +2346,17 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
23372346 entries : readonly Entry [ ] ,
23382347 containingFile : SourceFileOrString ,
23392348 reusedNames : readonly Entry [ ] | undefined ,
2349+ ambientEntries : readonly Entry [ ] | undefined ,
23402350 ) => 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 ;
23412360 getResolutionFromOldProgram : ( name : string , mode : ResolutionMode ) => Resolution | undefined ;
23422361 getResolved : ( oldResolution : Resolution ) => ResolutionWithResolvedFileName | undefined ;
23432362 canReuseResolutionsInFile : ( ) => boolean ;
@@ -2351,19 +2370,24 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
23512370 redirectedReference,
23522371 nameAndModeGetter,
23532372 resolutionWorker,
2373+ onReusedResolutions,
23542374 getResolutionFromOldProgram,
23552375 getResolved,
23562376 canReuseResolutionsInFile,
23572377 isEntryResolvingToAmbientModule,
23582378 } : 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+ }
23602383 if ( structureIsReused === StructureIsReused . Not && ( ! isEntryResolvingToAmbientModule || ! containingSourceFile ! . ambientModuleNames . length ) ) {
23612384 // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
23622385 // the best we can do is fallback to the default logic.
23632386 return resolutionWorker (
23642387 entries ,
23652388 containingFile ,
23662389 /*reusedNames*/ undefined ,
2390+ /*ambientEntries*/ undefined ,
23672391 ) ;
23682392 }
23692393
@@ -2372,6 +2396,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
23722396 let unknownEntryIndices : number [ ] | undefined ;
23732397 let result : Resolution [ ] | undefined ;
23742398 let reusedNames : Entry [ ] | undefined ;
2399+ let ambientEntries : Entry [ ] | undefined ;
23752400 const reuseResolutions = canReuseResolutionsInFile ( ) ;
23762401 for ( let i = 0 ; i < entries . length ; i ++ ) {
23772402 const entry = entries [ i ] ;
@@ -2403,6 +2428,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
24032428 }
24042429 }
24052430 if ( isEntryResolvingToAmbientModule ?.( entry , containingFile ) ) {
2431+ ( ambientEntries ??= [ ] ) . push ( entry ) ;
24062432 ( result ??= new Array ( entries . length ) ) [ i ] = emptyResolution ;
24072433 }
24082434 else {
@@ -2412,8 +2438,16 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
24122438 }
24132439 }
24142440
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+ ) ;
24172451 if ( ! result ) return resolutions ;
24182452 resolutions . forEach ( ( resolution , index ) => result [ unknownEntryIndices ! [ index ] ] = resolution ) ;
24192453 return result ;
@@ -3986,7 +4020,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
39864020
39874021 function processTypeReferenceDirectives ( file : SourceFile ) {
39884022 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+ }
39904027
39914028 const resolutions = resolvedTypeReferenceDirectiveNamesProcessing ?. get ( file . path ) ||
39924029 resolveTypeReferenceDirectiveNamesReusingOldState ( typeDirectives , file ) ;
@@ -4111,13 +4148,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
41114148
41124149 function processImportedModules ( file : SourceFile ) {
41134150 collectExternalModuleReferences ( file ) ;
4151+ const redirectedReference = getRedirectReferenceForResolution ( file ) ;
41144152 if ( file . imports . length || file . moduleAugmentations . length ) {
41154153 // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
41164154 const moduleNames = getModuleNames ( file ) ;
41174155 const resolutions = resolvedModulesProcessing ?. get ( file . path ) ||
41184156 resolveModuleNamesReusingOldState ( moduleNames , file ) ;
41194157 Debug . assert ( resolutions . length === moduleNames . length ) ;
4120- const optionsForFile = getRedirectReferenceForResolution ( file ) ?. commandLine . options || options ;
4158+ const optionsForFile = redirectedReference ?. commandLine . options || options ;
41214159 const resolutionsInFile = createModeAwareCache < ResolutionWithFailedLookupLocations > ( ) ;
41224160 ( resolvedModules ??= new Map ( ) ) . set ( file . path , resolutionsInFile ) ;
41234161 for ( let index = 0 ; index < moduleNames . length ; index ++ ) {
@@ -4175,6 +4213,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
41754213 }
41764214 }
41774215 }
4216+ else {
4217+ host . onReusedModuleResolutions ?.( /*reusedNames*/ undefined , file , redirectedReference , options , /*ambientModuleNames*/ undefined ) ;
4218+ }
41784219 }
41794220
41804221 function checkSourceFilesBelongToPath ( sourceFiles : readonly SourceFile [ ] , rootDirectory : string ) : boolean {
0 commit comments