@@ -336,32 +336,42 @@ namespace ts {
336336 export function forEachExternalModuleToImportFrom (
337337 program : Program ,
338338 host : LanguageServiceHost ,
339+ preferences : UserPreferences ,
339340 useAutoImportProvider : boolean ,
340341 cb : ( module : Symbol , moduleFile : SourceFile | undefined , program : Program , isFromPackageJson : boolean ) => void ,
341342 ) {
342- forEachExternalModule ( program . getTypeChecker ( ) , program . getSourceFiles ( ) , ( module , file ) => cb ( module , file , program , /*isFromPackageJson*/ false ) ) ;
343+ const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames ( host ) ;
344+ const excludePatterns = preferences . autoImportFileExcludePatterns && mapDefined ( preferences . autoImportFileExcludePatterns , spec => {
345+ // The client is expected to send rooted path specs since we don't know
346+ // what directory a relative path is relative to.
347+ const pattern = getPatternFromSpec ( spec , "" , "exclude" ) ;
348+ return pattern ? getRegexFromPattern ( pattern , useCaseSensitiveFileNames ) : undefined ;
349+ } ) ;
350+
351+ forEachExternalModule ( program . getTypeChecker ( ) , program . getSourceFiles ( ) , excludePatterns , ( module , file ) => cb ( module , file , program , /*isFromPackageJson*/ false ) ) ;
343352 const autoImportProvider = useAutoImportProvider && host . getPackageJsonAutoImportProvider ?.( ) ;
344353 if ( autoImportProvider ) {
345354 const start = timestamp ( ) ;
346- forEachExternalModule ( autoImportProvider . getTypeChecker ( ) , autoImportProvider . getSourceFiles ( ) , ( module , file ) => cb ( module , file , autoImportProvider , /*isFromPackageJson*/ true ) ) ;
355+ forEachExternalModule ( autoImportProvider . getTypeChecker ( ) , autoImportProvider . getSourceFiles ( ) , excludePatterns , ( module , file ) => cb ( module , file , autoImportProvider , /*isFromPackageJson*/ true ) ) ;
347356 host . log ?.( `forEachExternalModuleToImportFrom autoImportProvider: ${ timestamp ( ) - start } ` ) ;
348357 }
349358 }
350359
351- function forEachExternalModule ( checker : TypeChecker , allSourceFiles : readonly SourceFile [ ] , cb : ( module : Symbol , sourceFile : SourceFile | undefined ) => void ) {
360+ function forEachExternalModule ( checker : TypeChecker , allSourceFiles : readonly SourceFile [ ] , excludePatterns : readonly RegExp [ ] | undefined , cb : ( module : Symbol , sourceFile : SourceFile | undefined ) => void ) {
361+ const isExcluded = ( fileName : string ) => excludePatterns ?. some ( p => p . test ( fileName ) ) ;
352362 for ( const ambient of checker . getAmbientModules ( ) ) {
353- if ( ! stringContains ( ambient . name , "*" ) ) {
363+ if ( ! stringContains ( ambient . name , "*" ) && ! ( excludePatterns && ambient . declarations ?. every ( d => isExcluded ( d . getSourceFile ( ) . fileName ) ) ) ) {
354364 cb ( ambient , /*sourceFile*/ undefined ) ;
355365 }
356366 }
357367 for ( const sourceFile of allSourceFiles ) {
358- if ( isExternalOrCommonJsModule ( sourceFile ) ) {
368+ if ( isExternalOrCommonJsModule ( sourceFile ) && ! isExcluded ( sourceFile . fileName ) ) {
359369 cb ( checker . getMergedSymbol ( sourceFile . symbol ) , sourceFile ) ;
360370 }
361371 }
362372 }
363373
364- export function getExportInfoMap ( importingFile : SourceFile , host : LanguageServiceHost , program : Program , cancellationToken : CancellationToken | undefined ) : ExportInfoMap {
374+ export function getExportInfoMap ( importingFile : SourceFile , host : LanguageServiceHost , program : Program , preferences : UserPreferences , cancellationToken : CancellationToken | undefined ) : ExportInfoMap {
365375 const start = timestamp ( ) ;
366376 // Pulling the AutoImportProvider project will trigger its updateGraph if pending,
367377 // which will invalidate the export map cache if things change, so pull it before
@@ -382,7 +392,7 @@ namespace ts {
382392 const compilerOptions = program . getCompilerOptions ( ) ;
383393 let moduleCount = 0 ;
384394 try {
385- forEachExternalModuleToImportFrom ( program , host , /*useAutoImportProvider*/ true , ( moduleSymbol , moduleFile , program , isFromPackageJson ) => {
395+ forEachExternalModuleToImportFrom ( program , host , preferences , /*useAutoImportProvider*/ true , ( moduleSymbol , moduleFile , program , isFromPackageJson ) => {
386396 if ( ++ moduleCount % 100 === 0 ) cancellationToken ?. throwIfCancellationRequested ( ) ;
387397 const seenExports = new Map < __String , true > ( ) ;
388398 const checker = program . getTypeChecker ( ) ;
0 commit comments