@@ -210,7 +210,6 @@ namespace ts {
210210 originalWriteFile : CompilerHost [ "writeFile" ] | undefined ;
211211 originalReadFileWithCache : CompilerHost [ "readFile" ] ;
212212 originalGetSourceFile : CompilerHost [ "getSourceFile" ] ;
213- buildInfoCache : ESMap < Path , BuildInfo | false > ;
214213 }
215214
216215 interface FileWatcherWithModifiedTime {
@@ -219,6 +218,11 @@ namespace ts {
219218 modifiedTime : Date | undefined ;
220219 }
221220
221+ interface BuildInfoCacheEntry {
222+ path : Path ;
223+ buildInfo : BuildInfo | false | string ;
224+ }
225+
222226 interface SolutionBuilderState < T extends BuilderProgram = BuilderProgram > extends WatchFactory < WatchType , ResolvedConfigFileName > {
223227 readonly host : SolutionBuilderHost < T > ;
224228 readonly hostWithWatch : SolutionBuilderWithWatchHost < T > ;
@@ -239,6 +243,7 @@ namespace ts {
239243 readonly projectStatus : ESMap < ResolvedConfigFilePath , UpToDateStatus > ;
240244 readonly buildInfoChecked : ESMap < ResolvedConfigFilePath , true > ;
241245 readonly extendedConfigCache : ESMap < string , ExtendedConfigCacheEntry > ;
246+ readonly buildInfoCache : ESMap < ResolvedConfigFilePath , BuildInfoCacheEntry > ;
242247
243248 readonly builderPrograms : ESMap < ResolvedConfigFilePath , T > ;
244249 readonly diagnostics : ESMap < ResolvedConfigFilePath , readonly Diagnostic [ ] > ;
@@ -301,7 +306,7 @@ namespace ts {
301306 compilerHost . resolveTypeReferenceDirectives = ( typeReferenceDirectiveNames , containingFile , redirectedReference , _options , containingFileMode ) =>
302307 loadWithTypeDirectiveCache < ResolvedTypeReferenceDirective > ( Debug . checkEachDefined ( typeReferenceDirectiveNames ) , containingFile , redirectedReference , containingFileMode , loader ) ;
303308 }
304- compilerHost . getBuildInfo = fileName => getBuildInfo ( state , fileName ) ;
309+ compilerHost . getBuildInfo = ( fileName , configFilePath ) => getBuildInfo ( state , fileName , toResolvedConfigFilePath ( state , configFilePath as ResolvedConfigFileName ) ) ;
305310
306311 const { watchFile, watchDirectory, writeLog } = createWatchFactory < ResolvedConfigFileName > ( hostWithWatch , options ) ;
307312
@@ -324,6 +329,7 @@ namespace ts {
324329 projectStatus : new Map ( ) ,
325330 buildInfoChecked : new Map ( ) ,
326331 extendedConfigCache : new Map ( ) ,
332+ buildInfoCache : new Map ( ) ,
327333
328334 builderPrograms : new Map ( ) ,
329335 diagnostics : new Map ( ) ,
@@ -487,6 +493,7 @@ namespace ts {
487493 mutateMapSkippingNewValues ( state . diagnostics , currentProjects , noopOnDelete ) ;
488494 mutateMapSkippingNewValues ( state . projectPendingBuild , currentProjects , noopOnDelete ) ;
489495 mutateMapSkippingNewValues ( state . projectErrorsReported , currentProjects , noopOnDelete ) ;
496+ mutateMapSkippingNewValues ( state . buildInfoCache , currentProjects , noopOnDelete ) ;
490497
491498 // Remove watches for the program no longer in the solution
492499 if ( state . watch ) {
@@ -575,7 +582,6 @@ namespace ts {
575582 originalWriteFile,
576583 originalReadFileWithCache,
577584 originalGetSourceFile,
578- buildInfoCache : new Map ( ) ,
579585 } ;
580586 }
581587
@@ -978,6 +984,7 @@ namespace ts {
978984 let newestDeclarationFileContentChangedTime : Date | undefined ;
979985 const emitterDiagnostics = createDiagnosticCollection ( ) ;
980986 const emittedOutputs = new Map < Path , string > ( ) ;
987+ const buildInfo = state . buildInfoCache . get ( projectPath ) ;
981988 outputFiles . forEach ( ( { name, text, writeByteOrderMark } ) => {
982989 if ( resultFlags === BuildResultFlags . DeclarationOutputUnchanged && isDeclarationFileName ( name ) ) {
983990 // Check for unchanged .d.ts files
@@ -991,7 +998,7 @@ namespace ts {
991998
992999 const path = toPath ( state , name ) ;
9931000 emittedOutputs . set ( path , name ) ;
994- state . cache ?. buildInfoCache . delete ( path ) ;
1001+ if ( buildInfo ?. path === path ) buildInfo . buildInfo = text ;
9951002 writeFile ( writeFileCallback ? { writeFile : writeFileCallback } : compilerHost , emitterDiagnostics , name , text , writeByteOrderMark ) ;
9961003 } ) ;
9971004
@@ -1010,7 +1017,8 @@ namespace ts {
10101017 Debug . assert ( step === BuildStep . EmitBuildInfo ) ;
10111018 const emitResult = program . emitBuildInfo ( ( name , data , writeByteOrderMark , onError , sourceFiles ) => {
10121019 const path = toPath ( state , name ) ;
1013- state . cache ?. buildInfoCache . delete ( path ) ;
1020+ const buildInfo = state . buildInfoCache . get ( projectPath ) ;
1021+ if ( buildInfo ?. path === path ) buildInfo . buildInfo = data ;
10141022 if ( writeFileCallback ) writeFileCallback ( name , data , writeByteOrderMark , onError , sourceFiles ) ;
10151023 else state . compilerHost . writeFile ( name , data , writeByteOrderMark , onError , sourceFiles ) ;
10161024 } , cancellationToken ) ;
@@ -1110,10 +1118,11 @@ namespace ts {
11101118 Debug . assert ( ! ! outputFiles . length ) ;
11111119 const emitterDiagnostics = createDiagnosticCollection ( ) ;
11121120 const emittedOutputs = new Map < Path , string > ( ) ;
1121+ const buildInfo = state . buildInfoCache . get ( projectPath ) ;
11131122 outputFiles . forEach ( ( { name, text, writeByteOrderMark } ) => {
11141123 const path = toPath ( state , name ) ;
11151124 emittedOutputs . set ( path , name ) ;
1116- state . cache ?. buildInfoCache . delete ( path ) ;
1125+ if ( buildInfo ?. path === path ) buildInfo . buildInfo = text ;
11171126 writeFile ( writeFileCallback ? { writeFile : writeFileCallback } : compilerHost , emitterDiagnostics , name , text , writeByteOrderMark ) ;
11181127 } ) ;
11191128
@@ -1402,13 +1411,17 @@ namespace ts {
14021411 } ;
14031412 }
14041413
1405- function getBuildInfo ( state : SolutionBuilderState , buildInfoPath : string ) : BuildInfo | undefined {
1414+ function getBuildInfo ( state : SolutionBuilderState , buildInfoPath : string , resolvedConfigPath : ResolvedConfigFilePath ) : BuildInfo | undefined {
14061415 const path = toPath ( state , buildInfoPath ) ;
1407- const existing = state . cache ?. buildInfoCache . get ( path ) ;
1408- if ( existing !== undefined ) return existing || undefined ;
1416+ const existing = state . buildInfoCache . get ( resolvedConfigPath ) ;
1417+ if ( existing !== undefined && existing . path === path ) {
1418+ return isString ( existing . buildInfo ) ?
1419+ existing . buildInfo = ts . getBuildInfo ( existing . buildInfo ) :
1420+ existing . buildInfo || undefined ;
1421+ }
14091422 const value = state . readFileWithCache ( buildInfoPath ) ;
14101423 const buildInfo = value ? ts . getBuildInfo ( value ) : undefined ;
1411- state . cache ?. buildInfoCache . set ( path , buildInfo || false ) ;
1424+ state . buildInfoCache . set ( resolvedConfigPath , { path, buildInfo : buildInfo || false } ) ;
14121425 return buildInfo ;
14131426 }
14141427
@@ -1487,7 +1500,7 @@ namespace ts {
14871500 } ;
14881501 }
14891502
1490- const buildInfo = Debug . checkDefined ( getBuildInfo ( state , buildInfoPath ) ) ;
1503+ const buildInfo = Debug . checkDefined ( getBuildInfo ( state , buildInfoPath , resolvedPath ) ) ;
14911504 if ( ! state . buildInfoChecked . has ( resolvedPath ) ) {
14921505 state . buildInfoChecked . set ( resolvedPath , true ) ;
14931506 if ( buildInfo && ( buildInfo . bundle || buildInfo . program ) && buildInfo . version !== version ) {
0 commit comments