@@ -48,6 +48,7 @@ namespace ts {
4848 addScriptInfo ( program : Program , sourceFile : SourceFile ) : void ;
4949 removeScriptInfo ( path : Path ) : void ;
5050 updateScriptInfo ( program : Program , sourceFile : SourceFile ) : void ;
51+ updaterScriptInfoWithSameVersion ( program : Program , sourceFile : SourceFile ) : boolean ;
5152 /**
5253 * Gets the files affected by the script info which has updated shape from the known one
5354 */
@@ -143,11 +144,15 @@ namespace ts {
143144 }
144145
145146 function updateExistingFileInfo ( program : Program , existingInfo : FileInfo , sourceFile : SourceFile , hasInvalidatedResolution : HasInvalidatedResolution ) {
146- if ( existingInfo . version !== sourceFile . version || hasInvalidatedResolution ( sourceFile . path ) ) {
147+ if ( existingInfo . version !== sourceFile . version ) {
147148 registerChangedFile ( sourceFile . path , sourceFile . fileName ) ;
148149 existingInfo . version = sourceFile . version ;
149150 emitHandler . updateScriptInfo ( program , sourceFile ) ;
150151 }
152+ else if ( hasInvalidatedResolution ( sourceFile . path ) &&
153+ emitHandler . updaterScriptInfoWithSameVersion ( program , sourceFile ) ) {
154+ registerChangedFile ( sourceFile . path , sourceFile . fileName ) ;
155+ }
151156 }
152157
153158 function ensureProgramGraph ( program : Program ) {
@@ -338,8 +343,8 @@ namespace ts {
338343 /**
339344 * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
340345 */
341- function getReferencedFiles ( program : Program , sourceFile : SourceFile ) : Map < true > {
342- const referencedFiles = createMap < true > ( ) ;
346+ function getReferencedFiles ( program : Program , sourceFile : SourceFile ) : Map < true > | undefined {
347+ let referencedFiles : Map < true > | undefined ;
343348
344349 // We need to use a set here since the code can contain the same import twice,
345350 // but that will only be one dependency.
@@ -351,7 +356,7 @@ namespace ts {
351356 if ( symbol && symbol . declarations && symbol . declarations [ 0 ] ) {
352357 const declarationSourceFile = getSourceFileOfNode ( symbol . declarations [ 0 ] ) ;
353358 if ( declarationSourceFile ) {
354- referencedFiles . set ( declarationSourceFile . path , true ) ;
359+ addReferencedFile ( declarationSourceFile . path ) ;
355360 }
356361 }
357362 }
@@ -362,7 +367,7 @@ namespace ts {
362367 if ( sourceFile . referencedFiles && sourceFile . referencedFiles . length > 0 ) {
363368 for ( const referencedFile of sourceFile . referencedFiles ) {
364369 const referencedPath = toPath ( referencedFile . fileName , sourceFileDirectory , getCanonicalFileName ) ;
365- referencedFiles . set ( referencedPath , true ) ;
370+ addReferencedFile ( referencedPath ) ;
366371 }
367372 }
368373
@@ -375,11 +380,18 @@ namespace ts {
375380
376381 const fileName = resolvedTypeReferenceDirective . resolvedFileName ;
377382 const typeFilePath = toPath ( fileName , sourceFileDirectory , getCanonicalFileName ) ;
378- referencedFiles . set ( typeFilePath , true ) ;
383+ addReferencedFile ( typeFilePath ) ;
379384 } ) ;
380385 }
381386
382387 return referencedFiles ;
388+
389+ function addReferencedFile ( referencedPath : Path ) {
390+ if ( ! referencedFiles ) {
391+ referencedFiles = createMap < true > ( ) ;
392+ }
393+ referencedFiles . set ( referencedPath , true ) ;
394+ }
383395 }
384396
385397 /**
@@ -402,6 +414,7 @@ namespace ts {
402414 addScriptInfo : noop ,
403415 removeScriptInfo : noop ,
404416 updateScriptInfo : noop ,
417+ updaterScriptInfoWithSameVersion : returnFalse ,
405418 getFilesAffectedByUpdatedShape
406419 } ;
407420
@@ -421,12 +434,45 @@ namespace ts {
421434 return {
422435 addScriptInfo : setReferences ,
423436 removeScriptInfo,
424- updateScriptInfo : setReferences ,
437+ updateScriptInfo : updateReferences ,
438+ updaterScriptInfoWithSameVersion : updateReferencesTrackingChangedReferences ,
425439 getFilesAffectedByUpdatedShape
426440 } ;
427441
428442 function setReferences ( program : Program , sourceFile : SourceFile ) {
429- references . set ( sourceFile . path , getReferencedFiles ( program , sourceFile ) ) ;
443+ const newReferences = getReferencedFiles ( program , sourceFile ) ;
444+ if ( newReferences ) {
445+ references . set ( sourceFile . path , getReferencedFiles ( program , sourceFile ) ) ;
446+ }
447+ }
448+
449+ function updateReferences ( program : Program , sourceFile : SourceFile ) {
450+ const newReferences = getReferencedFiles ( program , sourceFile ) ;
451+ if ( newReferences ) {
452+ references . set ( sourceFile . path , newReferences ) ;
453+ }
454+ else {
455+ references . delete ( sourceFile . path ) ;
456+ }
457+ }
458+
459+ function updateReferencesTrackingChangedReferences ( program : Program , sourceFile : SourceFile ) {
460+ const newReferences = getReferencedFiles ( program , sourceFile ) ;
461+ if ( ! newReferences ) {
462+ // Changed if we had references
463+ return references . delete ( sourceFile . path ) ;
464+ }
465+
466+ const oldReferences = references . get ( sourceFile . path ) ;
467+ references . set ( sourceFile . path , newReferences ) ;
468+ if ( ! oldReferences || oldReferences . size !== newReferences . size ) {
469+ return true ;
470+ }
471+
472+ // If there are any new references that werent present previously there is change
473+ return forEachEntry ( newReferences , ( _true , referencedPath ) => ! oldReferences . delete ( referencedPath ) ) ||
474+ // Otherwise its changed if there are more references previously than now
475+ ! ! oldReferences . size ;
430476 }
431477
432478 function removeScriptInfo ( removedFilePath : Path ) {
0 commit comments