@@ -594,7 +594,7 @@ namespace ts {
594
594
let diagnosticsProducingTypeChecker : TypeChecker ;
595
595
let noDiagnosticsTypeChecker : TypeChecker ;
596
596
let classifiableNames : UnderscoreEscapedMap < true > ;
597
- let modifiedFilePaths : Path [ ] | undefined ;
597
+ const ambientModuleNameToUnmodifiedFileName = createMap < string > ( ) ;
598
598
599
599
const cachedSemanticDiagnosticsForFile : DiagnosticCache < Diagnostic > = { } ;
600
600
const cachedDeclarationDiagnosticsForFile : DiagnosticCache < DiagnosticWithLocation > = { } ;
@@ -880,21 +880,14 @@ namespace ts {
880
880
return classifiableNames ;
881
881
}
882
882
883
- interface OldProgramState {
884
- program : Program | undefined ;
885
- oldSourceFile : SourceFile | undefined ;
886
- /** The collection of paths modified *since* the old program. */
887
- modifiedFilePaths : Path [ ] | undefined ;
888
- }
889
-
890
- function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , containingFile : string , file : SourceFile , oldProgramState : OldProgramState ) {
883
+ function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , containingFile : string , file : SourceFile ) {
891
884
if ( structuralIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
892
885
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
893
886
// the best we can do is fallback to the default logic.
894
887
return resolveModuleNamesWorker ( moduleNames , containingFile , /*reusedNames*/ undefined , getResolvedProjectReferenceToRedirect ( file . originalFileName ) ) ;
895
888
}
896
889
897
- const oldSourceFile = oldProgramState . program && oldProgramState . program . getSourceFile ( containingFile ) ;
890
+ const oldSourceFile = oldProgram && oldProgram . getSourceFile ( containingFile ) ;
898
891
if ( oldSourceFile !== file && file . resolvedModules ) {
899
892
// `file` was created for the new program.
900
893
//
@@ -958,7 +951,7 @@ namespace ts {
958
951
}
959
952
}
960
953
else {
961
- resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName , oldProgramState ) ;
954
+ resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName ) ;
962
955
}
963
956
964
957
if ( resolvesToAmbientModuleInNonModifiedFile ) {
@@ -1001,12 +994,9 @@ namespace ts {
1001
994
1002
995
// If we change our policy of rechecking failed lookups on each program create,
1003
996
// we should adjust the value returned here.
1004
- function moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName : string , oldProgramState : OldProgramState ) : boolean {
1005
- if ( ! oldProgramState . program ) {
1006
- return false ;
1007
- }
1008
- const resolutionToFile = getResolvedModule ( oldProgramState . oldSourceFile ! , moduleName ) ; // TODO: GH#18217
1009
- const resolvedFile = resolutionToFile && oldProgramState . program . getSourceFile ( resolutionToFile . resolvedFileName ) ;
997
+ function moduleNameResolvesToAmbientModuleInNonModifiedFile ( moduleName : string ) : boolean {
998
+ const resolutionToFile = getResolvedModule ( oldSourceFile ! , moduleName ) ;
999
+ const resolvedFile = resolutionToFile && oldProgram ! . getSourceFile ( resolutionToFile . resolvedFileName ) ;
1010
1000
if ( resolutionToFile && resolvedFile && ! resolvedFile . externalModuleIndicator ) {
1011
1001
// In the old program, we resolved to an ambient module that was in the same
1012
1002
// place as we expected to find an actual module file.
@@ -1016,16 +1006,14 @@ namespace ts {
1016
1006
}
1017
1007
1018
1008
// at least one of declarations should come from non-modified source file
1019
- const firstUnmodifiedFile = oldProgramState . program . getSourceFiles ( ) . find (
1020
- f => ! contains ( oldProgramState . modifiedFilePaths , f . path ) && contains ( f . ambientModuleNames , moduleName )
1021
- ) ;
1009
+ const unmodifiedFile = ambientModuleNameToUnmodifiedFileName . get ( moduleName ) ;
1022
1010
1023
- if ( ! firstUnmodifiedFile ) {
1011
+ if ( ! unmodifiedFile ) {
1024
1012
return false ;
1025
1013
}
1026
1014
1027
1015
if ( isTraceEnabled ( options , host ) ) {
1028
- trace ( host , Diagnostics . Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified , moduleName , firstUnmodifiedFile . fileName ) ;
1016
+ trace ( host , Diagnostics . Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified , moduleName , unmodifiedFile ) ;
1029
1017
}
1030
1018
return true ;
1031
1019
}
@@ -1213,14 +1201,20 @@ namespace ts {
1213
1201
return oldProgram . structureIsReused ;
1214
1202
}
1215
1203
1216
- modifiedFilePaths = modifiedSourceFiles . map ( f => f . newFile . path ) ;
1204
+ const modifiedFiles = modifiedSourceFiles . map ( f => f . oldFile ) ;
1205
+ for ( const oldFile of oldSourceFiles ) {
1206
+ if ( ! contains ( modifiedFiles , oldFile ) ) {
1207
+ for ( const moduleName of oldFile . ambientModuleNames ) {
1208
+ ambientModuleNameToUnmodifiedFileName . set ( moduleName , oldFile . fileName ) ;
1209
+ }
1210
+ }
1211
+ }
1217
1212
// try to verify results of module resolution
1218
1213
for ( const { oldFile : oldSourceFile , newFile : newSourceFile } of modifiedSourceFiles ) {
1219
1214
const newSourceFilePath = getNormalizedAbsolutePath ( newSourceFile . originalFileName , currentDirectory ) ;
1220
1215
if ( resolveModuleNamesWorker ) {
1221
1216
const moduleNames = getModuleNames ( newSourceFile ) ;
1222
- const oldProgramState : OldProgramState = { program : oldProgram , oldSourceFile, modifiedFilePaths } ;
1223
- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile , oldProgramState ) ;
1217
+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile ) ;
1224
1218
// ensure that module resolution results are still correct
1225
1219
const resolutionsChanged = hasChangesInResolutions ( moduleNames , resolutions , oldSourceFile . resolvedModules , moduleResolutionIsEqualTo ) ;
1226
1220
if ( resolutionsChanged ) {
@@ -2432,8 +2426,7 @@ namespace ts {
2432
2426
if ( file . imports . length || file . moduleAugmentations . length ) {
2433
2427
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
2434
2428
const moduleNames = getModuleNames ( file ) ;
2435
- const oldProgramState : OldProgramState = { program : oldProgram , oldSourceFile : oldProgram && oldProgram . getSourceFile ( file . fileName ) , modifiedFilePaths } ;
2436
- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) , file , oldProgramState ) ;
2429
+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) , file ) ;
2437
2430
Debug . assert ( resolutions . length === moduleNames . length ) ;
2438
2431
for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
2439
2432
const resolution = resolutions [ i ] ;
0 commit comments