@@ -137,26 +137,25 @@ namespace ts.server {
137137
138138 private readonly directoryWatchers : DirectoryWatchers ;
139139
140- private hostConfiguration : HostConfiguration ;
140+ private readonly hostConfiguration : HostConfiguration ;
141141
142142 private timerForDetectingProjectFileListChanges : Map < any > = { } ;
143143
144144 constructor ( public readonly host : ServerHost ,
145145 public readonly logger : Logger ,
146146 public readonly cancellationToken : HostCancellationToken ,
147+ private readonly useOneInferredProject : boolean ,
147148 private readonly eventHandler ?: ProjectServiceEventHandler ) {
148149
149150 this . directoryWatchers = new DirectoryWatchers ( this ) ;
150151 // ts.disableIncrementalParsing = true;
151- this . setDefaultHostConfiguration ( ) ;
152- this . documentRegistry = createDocumentRegistry ( host . useCaseSensitiveFileNames , host . getCurrentDirectory ( ) ) ;
153- }
154152
155- private setDefaultHostConfiguration ( ) {
156153 this . hostConfiguration = {
157154 formatCodeOptions : getDefaultFormatCodeSettings ( this . host ) ,
158155 hostInfo : "Unknown host"
159156 } ;
157+
158+ this . documentRegistry = createDocumentRegistry ( host . useCaseSensitiveFileNames , host . getCurrentDirectory ( ) ) ;
160159 }
161160
162161 stopWatchingDirectory ( directory : string ) {
@@ -378,31 +377,36 @@ namespace ts.server {
378377 }
379378 if ( info . containingProjects . length === 0 ) {
380379 // create new inferred project p with the newly opened file as root
381- const inferredProject = this . createAndAddInferredProject ( info ) ;
382- const openFileRoots : ScriptInfo [ ] = [ ] ;
383- // for each inferred project root r
384- for ( const rootFile of this . openFileRoots ) {
385- // if r referenced by the new project
386- if ( inferredProject . containsScriptInfo ( rootFile ) ) {
387- // remove inferred project that was initially created for rootFile
388- const defaultProject = rootFile . getDefaultProject ( ) ;
389- if ( defaultProject === inferredProject ) {
390- continue ;
391- }
392- Debug . assert ( defaultProject . projectKind === ProjectKind . Inferred ) ;
380+ // or add root to existing inferred project if 'useOneInferredProject' is true
381+ const inferredProject = this . addFileToInferredProject ( info ) ;
382+ if ( ! this . useOneInferredProject ) {
383+
384+ // if useOneInferredProject is not set then try to fixup ownership of open files
385+ const openFileRoots : ScriptInfo [ ] = [ ] ;
386+ // for each inferred project root r
387+ for ( const rootFile of this . openFileRoots ) {
388+ // if r referenced by the new project
389+ if ( inferredProject . containsScriptInfo ( rootFile ) ) {
390+ // remove inferred project that was initially created for rootFile
391+ const defaultProject = rootFile . getDefaultProject ( ) ;
392+ if ( defaultProject === inferredProject ) {
393+ continue ;
394+ }
395+ Debug . assert ( defaultProject . projectKind === ProjectKind . Inferred ) ;
393396
394- this . removeProject ( defaultProject ) ;
395- // put r in referenced open file list
396- this . openFilesReferenced . push ( rootFile ) ;
397- // set default project of r to the new project
398- rootFile . attachToProject ( inferredProject ) ;
399- }
400- else {
401- // otherwise, keep r as root of inferred project
402- openFileRoots . push ( rootFile ) ;
397+ this . removeProject ( defaultProject ) ;
398+ // put r in referenced open file list
399+ this . openFilesReferenced . push ( rootFile ) ;
400+ // set default project of r to the new project
401+ rootFile . attachToProject ( inferredProject ) ;
402+ }
403+ else {
404+ // otherwise, keep r as root of inferred project
405+ openFileRoots . push ( rootFile ) ;
406+ }
403407 }
408+ this . openFileRoots = openFileRoots ;
404409 }
405- this . openFileRoots = openFileRoots ;
406410 }
407411
408412 this . openFileRoots . push ( info ) ;
@@ -736,14 +740,19 @@ namespace ts.server {
736740
737741 // delete inferred project
738742 let toRemove : Project [ ] ;
743+
744+ // TODO: unify logic
739745 for ( const p of info . containingProjects ) {
740746 if ( p . projectKind === ProjectKind . Inferred && p . isRoot ( info ) ) {
741747 ( toRemove || ( toRemove = [ ] ) ) . push ( p ) ;
742748 }
743749 }
744750 if ( toRemove ) {
745751 for ( const p of toRemove ) {
746- this . removeProject ( p ) ;
752+ p . removeFile ( info ) ;
753+ if ( ! p . hasRoots ( ) ) {
754+ this . removeProject ( p ) ;
755+ }
747756 }
748757 }
749758 }
@@ -792,8 +801,12 @@ namespace ts.server {
792801 }
793802 }
794803
795- createAndAddInferredProject ( root : ScriptInfo ) {
796- const project = new InferredProject ( this , this . documentRegistry , /*languageServiceEnabled*/ true ) ;
804+ addFileToInferredProject ( root : ScriptInfo ) {
805+ const useExistingProject = this . useOneInferredProject && this . inferredProjects . length ;
806+ const project = useExistingProject
807+ ? this . inferredProjects [ 0 ]
808+ : new InferredProject ( this , this . documentRegistry , /*languageServiceEnabled*/ true ) ;
809+
797810 project . addRoot ( root ) ;
798811
799812 this . directoryWatchers . startWatchingContainingDirectoriesForFile (
@@ -802,7 +815,10 @@ namespace ts.server {
802815 fileName => this . onConfigFileAddedForInferredProject ( fileName ) ) ;
803816
804817 project . updateGraph ( ) ;
805- this . inferredProjects . push ( project ) ;
818+
819+ if ( ! useExistingProject ) {
820+ this . inferredProjects . push ( project ) ;
821+ }
806822 return project ;
807823 }
808824
@@ -966,7 +982,10 @@ namespace ts.server {
966982 if ( inConfiguredProject || inExternalProject ) {
967983 const inferredProjects = rootFile . containingProjects . filter ( p => p . projectKind === ProjectKind . Inferred ) ;
968984 for ( const p of inferredProjects ) {
969- this . removeProject ( p ) ;
985+ p . removeFile ( rootFile , /*detachFromProject*/ true ) ;
986+ if ( ! p . hasRoots ( ) ) {
987+ this . removeProject ( p ) ;
988+ }
970989 }
971990 if ( inConfiguredProject ) {
972991 this . openFileRootsConfigured . push ( rootFile ) ;
@@ -1033,6 +1052,9 @@ namespace ts.server {
10331052 for ( const f of unattachedOpenFiles ) {
10341053 this . addOpenFile ( f ) ;
10351054 }
1055+ for ( const p of this . inferredProjects ) {
1056+ p . updateGraph ( ) ;
1057+ }
10361058 this . printProjects ( ) ;
10371059 }
10381060
0 commit comments