@@ -574,7 +574,7 @@ namespace ts {
574
574
let diagnosticsProducingTypeChecker : TypeChecker ;
575
575
let noDiagnosticsTypeChecker : TypeChecker ;
576
576
let classifiableNames : UnderscoreEscapedMap < true > ;
577
- let modifiedFilePaths : Path [ ] | undefined ;
577
+ const ambientModuleNameToUnmodifiedFileName = createMap < string > ( ) ;
578
578
579
579
const cachedSemanticDiagnosticsForFile : DiagnosticCache < Diagnostic > = { } ;
580
580
const cachedDeclarationDiagnosticsForFile : DiagnosticCache < DiagnosticWithLocation > = { } ;
@@ -850,21 +850,14 @@ namespace ts {
850
850
return classifiableNames ;
851
851
}
852
852
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 ) {
861
854
if ( structuralIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
862
855
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
863
856
// the best we can do is fallback to the default logic.
864
857
return resolveModuleNamesWorker ( moduleNames , containingFile ) ;
865
858
}
866
859
867
- const oldSourceFile = oldProgramState . program && oldProgramState . program . getSourceFile ( containingFile ) ;
860
+ const oldSourceFile = oldProgram && oldProgram . getSourceFile ( containingFile ) ;
868
861
if ( oldSourceFile !== file && file . resolvedModules ) {
869
862
// `file` was created for the new program.
870
863
//
@@ -928,7 +921,7 @@ namespace ts {
928
921
}
929
922
}
930
923
else {
931
- resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName , oldProgramState ) ;
924
+ resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName ) ;
932
925
}
933
926
934
927
if ( resolvesToAmbientModuleInNonModifiedFile ) {
@@ -971,12 +964,9 @@ namespace ts {
971
964
972
965
// If we change our policy of rechecking failed lookups on each program create,
973
966
// 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 ) ;
980
970
if ( resolutionToFile && resolvedFile && ! resolvedFile . externalModuleIndicator ) {
981
971
// In the old program, we resolved to an ambient module that was in the same
982
972
// place as we expected to find an actual module file.
@@ -986,16 +976,14 @@ namespace ts {
986
976
}
987
977
988
978
// 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 ) ;
992
980
993
- if ( ! firstUnmodifiedFile ) {
981
+ if ( ! unmodifiedFile ) {
994
982
return false ;
995
983
}
996
984
997
985
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 ) ;
999
987
}
1000
988
return true ;
1001
989
}
@@ -1188,14 +1176,20 @@ namespace ts {
1188
1176
return oldProgram . structureIsReused ;
1189
1177
}
1190
1178
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
+ }
1192
1187
// try to verify results of module resolution
1193
1188
for ( const { oldFile : oldSourceFile , newFile : newSourceFile } of modifiedSourceFiles ) {
1194
1189
const newSourceFilePath = getNormalizedAbsolutePath ( newSourceFile . originalFileName , currentDirectory ) ;
1195
1190
if ( resolveModuleNamesWorker ) {
1196
1191
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 ) ;
1199
1193
// ensure that module resolution results are still correct
1200
1194
const resolutionsChanged = hasChangesInResolutions ( moduleNames , resolutions , oldSourceFile . resolvedModules , moduleResolutionIsEqualTo ) ;
1201
1195
if ( resolutionsChanged ) {
@@ -2308,8 +2302,7 @@ namespace ts {
2308
2302
if ( file . imports . length || file . moduleAugmentations . length ) {
2309
2303
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
2310
2304
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 ) ;
2313
2306
Debug . assert ( resolutions . length === moduleNames . length ) ;
2314
2307
for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
2315
2308
const resolution = resolutions [ i ] ;
0 commit comments