@@ -308,7 +308,7 @@ namespace ts.server {
308
308
}
309
309
310
310
interface AssignProjectResult extends OpenConfiguredProjectResult {
311
- defaultConfigProject : ConfiguredProject | undefined ;
311
+ retainProjects : readonly ConfiguredProject [ ] | ConfiguredProject | undefined ;
312
312
}
313
313
314
314
interface FilePropertyReader < T > {
@@ -2860,6 +2860,7 @@ namespace ts.server {
2860
2860
let configFileErrors : readonly Diagnostic [ ] | undefined ;
2861
2861
let project : ConfiguredProject | ExternalProject | undefined = this . findExternalProjectContainingOpenScriptInfo ( info ) ;
2862
2862
let defaultConfigProject : ConfiguredProject | undefined ;
2863
+ let retainProjects : ConfiguredProject [ ] | ConfiguredProject | undefined ;
2863
2864
if ( ! project && ! this . syntaxOnly ) { // Checking syntaxOnly is an optimization
2864
2865
configFileName = this . getConfigFileNameForFile ( info ) ;
2865
2866
if ( configFileName ) {
@@ -2880,7 +2881,42 @@ namespace ts.server {
2880
2881
// Ensure project is ready to check if it contains opened script info
2881
2882
updateProjectIfDirty ( project ) ;
2882
2883
}
2884
+
2883
2885
defaultConfigProject = project ;
2886
+ retainProjects = defaultConfigProject ;
2887
+
2888
+ // If this configured project doesnt contain script info but
2889
+ // it is solution with project references, try those project references
2890
+ if ( ! project . containsScriptInfo ( info ) &&
2891
+ project . getRootFilesMap ( ) . size === 0 &&
2892
+ ! project . canConfigFileJsonReportNoInputFiles ) {
2893
+
2894
+ // try to load project from the tree
2895
+ forEachResolvedProjectReference (
2896
+ project ,
2897
+ ref => {
2898
+ if ( ! ref ) return ;
2899
+
2900
+ // Try to load the project of resolvedRef
2901
+ const configFileName = toNormalizedPath ( ref . sourceFile . fileName ) ;
2902
+ const child = this . findConfiguredProjectByProjectName ( configFileName ) ||
2903
+ this . createAndLoadConfiguredProject ( configFileName , `Creating project referenced in solution ${ defaultConfigProject ! . projectName } to find possible configured project for ${ info . fileName } to open` ) ;
2904
+ // Retain these projects
2905
+ if ( ! isArray ( retainProjects ) ) {
2906
+ retainProjects = [ defaultConfigProject ! , child ] ;
2907
+ }
2908
+ else {
2909
+ retainProjects . push ( child ) ;
2910
+ }
2911
+
2912
+ if ( child . containsScriptInfo ( info ) ) {
2913
+ defaultConfigProject = child ;
2914
+ return true ;
2915
+ }
2916
+ }
2917
+ ) ;
2918
+ }
2919
+
2884
2920
// Create ancestor configured project
2885
2921
this . createAncestorProjects ( info , defaultConfigProject ) ;
2886
2922
}
@@ -2902,7 +2938,7 @@ namespace ts.server {
2902
2938
this . assignOrphanScriptInfoToInferredProject ( info , this . openFiles . get ( info . path ) ) ;
2903
2939
}
2904
2940
Debug . assert ( ! info . isOrphan ( ) ) ;
2905
- return { configFileName, configFileErrors, defaultConfigProject } ;
2941
+ return { configFileName, configFileErrors, retainProjects } ;
2906
2942
}
2907
2943
2908
2944
private createAncestorProjects ( info : ScriptInfo , project : ConfiguredProject ) {
@@ -2978,7 +3014,7 @@ namespace ts.server {
2978
3014
) ;
2979
3015
}
2980
3016
2981
- private cleanupAfterOpeningFile ( toRetainConfigProjects : ConfiguredProject [ ] | ConfiguredProject | undefined ) {
3017
+ private cleanupAfterOpeningFile ( toRetainConfigProjects : readonly ConfiguredProject [ ] | ConfiguredProject | undefined ) {
2982
3018
// This was postponed from closeOpenFile to after opening next file,
2983
3019
// so that we can reuse the project if we need to right away
2984
3020
this . removeOrphanConfiguredProjects ( toRetainConfigProjects ) ;
@@ -3000,14 +3036,14 @@ namespace ts.server {
3000
3036
3001
3037
openClientFileWithNormalizedPath ( fileName : NormalizedPath , fileContent ?: string , scriptKind ?: ScriptKind , hasMixedContent ?: boolean , projectRootPath ?: NormalizedPath ) : OpenConfiguredProjectResult {
3002
3038
const info = this . getOrCreateOpenScriptInfo ( fileName , fileContent , scriptKind , hasMixedContent , projectRootPath ) ;
3003
- const { defaultConfigProject , ...result } = this . assignProjectToOpenedScriptInfo ( info ) ;
3004
- this . cleanupAfterOpeningFile ( defaultConfigProject ) ;
3039
+ const { retainProjects , ...result } = this . assignProjectToOpenedScriptInfo ( info ) ;
3040
+ this . cleanupAfterOpeningFile ( retainProjects ) ;
3005
3041
this . telemetryOnOpenFile ( info ) ;
3006
3042
this . printProjects ( ) ;
3007
3043
return result ;
3008
3044
}
3009
3045
3010
- private removeOrphanConfiguredProjects ( toRetainConfiguredProjects : ConfiguredProject [ ] | ConfiguredProject | undefined ) {
3046
+ private removeOrphanConfiguredProjects ( toRetainConfiguredProjects : readonly ConfiguredProject [ ] | ConfiguredProject | undefined ) {
3011
3047
const toRemoveConfiguredProjects = cloneMap ( this . configuredProjects ) ;
3012
3048
const markOriginalProjectsAsUsed = ( project : Project ) => {
3013
3049
if ( ! project . isOrphan ( ) && project . originalConfiguredProjects ) {
@@ -3206,9 +3242,9 @@ namespace ts.server {
3206
3242
}
3207
3243
3208
3244
// All the script infos now exist, so ok to go update projects for open files
3209
- let defaultConfigProjects : ConfiguredProject [ ] | undefined ;
3245
+ let retainProjects : readonly ConfiguredProject [ ] | undefined ;
3210
3246
if ( openScriptInfos ) {
3211
- defaultConfigProjects = mapDefined ( openScriptInfos , info => this . assignProjectToOpenedScriptInfo ( info ) . defaultConfigProject ) ;
3247
+ retainProjects = flatMap ( openScriptInfos , info => this . assignProjectToOpenedScriptInfo ( info ) . retainProjects ) ;
3212
3248
}
3213
3249
3214
3250
// While closing files there could be open files that needed assigning new inferred projects, do it now
@@ -3218,7 +3254,7 @@ namespace ts.server {
3218
3254
3219
3255
if ( openScriptInfos ) {
3220
3256
// Cleanup projects
3221
- this . cleanupAfterOpeningFile ( defaultConfigProjects ) ;
3257
+ this . cleanupAfterOpeningFile ( retainProjects ) ;
3222
3258
// Telemetry
3223
3259
openScriptInfos . forEach ( info => this . telemetryOnOpenFile ( info ) ) ;
3224
3260
this . printProjects ( ) ;
0 commit comments