@@ -789,41 +789,6 @@ namespace ts.server {
789
789
}
790
790
}
791
791
792
- /* @internal */
793
- private extractUnresolvedImportsFromSourceFile ( file : SourceFile , ambientModules : string [ ] ) : ReadonlyArray < string > {
794
- const cached = this . cachedUnresolvedImportsPerFile . get ( file . path ) ;
795
- if ( cached ) {
796
- // found cached result, return
797
- return cached ;
798
- }
799
- let unresolvedImports : string [ ] | undefined ;
800
- if ( file . resolvedModules ) {
801
- file . resolvedModules . forEach ( ( resolvedModule , name ) => {
802
- // pick unresolved non-relative names
803
- if ( ! resolvedModule && ! isExternalModuleNameRelative ( name ) && ! isAmbientlyDeclaredModule ( name ) ) {
804
- // for non-scoped names extract part up-to the first slash
805
- // for scoped names - extract up to the second slash
806
- let trimmed = name . trim ( ) ;
807
- let i = trimmed . indexOf ( "/" ) ;
808
- if ( i !== - 1 && trimmed . charCodeAt ( 0 ) === CharacterCodes . at ) {
809
- i = trimmed . indexOf ( "/" , i + 1 ) ;
810
- }
811
- if ( i !== - 1 ) {
812
- trimmed = trimmed . substr ( 0 , i ) ;
813
- }
814
- ( unresolvedImports || ( unresolvedImports = [ ] ) ) . push ( trimmed ) ;
815
- }
816
- } ) ;
817
- }
818
-
819
- this . cachedUnresolvedImportsPerFile . set ( file . path , unresolvedImports || emptyArray ) ;
820
- return unresolvedImports || emptyArray ;
821
-
822
- function isAmbientlyDeclaredModule ( name : string ) {
823
- return ambientModules . some ( m => m === name ) ;
824
- }
825
- }
826
-
827
792
/* @internal */
828
793
onFileAddedOrRemoved ( ) {
829
794
this . hasAddedorRemovedFiles = true ;
@@ -857,15 +822,7 @@ namespace ts.server {
857
822
// (can reuse cached imports for files that were not changed)
858
823
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
859
824
if ( hasNewProgram || changedFiles . length ) {
860
- let result : string [ ] | undefined ;
861
- const ambientModules = this . program . getTypeChecker ( ) . getAmbientModules ( ) . map ( mod => stripQuotes ( mod . getName ( ) ) ) ;
862
- for ( const sourceFile of this . program . getSourceFiles ( ) ) {
863
- const unResolved = this . extractUnresolvedImportsFromSourceFile ( sourceFile , ambientModules ) ;
864
- if ( unResolved !== emptyArray ) {
865
- ( result || ( result = [ ] ) ) . push ( ...unResolved ) ;
866
- }
867
- }
868
- this . lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray ( result ) : emptyArray ;
825
+ this . lastCachedUnresolvedImportsList = getUnresolvedImports ( this . program , this . cachedUnresolvedImportsPerFile ) ;
869
826
}
870
827
871
828
this . projectService . typingsCache . enqueueInstallTypingsForProject ( this , this . lastCachedUnresolvedImportsList , hasAddedorRemovedFiles ) ;
@@ -1194,6 +1151,27 @@ namespace ts.server {
1194
1151
}
1195
1152
}
1196
1153
1154
+ function getUnresolvedImports ( program : Program , cachedUnresolvedImportsPerFile : Map < ReadonlyArray < string > > ) : SortedReadonlyArray < string > {
1155
+ const ambientModules = program . getTypeChecker ( ) . getAmbientModules ( ) . map ( mod => stripQuotes ( mod . getName ( ) ) ) ;
1156
+ return toDeduplicatedSortedArray ( flatMap ( program . getSourceFiles ( ) , sourceFile =>
1157
+ extractUnresolvedImportsFromSourceFile ( sourceFile , ambientModules , cachedUnresolvedImportsPerFile ) ) ) ;
1158
+ }
1159
+ function extractUnresolvedImportsFromSourceFile ( file : SourceFile , ambientModules : ReadonlyArray < string > , cachedUnresolvedImportsPerFile : Map < ReadonlyArray < string > > ) : ReadonlyArray < string > {
1160
+ return getOrUpdate ( cachedUnresolvedImportsPerFile , file . path , ( ) => {
1161
+ if ( ! file . resolvedModules ) return emptyArray ;
1162
+ let unresolvedImports : string [ ] | undefined ;
1163
+ file . resolvedModules . forEach ( ( resolvedModule , name ) => {
1164
+ // pick unresolved non-relative names
1165
+ if ( ( ! resolvedModule || ! resolutionExtensionIsTSOrJson ( resolvedModule . extension ) ) &&
1166
+ ! isExternalModuleNameRelative ( name ) &&
1167
+ ! ambientModules . some ( m => m === name ) ) {
1168
+ unresolvedImports = append ( unresolvedImports , parsePackageName ( name ) . packageName ) ;
1169
+ }
1170
+ } ) ;
1171
+ return unresolvedImports || emptyArray ;
1172
+ } ) ;
1173
+ }
1174
+
1197
1175
/**
1198
1176
* If a file is opened and no tsconfig (or jsconfig) is found,
1199
1177
* the file and its imports/references are put into an InferredProject.
0 commit comments