44/// <reference path="lshost.ts"/>
55
66namespace ts . server {
7+
78 export enum ProjectKind {
89 Inferred ,
910 Configured ,
1011 External
1112 }
1213
14+ function remove < T > ( items : T [ ] , item : T ) {
15+ const index = items . indexOf ( item ) ;
16+ if ( index >= 0 ) {
17+ items . splice ( index , 1 ) ;
18+ }
19+ }
20+
1321 export abstract class Project {
14- private rootFiles : ScriptInfo [ ] = [ ] ;
22+ private readonly rootFiles : ScriptInfo [ ] = [ ] ;
1523 private readonly rootFilesMap : FileMap < ScriptInfo > = createFileMap < ScriptInfo > ( ) ;
1624 private lsHost : ServerLanguageServiceHost ;
1725 private program : ts . Program ;
@@ -130,10 +138,8 @@ namespace ts.server {
130138
131139 containsFile ( filename : NormalizedPath , requireOpen ?: boolean ) {
132140 const info = this . projectService . getScriptInfoForNormalizedPath ( filename ) ;
133- if ( info ) {
134- if ( ( ! requireOpen ) || info . isOpen ) {
135- return this . containsScriptInfo ( info ) ;
136- }
141+ if ( info && ( info . isOpen || ! requireOpen ) ) {
142+ return this . containsScriptInfo ( info ) ;
137143 }
138144 }
139145
@@ -153,12 +159,13 @@ namespace ts.server {
153159 }
154160
155161 removeFile ( info : ScriptInfo , detachFromProject : boolean = true ) {
156- if ( ! this . removeRoot ( info ) ) {
157- this . removeReferencedFile ( info )
158- }
162+ this . removeRootFileIfNecessary ( info ) ;
163+ this . lsHost . notifyFileRemoved ( info ) ;
164+
159165 if ( detachFromProject ) {
160166 info . detachFromProject ( this ) ;
161167 }
168+
162169 this . markAsDirty ( ) ;
163170 }
164171
@@ -179,14 +186,31 @@ namespace ts.server {
179186 // - newProgram is different from the old program and structure of the old program was not reused.
180187 if ( ! oldProgram || ( this . program !== oldProgram && ! oldProgram . structureIsReused ) ) {
181188 this . projectStructureVersion ++ ;
189+ if ( oldProgram ) {
190+ for ( const f of oldProgram . getSourceFiles ( ) ) {
191+ if ( ! this . program . getSourceFileByPath ( f . path ) ) {
192+ // new program does not contain this file - detach it from the project
193+ const scriptInfoToDetach = this . projectService . getScriptInfo ( f . fileName ) ;
194+ if ( scriptInfoToDetach ) {
195+ scriptInfoToDetach . detachFromProject ( this ) ;
196+ }
197+ }
198+ }
199+ }
182200 }
183201 }
184202
203+ getScriptInfoLSHost ( fileName : string ) {
204+ const scriptInfo = this . projectService . getOrCreateScriptInfo ( fileName , /*openedByClient*/ false ) ;
205+ if ( scriptInfo ) {
206+ scriptInfo . attachToProject ( this ) ;
207+ }
208+ return scriptInfo ;
209+ }
210+
185211 getScriptInfoForNormalizedPath ( fileName : NormalizedPath ) {
186212 const scriptInfo = this . projectService . getOrCreateScriptInfoForNormalizedPath ( fileName , /*openedByClient*/ false ) ;
187- if ( scriptInfo && scriptInfo . attachToProject ( this ) ) {
188- this . markAsDirty ( ) ;
189- }
213+ Debug . assert ( ! scriptInfo || scriptInfo . isAttached ( this ) ) ;
190214 return scriptInfo ;
191215 }
192216
@@ -215,19 +239,23 @@ namespace ts.server {
215239 }
216240 }
217241
218- saveTo ( filename : string , tmpfilename : string ) {
219- const script = this . getScriptInfo ( filename ) ;
242+ saveTo ( filename : NormalizedPath , tmpfilename : NormalizedPath ) {
243+ const script = this . projectService . getScriptInfoForNormalizedPath ( filename ) ;
220244 if ( script ) {
245+ Debug . assert ( script . isAttached ( this ) ) ;
221246 const snap = script . snap ( ) ;
222247 this . projectService . host . writeFile ( tmpfilename , snap . getText ( 0 , snap . getLength ( ) ) ) ;
223248 }
224249 }
225250
226- reloadScript ( filename : NormalizedPath , cb : ( ) => void ) {
227- const script = this . getScriptInfoForNormalizedPath ( filename ) ;
251+ reloadScript ( filename : NormalizedPath ) : boolean {
252+ const script = this . projectService . getScriptInfoForNormalizedPath ( filename ) ;
228253 if ( script ) {
229- script . reloadFromFile ( filename , cb ) ;
254+ Debug . assert ( script . isAttached ( this ) ) ;
255+ script . reloadFromFile ( ) ;
256+ return true ;
230257 }
258+ return false ;
231259 }
232260
233261 getChangesSinceVersion ( lastKnownVersion ?: number ) : protocol . ProjectFiles {
@@ -274,18 +302,11 @@ namespace ts.server {
274302 }
275303
276304 // remove a root file from project
277- private removeRoot ( info : ScriptInfo ) : boolean {
305+ private removeRootFileIfNecessary ( info : ScriptInfo ) : void {
278306 if ( this . isRoot ( info ) ) {
279- this . rootFiles = copyListRemovingItem ( info , this . rootFiles ) ;
307+ remove ( this . rootFiles , info ) ;
280308 this . rootFilesMap . remove ( info . path ) ;
281- this . lsHost . removeRoot ( info ) ;
282- return true ;
283309 }
284- return false ;
285- }
286-
287- private removeReferencedFile ( info : ScriptInfo ) {
288- this . lsHost . removeReferencedFile ( info )
289310 }
290311 }
291312
0 commit comments