@@ -145,6 +145,8 @@ namespace ts.server {
145145
146146 private readonly hostConfiguration : HostConfiguration ;
147147
148+ private changedFiles : ScriptInfo [ ] ;
149+
148150 constructor ( public readonly host : ServerHost ,
149151 public readonly logger : Logger ,
150152 public readonly cancellationToken : HostCancellationToken ,
@@ -163,6 +165,14 @@ namespace ts.server {
163165 this . documentRegistry = createDocumentRegistry ( host . useCaseSensitiveFileNames , host . getCurrentDirectory ( ) ) ;
164166 }
165167
168+ getChangedFiles_TestOnly ( ) {
169+ return this . changedFiles ;
170+ }
171+
172+ ensureInferredProjectsUpToDate_TestOnly ( ) {
173+ this . ensureInferredProjectsUpToDate ( ) ;
174+ }
175+
166176 stopWatchingDirectory ( directory : string ) {
167177 this . directoryWatchers . stopWatchingDirectory ( directory ) ;
168178 }
@@ -187,7 +197,21 @@ namespace ts.server {
187197 }
188198
189199 private ensureInferredProjectsUpToDate ( ) {
190-
200+ if ( this . changedFiles ) {
201+ let projectsToUpdate : Project [ ] ;
202+ if ( this . changedFiles . length === 1 ) {
203+ // simpliest case - no allocations
204+ projectsToUpdate = this . changedFiles [ 0 ] . containingProjects ;
205+ }
206+ else {
207+ projectsToUpdate = [ ] ;
208+ for ( const f of this . changedFiles ) {
209+ projectsToUpdate = projectsToUpdate . concat ( f . containingProjects ) ;
210+ }
211+ }
212+ this . updateProjectGraphs ( projectsToUpdate ) ;
213+ this . changedFiles = undefined ;
214+ }
191215 }
192216
193217 private findContainingConfiguredProject ( info : ScriptInfo ) : ConfiguredProject {
@@ -532,7 +556,7 @@ namespace ts.server {
532556 }
533557
534558 private printProjects ( ) {
535- if ( ! this . logger . isVerbose ( ) ) {
559+ if ( ! this . logger . hasLevel ( LogLevel . verbose ) ) {
536560 return ;
537561 }
538562
@@ -970,11 +994,13 @@ namespace ts.server {
970994 }
971995
972996 applyChangesInOpenFiles ( openFiles : protocol . NewOpenFile [ ] , changedFiles : protocol . ChangedOpenFile [ ] , closedFiles : string [ ] ) : void {
997+ const recordChangedFiles = changedFiles && ! openFiles && ! closedFiles ;
973998 if ( openFiles ) {
974999 for ( const file of openFiles ) {
9751000 const scriptInfo = this . getScriptInfo ( file . fileName ) ;
9761001 Debug . assert ( ! scriptInfo || ! scriptInfo . isOpen ) ;
977- this . openClientFileWithNormalizedPath ( toNormalizedPath ( file . fileName ) , file . content ) ;
1002+ const normalizedPath = scriptInfo ? scriptInfo . fileName : toNormalizedPath ( file . fileName ) ;
1003+ this . openClientFileWithNormalizedPath ( normalizedPath , file . content ) ;
9781004 }
9791005 }
9801006
@@ -987,6 +1013,14 @@ namespace ts.server {
9871013 const change = file . changes [ i ] ;
9881014 scriptInfo . editContent ( change . span . start , change . span . start + change . span . length , change . newText ) ;
9891015 }
1016+ if ( recordChangedFiles ) {
1017+ if ( ! this . changedFiles ) {
1018+ this . changedFiles = [ scriptInfo ] ;
1019+ }
1020+ else if ( this . changedFiles . indexOf ( scriptInfo ) < 0 ) {
1021+ this . changedFiles . push ( scriptInfo ) ;
1022+ }
1023+ }
9901024 }
9911025 }
9921026
@@ -996,7 +1030,9 @@ namespace ts.server {
9961030 }
9971031 }
9981032
999- if ( openFiles || changedFiles || closedFiles ) {
1033+ // if files were open or closed then explicitly refresh list of inferred projects
1034+ // otherwise if there were only changes in files - record changed files in `changedFiles` and defer the update
1035+ if ( openFiles || closedFiles ) {
10001036 this . refreshInferredProjects ( ) ;
10011037 }
10021038 }
0 commit comments