@@ -989,22 +989,60 @@ namespace ts {
989
989
990
990
return program ;
991
991
992
- function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : string , reusedNames ?: string [ ] , redirectedReference ?: ResolvedProjectReference ) {
992
+ function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : SourceFile , reusedNames : string [ ] | undefined ) : readonly ResolvedModuleFull [ ] {
993
+ if ( ! moduleNames . length ) return emptyArray ;
994
+ const containingFileName = getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) ;
995
+ const redirectedReference = getRedirectReferenceForResolution ( containingFile ) ;
993
996
performance . mark ( "beforeResolveModule" ) ;
994
- const result = actualResolveModuleNamesWorker ( moduleNames , containingFile , reusedNames , redirectedReference ) ;
997
+ const result = actualResolveModuleNamesWorker ( moduleNames , containingFileName , reusedNames , redirectedReference ) ;
995
998
performance . mark ( "afterResolveModule" ) ;
996
999
performance . measure ( "ResolveModule" , "beforeResolveModule" , "afterResolveModule" ) ;
997
1000
return result ;
998
1001
}
999
1002
1000
- function resolveTypeReferenceDirectiveNamesWorker ( typeDirectiveNames : string [ ] , containingFile : string , redirectedReference ?: ResolvedProjectReference ) {
1003
+ function resolveTypeReferenceDirectiveNamesWorker ( typeDirectiveNames : string [ ] , containingFile : string | SourceFile ) : readonly ( ResolvedTypeReferenceDirective | undefined ) [ ] {
1004
+ if ( ! typeDirectiveNames . length ) return [ ] ;
1001
1005
performance . mark ( "beforeResolveTypeReference" ) ;
1002
- const result = actualResolveTypeReferenceDirectiveNamesWorker ( typeDirectiveNames , containingFile , redirectedReference ) ;
1006
+ const containingFileName = ! isString ( containingFile ) ? getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) : containingFile ;
1007
+ const redirectedReference = ! isString ( containingFile ) ? getRedirectReferenceForResolution ( containingFile ) : undefined ;
1008
+ const result = actualResolveTypeReferenceDirectiveNamesWorker ( typeDirectiveNames , containingFileName , redirectedReference ) ;
1003
1009
performance . mark ( "afterResolveTypeReference" ) ;
1004
1010
performance . measure ( "ResolveTypeReference" , "beforeResolveTypeReference" , "afterResolveTypeReference" ) ;
1005
1011
return result ;
1006
1012
}
1007
1013
1014
+ function getRedirectReferenceForResolution ( file : SourceFile ) {
1015
+ const redirect = getResolvedProjectReferenceToRedirect ( file . originalFileName ) ;
1016
+ if ( redirect || ! fileExtensionIs ( file . originalFileName , Extension . Dts ) ) return redirect ;
1017
+
1018
+ // The originalFileName could not be actual source file name if file found was d.ts from referecned project
1019
+ // So in this case try to look up if this is output from referenced project, if it is use the redirected project in that case
1020
+ const resultFromDts = getRedirectReferenceForResolutionFromSourceOfProject ( file . originalFileName , file . path ) ;
1021
+ if ( resultFromDts ) return resultFromDts ;
1022
+
1023
+ // If preserveSymlinks is true, module resolution wont jump the symlink
1024
+ // but the resolved real path may be the .d.ts from project reference
1025
+ // Note:: Currently we try the real path only if the
1026
+ // file is from node_modules to avoid having to run real path on all file paths
1027
+ if ( ! host . realpath || ! options . preserveSymlinks || ! stringContains ( file . originalFileName , nodeModulesPathPart ) ) return undefined ;
1028
+ const realDeclarationFileName = host . realpath ( file . originalFileName ) ;
1029
+ const realDeclarationPath = toPath ( realDeclarationFileName ) ;
1030
+ return realDeclarationPath === file . path ? undefined : getRedirectReferenceForResolutionFromSourceOfProject ( realDeclarationFileName , realDeclarationPath ) ;
1031
+ }
1032
+
1033
+ function getRedirectReferenceForResolutionFromSourceOfProject ( fileName : string , filePath : Path ) {
1034
+ const source = getSourceOfProjectReferenceRedirect ( fileName ) ;
1035
+ if ( isString ( source ) ) return getResolvedProjectReferenceToRedirect ( source ) ;
1036
+ if ( ! source ) return undefined ;
1037
+ // Output of .d.ts file so return resolved ref that matches the out file name
1038
+ return forEachResolvedProjectReference ( resolvedRef => {
1039
+ if ( ! resolvedRef ) return undefined ;
1040
+ const out = outFile ( resolvedRef . commandLine . options ) ;
1041
+ if ( ! out ) return undefined ;
1042
+ return toPath ( out ) === filePath ? resolvedRef : undefined ;
1043
+ } ) ;
1044
+ }
1045
+
1008
1046
function compareDefaultLibFiles ( a : SourceFile , b : SourceFile ) {
1009
1047
return compareValues ( getDefaultLibFilePriority ( a ) , getDefaultLibFilePriority ( b ) ) ;
1010
1048
}
@@ -1068,14 +1106,14 @@ namespace ts {
1068
1106
return classifiableNames ;
1069
1107
}
1070
1108
1071
- function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , containingFile : string , file : SourceFile ) {
1109
+ function resolveModuleNamesReusingOldState ( moduleNames : string [ ] , file : SourceFile ) : readonly ResolvedModuleFull [ ] {
1072
1110
if ( structuralIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
1073
1111
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
1074
1112
// the best we can do is fallback to the default logic.
1075
- return resolveModuleNamesWorker ( moduleNames , containingFile , /*reusedNames*/ undefined , getResolvedProjectReferenceToRedirect ( file . originalFileName ) ) ;
1113
+ return resolveModuleNamesWorker ( moduleNames , file , /*reusedNames*/ undefined ) ;
1076
1114
}
1077
1115
1078
- const oldSourceFile = oldProgram && oldProgram . getSourceFile ( containingFile ) ;
1116
+ const oldSourceFile = oldProgram && oldProgram . getSourceFile ( file . fileName ) ;
1079
1117
if ( oldSourceFile !== file && file . resolvedModules ) {
1080
1118
// `file` was created for the new program.
1081
1119
//
@@ -1120,7 +1158,7 @@ namespace ts {
1120
1158
const oldResolvedModule = getResolvedModule ( oldSourceFile , moduleName ) ;
1121
1159
if ( oldResolvedModule ) {
1122
1160
if ( isTraceEnabled ( options , host ) ) {
1123
- trace ( host , Diagnostics . Reusing_resolution_of_module_0_to_file_1_from_old_program , moduleName , containingFile ) ;
1161
+ trace ( host , Diagnostics . Reusing_resolution_of_module_0_to_file_1_from_old_program , moduleName , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) ) ;
1124
1162
}
1125
1163
( result || ( result = new Array ( moduleNames . length ) ) ) [ i ] = oldResolvedModule ;
1126
1164
( reusedNames || ( reusedNames = [ ] ) ) . push ( moduleName ) ;
@@ -1135,7 +1173,7 @@ namespace ts {
1135
1173
if ( contains ( file . ambientModuleNames , moduleName ) ) {
1136
1174
resolvesToAmbientModuleInNonModifiedFile = true ;
1137
1175
if ( isTraceEnabled ( options , host ) ) {
1138
- trace ( host , Diagnostics . Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1 , moduleName , containingFile ) ;
1176
+ trace ( host , Diagnostics . Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1 , moduleName , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) ) ;
1139
1177
}
1140
1178
}
1141
1179
else {
@@ -1152,7 +1190,7 @@ namespace ts {
1152
1190
}
1153
1191
1154
1192
const resolutions = unknownModuleNames && unknownModuleNames . length
1155
- ? resolveModuleNamesWorker ( unknownModuleNames , containingFile , reusedNames , getResolvedProjectReferenceToRedirect ( file . originalFileName ) )
1193
+ ? resolveModuleNamesWorker ( unknownModuleNames , file , reusedNames )
1156
1194
: emptyArray ;
1157
1195
1158
1196
// Combine results of resolutions and predicted results
@@ -1397,9 +1435,8 @@ namespace ts {
1397
1435
}
1398
1436
// try to verify results of module resolution
1399
1437
for ( const { oldFile : oldSourceFile , newFile : newSourceFile } of modifiedSourceFiles ) {
1400
- const newSourceFilePath = getNormalizedAbsolutePath ( newSourceFile . originalFileName , currentDirectory ) ;
1401
1438
const moduleNames = getModuleNames ( newSourceFile ) ;
1402
- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile ) ;
1439
+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFile ) ;
1403
1440
// ensure that module resolution results are still correct
1404
1441
const resolutionsChanged = hasChangesInResolutions ( moduleNames , resolutions , oldSourceFile . resolvedModules , moduleResolutionIsEqualTo ) ;
1405
1442
if ( resolutionsChanged ) {
@@ -1409,19 +1446,17 @@ namespace ts {
1409
1446
else {
1410
1447
newSourceFile . resolvedModules = oldSourceFile . resolvedModules ;
1411
1448
}
1412
- if ( resolveTypeReferenceDirectiveNamesWorker ) {
1413
- // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
1414
- const typesReferenceDirectives = map ( newSourceFile . typeReferenceDirectives , ref => toFileNameLowerCase ( ref . fileName ) ) ;
1415
- const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typesReferenceDirectives , newSourceFilePath , getResolvedProjectReferenceToRedirect ( newSourceFile . originalFileName ) ) ;
1416
- // ensure that types resolutions are still correct
1417
- const resolutionsChanged = hasChangesInResolutions ( typesReferenceDirectives , resolutions , oldSourceFile . resolvedTypeReferenceDirectiveNames , typeDirectiveIsEqualTo ) ;
1418
- if ( resolutionsChanged ) {
1419
- oldProgram . structureIsReused = StructureIsReused . SafeModules ;
1420
- newSourceFile . resolvedTypeReferenceDirectiveNames = zipToMap ( typesReferenceDirectives , resolutions ) ;
1421
- }
1422
- else {
1423
- newSourceFile . resolvedTypeReferenceDirectiveNames = oldSourceFile . resolvedTypeReferenceDirectiveNames ;
1424
- }
1449
+ // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
1450
+ const typesReferenceDirectives = map ( newSourceFile . typeReferenceDirectives , ref => toFileNameLowerCase ( ref . fileName ) ) ;
1451
+ const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker ( typesReferenceDirectives , newSourceFile ) ;
1452
+ // ensure that types resolutions are still correct
1453
+ const typeReferenceEesolutionsChanged = hasChangesInResolutions ( typesReferenceDirectives , typeReferenceResolutions , oldSourceFile . resolvedTypeReferenceDirectiveNames , typeDirectiveIsEqualTo ) ;
1454
+ if ( typeReferenceEesolutionsChanged ) {
1455
+ oldProgram . structureIsReused = StructureIsReused . SafeModules ;
1456
+ newSourceFile . resolvedTypeReferenceDirectiveNames = zipToMap ( typesReferenceDirectives , typeReferenceResolutions ) ;
1457
+ }
1458
+ else {
1459
+ newSourceFile . resolvedTypeReferenceDirectiveNames = oldSourceFile . resolvedTypeReferenceDirectiveNames ;
1425
1460
}
1426
1461
}
1427
1462
@@ -2685,7 +2720,7 @@ namespace ts {
2685
2720
return ;
2686
2721
}
2687
2722
2688
- const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeDirectives , file . originalFileName , getResolvedProjectReferenceToRedirect ( file . originalFileName ) ) ;
2723
+ const resolutions = resolveTypeReferenceDirectiveNamesWorker ( typeDirectives , file ) ;
2689
2724
2690
2725
for ( let i = 0 ; i < typeDirectives . length ; i ++ ) {
2691
2726
const ref = file . typeReferenceDirectives [ i ] ;
@@ -2823,7 +2858,7 @@ namespace ts {
2823
2858
if ( file . imports . length || file . moduleAugmentations . length ) {
2824
2859
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
2825
2860
const moduleNames = getModuleNames ( file ) ;
2826
- const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . originalFileName , currentDirectory ) , file ) ;
2861
+ const resolutions = resolveModuleNamesReusingOldState ( moduleNames , file ) ;
2827
2862
Debug . assert ( resolutions . length === moduleNames . length ) ;
2828
2863
for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
2829
2864
const resolution = resolutions [ i ] ;
0 commit comments