8
8
createMultiMap ,
9
9
Debug ,
10
10
emptyArray ,
11
+ ensureTrailingDirectorySeparator ,
11
12
findIndex ,
12
13
firstDefined ,
13
14
forEachAncestorDirectory ,
@@ -43,6 +44,7 @@ import {
43
44
nodeModulesPathPart ,
44
45
PackageJsonImportFilter ,
45
46
Path ,
47
+ pathContainsNodeModules ,
46
48
Program ,
47
49
skipAlias ,
48
50
skipOuterExpressions ,
@@ -427,12 +429,12 @@ export function forEachExternalModuleToImportFrom(
427
429
return pattern ? getRegexFromPattern ( pattern , useCaseSensitiveFileNames ) : undefined ;
428
430
} ) ;
429
431
430
- forEachExternalModule ( program . getTypeChecker ( ) , program . getSourceFiles ( ) , excludePatterns , ( module , file ) => cb ( module , file , program , /*isFromPackageJson*/ false ) ) ;
432
+ forEachExternalModule ( program . getTypeChecker ( ) , program . getSourceFiles ( ) , excludePatterns , host , ( module , file ) => cb ( module , file , program , /*isFromPackageJson*/ false ) ) ;
431
433
const autoImportProvider = useAutoImportProvider && host . getPackageJsonAutoImportProvider ?.( ) ;
432
434
if ( autoImportProvider ) {
433
435
const start = timestamp ( ) ;
434
436
const checker = program . getTypeChecker ( ) ;
435
- forEachExternalModule ( autoImportProvider . getTypeChecker ( ) , autoImportProvider . getSourceFiles ( ) , excludePatterns , ( module , file ) => {
437
+ forEachExternalModule ( autoImportProvider . getTypeChecker ( ) , autoImportProvider . getSourceFiles ( ) , excludePatterns , host , ( module , file ) => {
436
438
if ( file && ! program . getSourceFile ( file . fileName ) || ! file && ! checker . resolveName ( module . name , /*location*/ undefined , SymbolFlags . Module , /*excludeGlobals*/ false ) ) {
437
439
// The AutoImportProvider filters files already in the main program out of its *root* files,
438
440
// but non-root files can still be present in both programs, and already in the export info map
@@ -445,15 +447,30 @@ export function forEachExternalModuleToImportFrom(
445
447
}
446
448
}
447
449
448
- function forEachExternalModule ( checker : TypeChecker , allSourceFiles : readonly SourceFile [ ] , excludePatterns : readonly RegExp [ ] | undefined , cb : ( module : Symbol , sourceFile : SourceFile | undefined ) => void ) {
449
- const isExcluded = excludePatterns && ( ( fileName : string ) => excludePatterns . some ( p => p . test ( fileName ) ) ) ;
450
+ function forEachExternalModule ( checker : TypeChecker , allSourceFiles : readonly SourceFile [ ] , excludePatterns : readonly RegExp [ ] | undefined , host : LanguageServiceHost , cb : ( module : Symbol , sourceFile : SourceFile | undefined ) => void ) {
451
+ const realpathsWithSymlinks = host . getSymlinkCache ?.( ) . getSymlinkedDirectoriesByRealpath ( ) ;
452
+ const isExcluded = excludePatterns && ( ( { fileName, path } : SourceFile ) => {
453
+ if ( excludePatterns . some ( p => p . test ( fileName ) ) ) return true ;
454
+ if ( realpathsWithSymlinks ?. size && pathContainsNodeModules ( fileName ) ) {
455
+ let dir = getDirectoryPath ( fileName ) ;
456
+ return forEachAncestorDirectory ( getDirectoryPath ( path ) , dirPath => {
457
+ const symlinks = realpathsWithSymlinks . get ( ensureTrailingDirectorySeparator ( dirPath ) ) ;
458
+ if ( symlinks ) {
459
+ return symlinks . some ( s => excludePatterns . some ( p => p . test ( fileName . replace ( dir , s ) ) ) ) ;
460
+ }
461
+ dir = getDirectoryPath ( dir ) ;
462
+ } ) ?? false ;
463
+ }
464
+ return false ;
465
+ } ) ;
466
+
450
467
for ( const ambient of checker . getAmbientModules ( ) ) {
451
- if ( ! ambient . name . includes ( "*" ) && ! ( excludePatterns && ambient . declarations ?. every ( d => isExcluded ! ( d . getSourceFile ( ) . fileName ) ) ) ) {
468
+ if ( ! ambient . name . includes ( "*" ) && ! ( excludePatterns && ambient . declarations ?. every ( d => isExcluded ! ( d . getSourceFile ( ) ) ) ) ) {
452
469
cb ( ambient , /*sourceFile*/ undefined ) ;
453
470
}
454
471
}
455
472
for ( const sourceFile of allSourceFiles ) {
456
- if ( isExternalOrCommonJsModule ( sourceFile ) && ! isExcluded ?.( sourceFile . fileName ) ) {
473
+ if ( isExternalOrCommonJsModule ( sourceFile ) && ! isExcluded ?.( sourceFile ) ) {
457
474
cb ( checker . getMergedSymbol ( sourceFile . symbol ) , sourceFile ) ;
458
475
}
459
476
}
0 commit comments