@@ -234,18 +234,21 @@ namespace ts.server {
234234 getFileName ( f : T ) : string ;
235235 getScriptKind ( f : T ) : ScriptKind ;
236236 hasMixedContent ( f : T , extraFileExtensions : JsFileExtensionInfo [ ] ) : boolean ;
237+ isDynamicFile ( f : T ) : boolean ;
237238 }
238239
239240 const fileNamePropertyReader : FilePropertyReader < string > = {
240241 getFileName : x => x ,
241242 getScriptKind : _ => undefined ,
242243 hasMixedContent : ( fileName , extraFileExtensions ) => some ( extraFileExtensions , ext => ext . isMixedContent && fileExtensionIs ( fileName , ext . extension ) ) ,
244+ isDynamicFile : x => x [ 0 ] == '^' ,
243245 } ;
244246
245247 const externalFilePropertyReader : FilePropertyReader < protocol . ExternalFile > = {
246248 getFileName : x => x . fileName ,
247249 getScriptKind : x => tryConvertScriptKindName ( x . scriptKind ) ,
248- hasMixedContent : x => x . hasMixedContent
250+ hasMixedContent : x => x . hasMixedContent ,
251+ isDynamicFile : x => x . fileName [ 0 ] == '^' ,
249252 } ;
250253
251254 function findProjectByName < T extends Project > ( projectName : string , projects : T [ ] ) : T {
@@ -1177,15 +1180,16 @@ namespace ts.server {
11771180 private addFilesToProjectAndUpdateGraph < T > ( project : ConfiguredProject | ExternalProject , files : T [ ] , propertyReader : FilePropertyReader < T > , clientFileName : string , typeAcquisition : TypeAcquisition , configFileErrors : ReadonlyArray < Diagnostic > ) : void {
11781181 let errors : Diagnostic [ ] ;
11791182 for ( const f of files ) {
1180- const rootFilename = propertyReader . getFileName ( f ) ;
1183+ const rootFileName = propertyReader . getFileName ( f ) ;
11811184 const scriptKind = propertyReader . getScriptKind ( f ) ;
11821185 const hasMixedContent = propertyReader . hasMixedContent ( f , this . hostConfiguration . extraFileExtensions ) ;
1183- if ( this . host . fileExists ( rootFilename ) ) {
1184- const info = this . getOrCreateScriptInfoForNormalizedPath ( toNormalizedPath ( rootFilename ) , /*openedByClient*/ clientFileName === rootFilename , /*fileContent*/ undefined , scriptKind , hasMixedContent ) ;
1186+ const isDynamicFile = propertyReader . isDynamicFile ( f ) ;
1187+ if ( isDynamicFile || this . host . fileExists ( rootFileName ) ) {
1188+ const info = this . getOrCreateScriptInfoForNormalizedPath ( toNormalizedPath ( rootFileName ) , /*openedByClient*/ clientFileName === rootFileName , /*fileContent*/ undefined , scriptKind , hasMixedContent , isDynamicFile ) ;
11851189 project . addRoot ( info ) ;
11861190 }
11871191 else {
1188- ( errors || ( errors = [ ] ) ) . push ( createFileNotFoundDiagnostic ( rootFilename ) ) ;
1192+ ( errors || ( errors = [ ] ) ) . push ( createFileNotFoundDiagnostic ( rootFileName ) ) ;
11891193 }
11901194 }
11911195 project . setProjectErrors ( concatenate ( configFileErrors , errors ) ) ;
@@ -1215,7 +1219,8 @@ namespace ts.server {
12151219 let rootFilesChanged = false ;
12161220 for ( const f of newUncheckedFiles ) {
12171221 const newRootFile = propertyReader . getFileName ( f ) ;
1218- if ( ! this . host . fileExists ( newRootFile ) ) {
1222+ const isDynamic = propertyReader . isDynamicFile ( f ) ;
1223+ if ( ! isDynamic && ! this . host . fileExists ( newRootFile ) ) {
12191224 ( projectErrors || ( projectErrors = [ ] ) ) . push ( createFileNotFoundDiagnostic ( newRootFile ) ) ;
12201225 continue ;
12211226 }
@@ -1226,7 +1231,7 @@ namespace ts.server {
12261231 if ( ! scriptInfo ) {
12271232 const scriptKind = propertyReader . getScriptKind ( f ) ;
12281233 const hasMixedContent = propertyReader . hasMixedContent ( f , this . hostConfiguration . extraFileExtensions ) ;
1229- scriptInfo = this . getOrCreateScriptInfoForNormalizedPath ( normalizedPath , /*openedByClient*/ false , /*fileContent*/ undefined , scriptKind , hasMixedContent ) ;
1234+ scriptInfo = this . getOrCreateScriptInfoForNormalizedPath ( normalizedPath , /*openedByClient*/ false , /*fileContent*/ undefined , scriptKind , hasMixedContent , isDynamic ) ;
12301235 }
12311236 }
12321237 newRootScriptInfos . push ( scriptInfo ) ;
@@ -1410,17 +1415,17 @@ namespace ts.server {
14101415
14111416 watchClosedScriptInfo ( info : ScriptInfo ) {
14121417 // do not watch files with mixed content - server doesn't know how to interpret it
1413- if ( ! info . hasMixedContent ) {
1418+ if ( ! info . hasMixedContent && ! info . isDynamic ) {
14141419 const { fileName } = info ;
14151420 info . setWatcher ( this . host . watchFile ( fileName , _ => this . onSourceFileChanged ( fileName ) ) ) ;
14161421 }
14171422 }
14181423
1419- getOrCreateScriptInfoForNormalizedPath ( fileName : NormalizedPath , openedByClient : boolean , fileContent ?: string , scriptKind ?: ScriptKind , hasMixedContent ?: boolean ) {
1424+ getOrCreateScriptInfoForNormalizedPath ( fileName : NormalizedPath , openedByClient : boolean , fileContent ?: string , scriptKind ?: ScriptKind , hasMixedContent ?: boolean , isDynamic ?: boolean ) {
14201425 let info = this . getScriptInfoForNormalizedPath ( fileName ) ;
14211426 if ( ! info ) {
1422- if ( openedByClient || this . host . fileExists ( fileName ) ) {
1423- info = new ScriptInfo ( this . host , fileName , scriptKind , hasMixedContent ) ;
1427+ if ( openedByClient || isDynamic || this . host . fileExists ( fileName ) ) {
1428+ info = new ScriptInfo ( this . host , fileName , scriptKind , hasMixedContent , isDynamic ) ;
14241429
14251430 this . filenameToScriptInfo . set ( info . path , info ) ;
14261431
@@ -1430,6 +1435,7 @@ namespace ts.server {
14301435 fileContent = this . host . readFile ( fileName ) || "" ;
14311436 }
14321437 }
1438+
14331439 else {
14341440 this . watchClosedScriptInfo ( info ) ;
14351441 }
0 commit comments