5
5
changeAnyExtension ,
6
6
CharacterCodes ,
7
7
combinePaths ,
8
+ CommandLineOption ,
8
9
comparePaths ,
9
10
Comparison ,
10
11
CompilerOptions ,
@@ -35,6 +36,7 @@ import {
35
36
getBaseFileName ,
36
37
GetCanonicalFileName ,
37
38
getCommonSourceDirectory ,
39
+ getCompilerOptionValue ,
38
40
getDirectoryPath ,
39
41
GetEffectiveTypeRootsHost ,
40
42
getEmitModuleKind ,
@@ -66,14 +68,13 @@ import {
66
68
ModuleKind ,
67
69
ModuleResolutionHost ,
68
70
ModuleResolutionKind ,
71
+ moduleResolutionOptionDeclarations ,
69
72
noop ,
70
73
noopPush ,
71
74
normalizePath ,
72
75
normalizeSlashes ,
73
- optionsHaveModuleResolutionChanges ,
74
76
PackageId ,
75
77
packageIdToString ,
76
- ParsedCommandLine ,
77
78
Path ,
78
79
pathIsRelative ,
79
80
Pattern ,
@@ -718,58 +719,97 @@ export interface PerModuleNameCache {
718
719
set ( directory : string , result : ResolvedModuleWithFailedLookupLocations ) : void ;
719
720
}
720
721
722
+ function compilerOptionValueToString ( value : unknown ) : string {
723
+ if ( value === null || typeof value !== "object" ) { // eslint-disable-line no-null/no-null
724
+ return "" + value ;
725
+ }
726
+ if ( isArray ( value ) ) {
727
+ return `[${ value . map ( e => compilerOptionValueToString ( e ) ) ?. join ( "," ) } ]` ;
728
+ }
729
+ let str = "{" ;
730
+ for ( const key in value ) {
731
+ if ( hasProperty ( value , key ) ) {
732
+ str += `${ key } : ${ compilerOptionValueToString ( ( value as any ) [ key ] ) } ` ;
733
+ }
734
+ }
735
+ return str + "}" ;
736
+ }
737
+
721
738
/** @internal */
722
- export interface CacheWithRedirects < T > {
723
- getOwnMap : ( ) => Map < string , T > ;
724
- redirectsMap : Map < Path , Map < string , T > > ;
725
- getOrCreateMapOfCacheRedirects ( redirectedReference : ResolvedProjectReference | undefined ) : Map < string , T > ;
739
+ export function getKeyForCompilerOptions ( options : CompilerOptions , affectingOptionDeclarations : readonly CommandLineOption [ ] ) {
740
+ return affectingOptionDeclarations . map ( option => compilerOptionValueToString ( getCompilerOptionValue ( options , option ) ) ) . join ( "|" ) + ( options . pathsBasePath ? `|${ options . pathsBasePath } ` : undefined ) ;
741
+ }
742
+
743
+ /** @internal */
744
+ export interface CacheWithRedirects < K , V > {
745
+ getOrCreateMapOfCacheRedirects ( redirectedReference : ResolvedProjectReference | undefined ) : Map < K , V > ;
746
+ update ( newOptions : CompilerOptions ) : void ;
726
747
clear ( ) : void ;
727
- setOwnOptions ( newOptions : CompilerOptions ) : void ;
728
- setOwnMap ( newOwnMap : Map < string , T > ) : void ;
729
748
}
730
749
731
750
/** @internal */
732
- export function createCacheWithRedirects < T > ( options ?: CompilerOptions ) : CacheWithRedirects < T > {
733
- let ownMap : Map < string , T > = new Map ( ) ;
734
- const redirectsMap = new Map < Path , Map < string , T > > ( ) ;
751
+ export function createCacheWithRedirects < K , V > ( ownOptions : CompilerOptions | undefined ) : CacheWithRedirects < K , V > {
752
+ type RedirectsCacheKey = string & { __compilerOptionsKey : any ; } ;
753
+ const redirectsMap = new Map < CompilerOptions , Map < K , V > > ( ) ;
754
+ const optionsToRedirectsKey = new Map < CompilerOptions , RedirectsCacheKey > ( ) ;
755
+ const redirectsKeyToMap = new Map < RedirectsCacheKey , Map < K , V > > ( ) ;
756
+ let ownMap = new Map < K , V > ( ) ;
757
+ if ( ownOptions ) redirectsMap . set ( ownOptions , ownMap ) ;
735
758
return {
736
- getOwnMap,
737
- redirectsMap,
738
759
getOrCreateMapOfCacheRedirects,
760
+ update,
739
761
clear,
740
- setOwnOptions,
741
- setOwnMap
742
762
} ;
743
763
744
- function getOwnMap ( ) {
745
- return ownMap ;
746
- }
747
-
748
- function setOwnOptions ( newOptions : CompilerOptions ) {
749
- options = newOptions ;
764
+ function getOrCreateMapOfCacheRedirects ( redirectedReference : ResolvedProjectReference | undefined ) : Map < K , V > {
765
+ return redirectedReference ?
766
+ getOrCreateMap ( redirectedReference . commandLine . options ) :
767
+ ownMap ;
750
768
}
751
769
752
- function setOwnMap ( newOwnMap : Map < string , T > ) {
753
- ownMap = newOwnMap ;
770
+ function update ( newOptions : CompilerOptions ) {
771
+ if ( ownOptions !== newOptions ) {
772
+ if ( ownOptions ) ownMap = getOrCreateMap ( newOptions ) ; // set new map for new options as ownMap
773
+ else redirectsMap . set ( newOptions , ownMap ) ; // Use existing map if oldOptions = undefined
774
+ ownOptions = newOptions ;
775
+ }
754
776
}
755
777
756
- function getOrCreateMapOfCacheRedirects ( redirectedReference : ResolvedProjectReference | undefined ) {
757
- if ( ! redirectedReference ) {
758
- return ownMap ;
759
- }
760
- const path = redirectedReference . sourceFile . path ;
761
- let redirects = redirectsMap . get ( path ) ;
762
- if ( ! redirects ) {
763
- // Reuse map if redirected reference map uses same resolution
764
- redirects = ! options || optionsHaveModuleResolutionChanges ( options , redirectedReference . commandLine . options ) ? new Map ( ) : ownMap ;
765
- redirectsMap . set ( path , redirects ) ;
778
+ function getOrCreateMap ( redirectOptions : CompilerOptions ) : Map < K , V > {
779
+ let result = redirectsMap . get ( redirectOptions ) ;
780
+ if ( result ) return result ;
781
+ const key = getRedirectsCacheKey ( redirectOptions ) ;
782
+ result = redirectsKeyToMap . get ( key ) ;
783
+ if ( ! result ) {
784
+ if ( ownOptions ) {
785
+ const ownKey = getRedirectsCacheKey ( ownOptions ) ;
786
+ if ( ownKey === key ) result = ownMap ;
787
+ else if ( ! redirectsKeyToMap . has ( ownKey ) ) redirectsKeyToMap . set ( ownKey , ownMap ) ;
788
+ }
789
+ redirectsKeyToMap . set ( key , result ??= new Map ( ) ) ;
766
790
}
767
- return redirects ;
791
+ redirectsMap . set ( redirectOptions , result ) ;
792
+ return result ;
768
793
}
769
794
770
795
function clear ( ) {
796
+ const ownKey = ownOptions && optionsToRedirectsKey . get ( ownOptions ) ;
771
797
ownMap . clear ( ) ;
772
798
redirectsMap . clear ( ) ;
799
+ optionsToRedirectsKey . clear ( ) ;
800
+ redirectsKeyToMap . clear ( ) ;
801
+ if ( ownOptions ) {
802
+ if ( ownKey ) optionsToRedirectsKey . set ( ownOptions , ownKey ) ;
803
+ redirectsMap . set ( ownOptions , ownMap ) ;
804
+ }
805
+ }
806
+
807
+ function getRedirectsCacheKey ( options : CompilerOptions ) {
808
+ let result = optionsToRedirectsKey . get ( options ) ;
809
+ if ( ! result ) {
810
+ optionsToRedirectsKey . set ( options , result = getKeyForCompilerOptions ( options , moduleResolutionOptionDeclarations ) as RedirectsCacheKey ) ;
811
+ }
812
+ return result ;
773
813
}
774
814
}
775
815
@@ -794,7 +834,7 @@ function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileNa
794
834
}
795
835
}
796
836
797
- function getOrCreateCache < T > ( cacheWithRedirects : CacheWithRedirects < T > , redirectedReference : ResolvedProjectReference | undefined , key : string , create : ( ) => T ) : T {
837
+ function getOrCreateCache < K , V > ( cacheWithRedirects : CacheWithRedirects < K , V > , redirectedReference : ResolvedProjectReference | undefined , key : K , create : ( ) => V ) : V {
798
838
const cache = cacheWithRedirects . getOrCreateMapOfCacheRedirects ( redirectedReference ) ;
799
839
let result = cache . get ( key ) ;
800
840
if ( ! result ) {
@@ -804,35 +844,7 @@ function getOrCreateCache<T>(cacheWithRedirects: CacheWithRedirects<T>, redirect
804
844
return result ;
805
845
}
806
846
807
- function updateRedirectsMap < T > (
808
- options : CompilerOptions ,
809
- directoryToModuleNameMap : CacheWithRedirects < ModeAwareCache < T > > ,
810
- moduleNameToDirectoryMap ?: CacheWithRedirects < PerModuleNameCache >
811
- ) {
812
- if ( ! options . configFile ) return ;
813
- if ( directoryToModuleNameMap . redirectsMap . size === 0 ) {
814
- // The own map will be for projectCompilerOptions
815
- Debug . assert ( ! moduleNameToDirectoryMap || moduleNameToDirectoryMap . redirectsMap . size === 0 ) ;
816
- Debug . assert ( directoryToModuleNameMap . getOwnMap ( ) . size === 0 ) ;
817
- Debug . assert ( ! moduleNameToDirectoryMap || moduleNameToDirectoryMap . getOwnMap ( ) . size === 0 ) ;
818
- directoryToModuleNameMap . redirectsMap . set ( options . configFile . path , directoryToModuleNameMap . getOwnMap ( ) ) ;
819
- moduleNameToDirectoryMap ?. redirectsMap . set ( options . configFile . path , moduleNameToDirectoryMap . getOwnMap ( ) ) ;
820
- }
821
- else {
822
- // Set correct own map
823
- Debug . assert ( ! moduleNameToDirectoryMap || moduleNameToDirectoryMap . redirectsMap . size > 0 ) ;
824
- const ref : ResolvedProjectReference = {
825
- sourceFile : options . configFile ,
826
- commandLine : { options } as ParsedCommandLine
827
- } ;
828
- directoryToModuleNameMap . setOwnMap ( directoryToModuleNameMap . getOrCreateMapOfCacheRedirects ( ref ) ) ;
829
- moduleNameToDirectoryMap ?. setOwnMap ( moduleNameToDirectoryMap . getOrCreateMapOfCacheRedirects ( ref ) ) ;
830
- }
831
- directoryToModuleNameMap . setOwnOptions ( options ) ;
832
- moduleNameToDirectoryMap ?. setOwnOptions ( options ) ;
833
- }
834
-
835
- function createPerDirectoryResolutionCache < T > ( currentDirectory : string , getCanonicalFileName : GetCanonicalFileName , directoryToModuleNameMap : CacheWithRedirects < ModeAwareCache < T > > ) : PerDirectoryResolutionCache < T > {
847
+ function createPerDirectoryResolutionCache < T > ( currentDirectory : string , getCanonicalFileName : GetCanonicalFileName , directoryToModuleNameMap : CacheWithRedirects < Path , ModeAwareCache < T > > ) : PerDirectoryResolutionCache < T > {
836
848
return {
837
849
getOrCreateCacheForDirectory,
838
850
clear,
@@ -844,19 +856,24 @@ function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanon
844
856
}
845
857
846
858
function update ( options : CompilerOptions ) {
847
- updateRedirectsMap ( options , directoryToModuleNameMap ) ;
859
+ directoryToModuleNameMap . update ( options ) ;
848
860
}
849
861
850
862
function getOrCreateCacheForDirectory ( directoryName : string , redirectedReference ?: ResolvedProjectReference ) {
851
863
const path = toPath ( directoryName , currentDirectory , getCanonicalFileName ) ;
852
- return getOrCreateCache < ModeAwareCache < T > > ( directoryToModuleNameMap , redirectedReference , path , ( ) => createModeAwareCache ( ) ) ;
864
+ return getOrCreateCache ( directoryToModuleNameMap , redirectedReference , path , ( ) => createModeAwareCache ( ) ) ;
853
865
}
854
866
}
855
867
868
+ /** @internal */
869
+ export type ModeAwareCacheKey = string & { __modeAwareCacheKey : any ; } ;
870
+ /** @internal */
871
+ export function createModeAwareCacheKey ( specifier : string , mode : ResolutionMode ) {
872
+ return ( mode === undefined ? specifier : `${ mode } |${ specifier } ` ) as ModeAwareCacheKey ;
873
+ }
856
874
/** @internal */
857
875
export function createModeAwareCache < T > ( ) : ModeAwareCache < T > {
858
876
const underlying = new Map < ModeAwareCacheKey , T > ( ) ;
859
- type ModeAwareCacheKey = string & { __modeAwareCacheKey : any ; } ;
860
877
const memoizedReverseKeys = new Map < ModeAwareCacheKey , [ specifier : string , mode : ResolutionMode ] > ( ) ;
861
878
862
879
const cache : ModeAwareCache < T > = {
@@ -887,7 +904,7 @@ export function createModeAwareCache<T>(): ModeAwareCache<T> {
887
904
return cache ;
888
905
889
906
function getUnderlyingCacheKey ( specifier : string , mode : ResolutionMode ) {
890
- const result = ( mode === undefined ? specifier : ` ${ mode } | ${ specifier } ` ) as ModeAwareCacheKey ;
907
+ const result = createModeAwareCacheKey ( specifier , mode ) ;
891
908
memoizedReverseKeys . set ( result , [ specifier , mode ] ) ;
892
909
return result ;
893
910
}
@@ -919,24 +936,10 @@ export function createModuleResolutionCache(
919
936
currentDirectory : string ,
920
937
getCanonicalFileName : ( s : string ) => string ,
921
938
options ?: CompilerOptions
922
- ) : ModuleResolutionCache ;
923
- /** @internal */
924
- export function createModuleResolutionCache (
925
- currentDirectory : string ,
926
- getCanonicalFileName : GetCanonicalFileName ,
927
- options : undefined ,
928
- directoryToModuleNameMap : CacheWithRedirects < ModeAwareCache < ResolvedModuleWithFailedLookupLocations > > ,
929
- moduleNameToDirectoryMap : CacheWithRedirects < PerModuleNameCache > ,
930
- ) : ModuleResolutionCache ;
931
- export function createModuleResolutionCache (
932
- currentDirectory : string ,
933
- getCanonicalFileName : GetCanonicalFileName ,
934
- options ?: CompilerOptions ,
935
- directoryToModuleNameMap ?: CacheWithRedirects < ModeAwareCache < ResolvedModuleWithFailedLookupLocations > > ,
936
- moduleNameToDirectoryMap ?: CacheWithRedirects < PerModuleNameCache > ,
937
939
) : ModuleResolutionCache {
938
- const perDirectoryResolutionCache = createPerDirectoryResolutionCache ( currentDirectory , getCanonicalFileName , directoryToModuleNameMap ||= createCacheWithRedirects ( options ) ) ;
939
- moduleNameToDirectoryMap ||= createCacheWithRedirects ( options ) ;
940
+ const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < ResolvedModuleWithFailedLookupLocations > > ( options ) ;
941
+ const perDirectoryResolutionCache = createPerDirectoryResolutionCache ( currentDirectory , getCanonicalFileName , directoryToModuleNameMap ) ;
942
+ const moduleNameToDirectoryMap = createCacheWithRedirects < ModeAwareCacheKey , PerModuleNameCache > ( options ) ;
940
943
const packageJsonInfoCache = createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
941
944
942
945
return {
@@ -956,20 +959,21 @@ export function createModuleResolutionCache(
956
959
957
960
function clearAllExceptPackageJsonInfoCache ( ) {
958
961
perDirectoryResolutionCache . clear ( ) ;
959
- moduleNameToDirectoryMap ! . clear ( ) ;
962
+ moduleNameToDirectoryMap . clear ( ) ;
960
963
}
961
964
962
965
function update ( options : CompilerOptions ) {
963
- updateRedirectsMap ( options , directoryToModuleNameMap ! , moduleNameToDirectoryMap ) ;
966
+ directoryToModuleNameMap . update ( options ) ;
967
+ moduleNameToDirectoryMap . update ( options ) ;
964
968
}
965
969
966
970
function getOrCreateCacheForModuleName ( nonRelativeModuleName : string , mode : ResolutionMode , redirectedReference ?: ResolvedProjectReference ) : PerModuleNameCache {
967
971
Debug . assert ( ! isExternalModuleNameRelative ( nonRelativeModuleName ) ) ;
968
- return getOrCreateCache ( moduleNameToDirectoryMap ! , redirectedReference , mode === undefined ? nonRelativeModuleName : ` ${ mode } | ${ nonRelativeModuleName } ` , createPerModuleNameCache ) ;
972
+ return getOrCreateCache ( moduleNameToDirectoryMap , redirectedReference , createModeAwareCacheKey ( nonRelativeModuleName , mode ) , createPerModuleNameCache ) ;
969
973
}
970
974
971
975
function createPerModuleNameCache ( ) : PerModuleNameCache {
972
- const directoryPathMap = new Map < string , ResolvedModuleWithFailedLookupLocations > ( ) ;
976
+ const directoryPathMap = new Map < Path , ResolvedModuleWithFailedLookupLocations > ( ) ;
973
977
974
978
return { get, set } ;
975
979
@@ -1046,23 +1050,9 @@ export function createTypeReferenceDirectiveResolutionCache(
1046
1050
getCanonicalFileName : ( s : string ) => string ,
1047
1051
options ?: CompilerOptions ,
1048
1052
packageJsonInfoCache ?: PackageJsonInfoCache ,
1049
- ) : TypeReferenceDirectiveResolutionCache ;
1050
- /** @internal */
1051
- export function createTypeReferenceDirectiveResolutionCache (
1052
- currentDirectory : string ,
1053
- getCanonicalFileName : GetCanonicalFileName ,
1054
- options : undefined ,
1055
- packageJsonInfoCache : PackageJsonInfoCache | undefined ,
1056
- directoryToModuleNameMap : CacheWithRedirects < ModeAwareCache < ResolvedTypeReferenceDirectiveWithFailedLookupLocations > > ,
1057
- ) : TypeReferenceDirectiveResolutionCache ;
1058
- export function createTypeReferenceDirectiveResolutionCache (
1059
- currentDirectory : string ,
1060
- getCanonicalFileName : GetCanonicalFileName ,
1061
- options ?: CompilerOptions ,
1062
- packageJsonInfoCache ?: PackageJsonInfoCache | undefined ,
1063
- directoryToModuleNameMap ?: CacheWithRedirects < ModeAwareCache < ResolvedTypeReferenceDirectiveWithFailedLookupLocations > > ,
1064
1053
) : TypeReferenceDirectiveResolutionCache {
1065
- const perDirectoryResolutionCache = createPerDirectoryResolutionCache ( currentDirectory , getCanonicalFileName , directoryToModuleNameMap ||= createCacheWithRedirects ( options ) ) ;
1054
+ const directoryToModuleNameMap = createCacheWithRedirects < Path , ModeAwareCache < ResolvedTypeReferenceDirectiveWithFailedLookupLocations > > ( options ) ;
1055
+ const perDirectoryResolutionCache = createPerDirectoryResolutionCache ( currentDirectory , getCanonicalFileName , directoryToModuleNameMap ) ;
1066
1056
packageJsonInfoCache ||= createPackageJsonInfoCache ( currentDirectory , getCanonicalFileName ) ;
1067
1057
1068
1058
return {
0 commit comments