@@ -574,7 +574,7 @@ namespace ts {
574574 let diagnosticsProducingTypeChecker : TypeChecker ;
575575 let noDiagnosticsTypeChecker : TypeChecker ;
576576 let classifiableNames : UnderscoreEscapedMap < true > ;
577- let modifiedFilePaths : Path [ ] | undefined ;
577+ const ambientModuleNameToUnmodifiedFileName = createMap < string > ( ) ;
578578
579579 const cachedSemanticDiagnosticsForFile : DiagnosticCache < Diagnostic > = { } ;
580580 const cachedDeclarationDiagnosticsForFile : DiagnosticCache < DiagnosticWithLocation > = { } ;
@@ -850,21 +850,14 @@ namespace ts {
850850 return classifiableNames ;
851851 }
852852
853- interface OldProgramState {
854- program : Program | undefined ;
855- oldSourceFile : SourceFile | undefined ;
856- /** The collection of paths modified *since* the old program. */
857- modifiedFilePaths : Path [ ] | undefined ;
858- }
859-
860- function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , containingFile : string , file : SourceFile , oldProgramState : OldProgramState ) {
853+ function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , containingFile : string , file : SourceFile ) {
861854 if ( structuralIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
862855 // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
863856 // the best we can do is fallback to the default logic.
864857 return resolveModuleNamesWorker ( moduleNames , containingFile ) ;
865858 }
866859
867- const oldSourceFile = oldProgramState . program && oldProgramState . program . getSourceFile ( containingFile ) ;
860+ const oldSourceFile = oldProgram && oldProgram . getSourceFile ( containingFile ) ;
868861 if ( oldSourceFile !== file && file . resolvedModules ) {
869862 // `file` was created for the new program.
870863 //
@@ -928,7 +921,7 @@ namespace ts {
928921 }
929922 }
930923 else {
931- resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName , oldProgramState ) ;
924+ resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName ) ;
932925 }
933926
934927 if ( resolvesToAmbientModuleInNonModifiedFile ) {
@@ -971,12 +964,9 @@ namespace ts {
971964
972965 // If we change our policy of rechecking failed lookups on each program create,
973966 // we should adjust the value returned here.
974- function moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName : string , oldProgramState : OldProgramState ) : boolean {
975- if ( ! oldProgramState . program ) {
976- return false ;
977- }
978- const resolutionToFile = getResolvedModule ( oldProgramState . oldSourceFile ! , moduleName ) ; // TODO: GH#18217
979- const resolvedFile = resolutionToFile && oldProgramState . program . getSourceFile ( resolutionToFile . resolvedFileName ) ;
967+ function moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName : string ) : boolean {
968+ const resolutionToFile = getResolvedModule ( oldSourceFile ! , moduleName ) ;
969+ const resolvedFile = resolutionToFile && oldProgram ! . getSourceFile ( resolutionToFile . resolvedFileName ) ;
980970 if ( resolutionToFile && resolvedFile && ! resolvedFile . externalModuleIndicator ) {
981971 // In the old program, we resolved to an ambient module that was in the same
982972 // place as we expected to find an actual module file.
@@ -986,16 +976,14 @@ namespace ts {
986976 }
987977
988978 // at least one of declarations should come from non-modified source file
989- const firstUnmodifiedFile = oldProgramState . program . getSourceFiles ( ) . find (
990- f => ! contains ( oldProgramState . modifiedFilePaths , f . path ) && contains ( f . ambientModuleNames , moduleName )
991- ) ;
979+ const unmodifiedFile = ambientModuleNameToUnmodifiedFileName . get ( moduleName ) ;
992980
993- if ( ! firstUnmodifiedFile ) {
981+ if ( ! unmodifiedFile ) {
994982 return false ;
995983 }
996984
997985 if ( isTraceEnabled ( options , host ) ) {
998- trace ( host , Diagnostics . Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified , moduleName , firstUnmodifiedFile . fileName ) ;
986+ trace ( host , Diagnostics . Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified , moduleName , unmodifiedFile ) ;
999987 }
1000988 return true ;
1001989 }
@@ -1188,14 +1176,20 @@ namespace ts {
11881176 return oldProgram . structureIsReused ;
11891177 }
11901178
1191- modifiedFilePaths = modifiedSourceFiles . map ( f => f . newFile . path ) ;
1179+ const modifiedFiles = modifiedSourceFiles . map ( f => f . oldFile ) ;
1180+ for ( const oldFile of oldSourceFiles ) {
1181+ if ( ! contains ( modifiedFiles , oldFile ) ) {
1182+ for ( const moduleName of oldFile . ambientModuleNames ) {
1183+ ambientModuleNameToUnmodifiedFileName . set ( moduleName , oldFile . fileName ) ;
1184+ }
1185+ }
1186+ }
11921187 // try to verify results of module resolution
11931188 for ( const { oldFile : oldSourceFile , newFile : newSourceFile } of modifiedSourceFiles ) {
11941189 const newSourceFilePath = getNormalizedAbsolutePath ( newSourceFile . originalFileName , currentDirectory ) ;
11951190 if ( resolveModuleNamesWorker ) {
11961191 const moduleNames = getModuleNames ( newSourceFile ) ;
1197- const oldProgramState : OldProgramState = { program : oldProgram , oldSourceFile, modifiedFilePaths } ;
1198- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile , oldProgramState ) ;
1192+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile ) ;
11991193 // ensure that module resolution results are still correct
12001194 const resolutionsChanged = hasChangesInResolutions ( moduleNames , resolutions , oldSourceFile . resolvedModules , moduleResolutionIsEqualTo ) ;
12011195 if ( resolutionsChanged ) {
@@ -2308,8 +2302,7 @@ namespace ts {
23082302 if ( file . imports . length || file . moduleAugmentations . length ) {
23092303 // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
23102304 const moduleNames = getModuleNames ( file ) ;
2311- const oldProgramState : OldProgramState = { program : oldProgram , oldSourceFile : oldProgram && oldProgram . getSourceFile ( file . fileName ) , modifiedFilePaths } ;
2312- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) , file , oldProgramState ) ;
2305+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) , file ) ;
23132306 Debug . assert ( resolutions . length === moduleNames . length ) ;
23142307 for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
23152308 const resolution = resolutions [ i ] ;
0 commit comments