@@ -10,6 +10,7 @@ namespace ts {
1010
1111 invalidateResolutionOfFile ( filePath : Path ) : void ;
1212 removeResolutionsOfFile ( filePath : Path ) : void ;
13+ setFilesWithInvalidatedNonRelativeUnresolvedImports ( filesWithUnresolvedImports : Map < ReadonlyArray < string > > ) : void ;
1314 createHasInvalidatedResolution ( forceAllFilesAsInvalidated ?: boolean ) : HasInvalidatedResolution ;
1415
1516 startCachingPerDirectoryResolution ( ) : void ;
@@ -74,6 +75,7 @@ namespace ts {
7475 export function createResolutionCache ( resolutionHost : ResolutionCacheHost , rootDirForResolution : string , logChangesWhenResolvingModule : boolean ) : ResolutionCache {
7576 let filesWithChangedSetOfUnresolvedImports : Path [ ] | undefined ;
7677 let filesWithInvalidatedResolutions : Map < true > | undefined ;
78+ let filesWithInvalidatedNonRelativeUnresolvedImports : Map < ReadonlyArray < string > > | undefined ;
7779 let allFilesHaveInvalidatedResolution = false ;
7880
7981 const getCurrentDirectory = memoize ( ( ) => resolutionHost . getCurrentDirectory ( ) ) ;
@@ -122,6 +124,7 @@ namespace ts {
122124 resolveTypeReferenceDirectives,
123125 removeResolutionsOfFile,
124126 invalidateResolutionOfFile,
127+ setFilesWithInvalidatedNonRelativeUnresolvedImports,
125128 createHasInvalidatedResolution,
126129 updateTypeRootsWatch,
127130 closeTypeRootsWatch,
@@ -165,6 +168,16 @@ namespace ts {
165168 return collected ;
166169 }
167170
171+ function isFileWithInvalidatedNonRelativeUnresolvedImports ( path : Path ) {
172+ if ( ! filesWithInvalidatedNonRelativeUnresolvedImports ) {
173+ return false ;
174+ }
175+
176+ // Invalidated if file has unresolved imports
177+ const value = filesWithInvalidatedNonRelativeUnresolvedImports . get ( path ) ;
178+ return value && ! ! value . length ;
179+ }
180+
168181 function createHasInvalidatedResolution ( forceAllFilesAsInvalidated ?: boolean ) : HasInvalidatedResolution {
169182 if ( allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated ) {
170183 // Any file asked would have invalidated resolution
@@ -173,7 +186,8 @@ namespace ts {
173186 }
174187 const collected = filesWithInvalidatedResolutions ;
175188 filesWithInvalidatedResolutions = undefined ;
176- return path => collected && collected . has ( path ) ;
189+ return path => ( collected && collected . has ( path ) ) ||
190+ isFileWithInvalidatedNonRelativeUnresolvedImports ( path ) ;
177191 }
178192
179193 function clearPerDirectoryResolutions ( ) {
@@ -184,6 +198,7 @@ namespace ts {
184198
185199 function finishCachingPerDirectoryResolution ( ) {
186200 allFilesHaveInvalidatedResolution = false ;
201+ filesWithInvalidatedNonRelativeUnresolvedImports = undefined ;
187202 directoryWatchesOfFailedLookups . forEach ( ( watcher , path ) => {
188203 if ( watcher . refCount === 0 ) {
189204 directoryWatchesOfFailedLookups . delete ( path ) ;
@@ -237,13 +252,15 @@ namespace ts {
237252
238253 const resolvedModules : R [ ] = [ ] ;
239254 const compilerOptions = resolutionHost . getCompilationSettings ( ) ;
240-
255+ const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports ( path ) ;
241256 const seenNamesInFile = createMap < true > ( ) ;
242257 for ( const name of names ) {
243258 let resolution = resolutionsInFile . get ( name ) ;
244259 // Resolution is valid if it is present and not invalidated
245260 if ( ! seenNamesInFile . has ( name ) &&
246- allFilesHaveInvalidatedResolution || ! resolution || resolution . isInvalidated ) {
261+ allFilesHaveInvalidatedResolution || ! resolution || resolution . isInvalidated ||
262+ // If the name is unresolved import that was invalidated, recalculate
263+ ( hasInvalidatedNonRelativeUnresolvedImport && ! isExternalModuleNameRelative ( name ) && ! getResolutionWithResolvedFileName ( resolution ) ) ) {
247264 const existingResolution = resolution ;
248265 const resolutionInDirectory = perDirectoryResolution . get ( name ) ;
249266 if ( resolutionInDirectory ) {
@@ -284,7 +301,7 @@ namespace ts {
284301 if ( oldResolution === newResolution ) {
285302 return true ;
286303 }
287- if ( ! oldResolution || ! newResolution || oldResolution . isInvalidated ) {
304+ if ( ! oldResolution || ! newResolution ) {
288305 return false ;
289306 }
290307 const oldResult = getResolutionWithResolvedFileName ( oldResolution ) ;
@@ -577,6 +594,11 @@ namespace ts {
577594 ) ;
578595 }
579596
597+ function setFilesWithInvalidatedNonRelativeUnresolvedImports ( filesMap : Map < ReadonlyArray < string > > ) {
598+ Debug . assert ( filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined ) ;
599+ filesWithInvalidatedNonRelativeUnresolvedImports = filesMap ;
600+ }
601+
580602 function invalidateResolutionOfFailedLookupLocation ( fileOrDirectoryPath : Path , isCreatingWatchedDirectory : boolean ) {
581603 let isChangedFailedLookupLocation : ( location : string ) => boolean ;
582604 if ( isCreatingWatchedDirectory ) {
0 commit comments