@@ -1408,17 +1408,22 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
14081408 this . hasAddedOrRemovedSymlinks = true ;
14091409 }
14101410
1411+ /** @internal */
1412+ useTypingsFromGlobalCache ( ) {
1413+ return this . languageServiceEnabled &&
1414+ this . projectService . serverMode === LanguageServiceMode . Semantic &&
1415+ this . projectService . typingsInstaller !== nullTypingsInstaller &&
1416+ this . getTypeAcquisition ( ) . enable ;
1417+ }
1418+
14111419 /**
14121420 * Updates set of files that contribute to this project
14131421 * @returns : true if set of files in the project stays the same and false - otherwise.
14141422 */
14151423 updateGraph ( ) : boolean {
14161424 tracing ?. push ( tracing . Phase . Session , "updateGraph" , { name : this . projectName , kind : ProjectKind [ this . projectKind ] } ) ;
14171425 perfLogger ?. logStartUpdateGraph ( ) ;
1418- const useTypingsFromGlobalCache = this . languageServiceEnabled &&
1419- this . projectService . serverMode === LanguageServiceMode . Semantic &&
1420- this . projectService . typingsInstaller !== nullTypingsInstaller &&
1421- this . getTypeAcquisition ( ) . enable ;
1426+ const useTypingsFromGlobalCache = this . useTypingsFromGlobalCache ( ) ;
14221427 if ( ! useTypingsFromGlobalCache ) this . resolutionCache . invalidateResolutionsWithGlobalCachePass ( ) ;
14231428 else this . resolutionCache . invalidateResolutionsWithoutGlobalCachePass ( ) ;
14241429 if ( useTypingsFromGlobalCache && this . cachedUnresolvedImportsPerFile . size ) this . recordChangesToUnresolvedImports = true ;
@@ -1430,14 +1435,19 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
14301435 this . recordChangesToUnresolvedImports = false ;
14311436
14321437 if ( useTypingsFromGlobalCache ) {
1433- this . lastCachedUnresolvedImportsList ??= this . getUnresolvedImports ( ) ;
1438+ this . lastCachedUnresolvedImportsList ??= getUnresolvedImports (
1439+ this . program ! ,
1440+ this . cachedUnresolvedImportsPerFile ,
1441+ s => this . writeLog ( s ) ,
1442+ ) ;
14341443 this . enqueueInstallTypingsForProject ( hasAddedorRemovedFiles ) ;
14351444 }
14361445 else {
14371446 this . lastCachedUnresolvedImportsList = undefined ;
14381447 this . cachedUnresolvedImportsPerFile . clear ( ) ;
14391448 this . typingsCacheEntry = undefined ;
14401449 }
1450+ this . projectService . verifyUnresovedImports ( this ) ;
14411451
14421452 const isFirstProgramLoad = this . projectProgramVersion === 0 && hasNewProgram ;
14431453 if ( hasNewProgram ) {
@@ -2344,43 +2354,52 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
23442354 noLib : true ,
23452355 } ;
23462356 }
2357+ }
23472358
2348- /** @internal */
2349- private getUnresolvedImports ( ) : SortedReadonlyArray < string > {
2350- const sourceFiles = this . program ! . getSourceFiles ( ) ;
2351- this . writeLog ( `Calculating unresolved imports list of program:: Files:: ${ sourceFiles . length } ` ) ;
2352- tracing ?. push ( tracing . Phase . Session , "getUnresolvedImports" , { count : sourceFiles . length } ) ;
2353- const ambientModules = this . program ! . getTypeChecker ( ) . getAmbientModules ( ) . map ( mod => stripQuotes ( mod . getName ( ) ) ) ;
2354- const result = sortAndDeduplicate ( flatMap ( sourceFiles , sourceFile =>
2355- this . extractUnresolvedImportsFromSourceFile (
2356- sourceFile ,
2357- ambientModules ,
2358- ) ) ) ;
2359- tracing ?. pop ( ) ;
2360- this . writeLog ( `Calculating unresolved imports list of program:: Files:: ${ sourceFiles . length } Done: ${ JSON . stringify ( result ) } ` ) ;
2361- return result ;
2362- }
2359+ /** @internal */
2360+ export function getUnresolvedImports (
2361+ program : Program ,
2362+ cachedUnresolvedImportsPerFile : Map < Path , readonly string [ ] > ,
2363+ writeLog : ( s : string ) => void ,
2364+ ) : SortedReadonlyArray < string > {
2365+ const sourceFiles = program . getSourceFiles ( ) ;
2366+ writeLog ( `Calculating unresolved imports list of program:: Files:: ${ sourceFiles . length } ` ) ;
2367+ tracing ?. push ( tracing . Phase . Session , "getUnresolvedImports" , { count : sourceFiles . length } ) ;
2368+ const ambientModules = program . getTypeChecker ( ) . getAmbientModules ( ) . map ( mod => stripQuotes ( mod . getName ( ) ) ) ;
2369+ const result = sortAndDeduplicate ( flatMap ( sourceFiles , sourceFile =>
2370+ extractUnresolvedImportsFromSourceFile (
2371+ program ,
2372+ sourceFile ,
2373+ ambientModules ,
2374+ cachedUnresolvedImportsPerFile ,
2375+ writeLog ,
2376+ ) ) ) ;
2377+ tracing ?. pop ( ) ;
2378+ writeLog ( `Calculating unresolved imports list of program:: Files:: ${ sourceFiles . length } Done: ${ JSON . stringify ( result ) } ` ) ;
2379+ return result ;
2380+ }
23632381
2364- /** @internal */
2365- private extractUnresolvedImportsFromSourceFile (
2366- file : SourceFile ,
2367- ambientModules : readonly string [ ] ,
2368- ) : readonly string [ ] {
2369- return getOrUpdate ( this . cachedUnresolvedImportsPerFile , file . path , ( ) => {
2370- let unresolvedImports : string [ ] | undefined ;
2371- this . program ! . forEachResolvedModule ( ( resolution , name ) => {
2372- // pick unresolved non-relative names
2373- if (
2374- needsResolutionFromGlobalCache ( name , resolution ) &&
2375- ! ambientModules . some ( m => m === name )
2376- ) {
2377- unresolvedImports = append ( unresolvedImports , parsePackageName ( name ) . packageName ) ;
2378- }
2379- } , file ) ;
2380- this . writeLog ( `New unresolvedImports for ${ file . path } :: ${ JSON . stringify ( unresolvedImports || emptyArray ) } ` ) ;
2381- return unresolvedImports || emptyArray ;
2382- } ) ;
2383- }
2382+ function extractUnresolvedImportsFromSourceFile (
2383+ program : Program ,
2384+ file : SourceFile ,
2385+ ambientModules : readonly string [ ] ,
2386+ cachedUnresolvedImportsPerFile : Map < Path , readonly string [ ] > ,
2387+ writeLog : ( s : string ) => void ,
2388+ ) : readonly string [ ] {
2389+ return getOrUpdate ( cachedUnresolvedImportsPerFile , file . path , ( ) => {
2390+ let unresolvedImports : string [ ] | undefined ;
2391+ program . forEachResolvedModule ( ( resolution , name ) => {
2392+ // pick unresolved non-relative names
2393+ if (
2394+ needsResolutionFromGlobalCache ( name , resolution ) &&
2395+ ! ambientModules . some ( m => m === name )
2396+ ) {
2397+ unresolvedImports = append ( unresolvedImports , parsePackageName ( name ) . packageName ) ;
2398+ }
2399+ } , file ) ;
2400+ writeLog ( `New unresolvedImports for ${ file . path } :: ${ JSON . stringify ( unresolvedImports || emptyArray ) } ` ) ;
2401+ return unresolvedImports || emptyArray ;
2402+ } ) ;
23842403}
23852404
23862405/**
0 commit comments