@@ -90,6 +90,35 @@ namespace ts.moduleSpecifiers {
9090 getLocalModuleSpecifier ( toFileName , info , compilerOptions , host , preferences ) ;
9191 }
9292
93+ export function tryGetModuleSpecifiersFromCache (
94+ moduleSymbol : Symbol ,
95+ importingSourceFile : SourceFile ,
96+ host : ModuleSpecifierResolutionHost ,
97+ userPreferences : UserPreferences ,
98+ ) : readonly string [ ] | undefined {
99+ return tryGetModuleSpecifiersFromCacheWorker (
100+ moduleSymbol ,
101+ importingSourceFile ,
102+ host ,
103+ userPreferences ) [ 0 ] ;
104+ }
105+
106+ function tryGetModuleSpecifiersFromCacheWorker (
107+ moduleSymbol : Symbol ,
108+ importingSourceFile : SourceFile ,
109+ host : ModuleSpecifierResolutionHost ,
110+ userPreferences : UserPreferences ,
111+ ) : readonly [ specifiers ?: readonly string [ ] , moduleFile ?: SourceFile , modulePaths ?: readonly ModulePath [ ] , cache ?: ModuleSpecifierCache ] {
112+ const moduleSourceFile = getSourceFileOfModule ( moduleSymbol ) ;
113+ if ( ! moduleSourceFile ) {
114+ return emptyArray as [ ] ;
115+ }
116+
117+ const cache = host . getModuleSpecifierCache ?.( ) ;
118+ const cached = cache ?. get ( importingSourceFile . path , moduleSourceFile . path , userPreferences ) ;
119+ return [ cached ?. moduleSpecifiers , moduleSourceFile , cached ?. modulePaths , cache ] ;
120+ }
121+
93122 /** Returns an import for each symlink and for the realpath. */
94123 export function getModuleSpecifiers (
95124 moduleSymbol : Symbol ,
@@ -99,24 +128,53 @@ namespace ts.moduleSpecifiers {
99128 host : ModuleSpecifierResolutionHost ,
100129 userPreferences : UserPreferences ,
101130 ) : readonly string [ ] {
102- const ambient = tryGetModuleNameFromAmbientModule ( moduleSymbol , checker ) ;
103- if ( ambient ) return [ ambient ] ;
131+ return getModuleSpecifiersWithCacheInfo (
132+ moduleSymbol ,
133+ checker ,
134+ compilerOptions ,
135+ importingSourceFile ,
136+ host ,
137+ userPreferences ,
138+ ) . moduleSpecifiers ;
139+ }
104140
105- const info = getInfo ( importingSourceFile . path , host ) ;
106- const moduleSourceFile = getSourceFileOfNode ( moduleSymbol . valueDeclaration || getNonAugmentationDeclaration ( moduleSymbol ) ) ;
107- if ( ! moduleSourceFile ) {
108- return [ ] ;
109- }
141+ export function getModuleSpecifiersWithCacheInfo (
142+ moduleSymbol : Symbol ,
143+ checker : TypeChecker ,
144+ compilerOptions : CompilerOptions ,
145+ importingSourceFile : SourceFile ,
146+ host : ModuleSpecifierResolutionHost ,
147+ userPreferences : UserPreferences ,
148+ ) : { moduleSpecifiers : readonly string [ ] , computedWithoutCache : boolean } {
149+ let computedWithoutCache = false ;
150+ const ambient = tryGetModuleNameFromAmbientModule ( moduleSymbol , checker ) ;
151+ if ( ambient ) return { moduleSpecifiers : [ ambient ] , computedWithoutCache } ;
110152
111- const cache = host . getModuleSpecifierCache ?.( ) ;
112- const cached = cache ?. get ( importingSourceFile . path , moduleSourceFile . path , userPreferences ) ;
113- let modulePaths ;
114- if ( cached ) {
115- if ( cached . moduleSpecifiers ) return cached . moduleSpecifiers ;
116- modulePaths = cached . modulePaths ;
117- }
153+ // eslint-disable-next-line prefer-const
154+ let [ specifiers , moduleSourceFile , modulePaths , cache ] = tryGetModuleSpecifiersFromCacheWorker (
155+ moduleSymbol ,
156+ importingSourceFile ,
157+ host ,
158+ userPreferences ,
159+ ) ;
160+ if ( specifiers ) return { moduleSpecifiers : specifiers , computedWithoutCache } ;
161+ if ( ! moduleSourceFile ) return { moduleSpecifiers : emptyArray , computedWithoutCache } ;
118162
163+ computedWithoutCache = true ;
119164 modulePaths ||= getAllModulePathsWorker ( importingSourceFile . path , moduleSourceFile . originalFileName , host ) ;
165+ const result = computeModuleSpecifiers ( modulePaths , compilerOptions , importingSourceFile , host , userPreferences ) ;
166+ cache ?. set ( importingSourceFile . path , moduleSourceFile . path , userPreferences , modulePaths , result ) ;
167+ return { moduleSpecifiers : result , computedWithoutCache } ;
168+ }
169+
170+ function computeModuleSpecifiers (
171+ modulePaths : readonly ModulePath [ ] ,
172+ compilerOptions : CompilerOptions ,
173+ importingSourceFile : SourceFile ,
174+ host : ModuleSpecifierResolutionHost ,
175+ userPreferences : UserPreferences ,
176+ ) : readonly string [ ] {
177+ const info = getInfo ( importingSourceFile . path , host ) ;
120178 const preferences = getPreferences ( userPreferences , compilerOptions , importingSourceFile ) ;
121179 const existingSpecifier = forEach ( modulePaths , modulePath => forEach (
122180 host . getFileIncludeReasons ( ) . get ( toPath ( modulePath . path , host . getCurrentDirectory ( ) , info . getCanonicalFileName ) ) ,
@@ -131,7 +189,6 @@ namespace ts.moduleSpecifiers {
131189 ) ) ;
132190 if ( existingSpecifier ) {
133191 const moduleSpecifiers = [ existingSpecifier ] ;
134- cache ?. set ( importingSourceFile . path , moduleSourceFile . path , userPreferences , modulePaths , moduleSpecifiers ) ;
135192 return moduleSpecifiers ;
136193 }
137194
@@ -151,7 +208,6 @@ namespace ts.moduleSpecifiers {
151208 if ( specifier && modulePath . isRedirect ) {
152209 // If we got a specifier for a redirect, it was a bare package specifier (e.g. "@foo/bar",
153210 // not "@foo/bar/path/to/file"). No other specifier will be this good, so stop looking.
154- cache ?. set ( importingSourceFile . path , moduleSourceFile . path , userPreferences , modulePaths , nodeModulesSpecifiers ! ) ;
155211 return nodeModulesSpecifiers ! ;
156212 }
157213
@@ -175,11 +231,9 @@ namespace ts.moduleSpecifiers {
175231 }
176232 }
177233
178- const moduleSpecifiers = pathsSpecifiers ?. length ? pathsSpecifiers :
234+ return pathsSpecifiers ?. length ? pathsSpecifiers :
179235 nodeModulesSpecifiers ?. length ? nodeModulesSpecifiers :
180236 Debug . checkDefined ( relativeSpecifiers ) ;
181- cache ?. set ( importingSourceFile . path , moduleSourceFile . path , userPreferences , modulePaths , moduleSpecifiers ) ;
182- return moduleSpecifiers ;
183237 }
184238
185239 interface Info {
0 commit comments