@@ -108,6 +108,7 @@ namespace ts.server {
108108 export interface HostConfiguration {
109109 formatCodeOptions : FormatCodeSettings ;
110110 hostInfo : string ;
111+ extraFileExtensions ?: FileExtensionInfo [ ] ;
111112 }
112113
113114 interface ConfigFileConversionResult {
@@ -132,13 +133,16 @@ namespace ts.server {
132133 interface FilePropertyReader < T > {
133134 getFileName ( f : T ) : string ;
134135 getScriptKind ( f : T ) : ScriptKind ;
135- hasMixedContent ( f : T ) : boolean ;
136+ hasMixedContent ( f : T , extraFileExtensions : FileExtensionInfo [ ] ) : boolean ;
136137 }
137138
138139 const fileNamePropertyReader : FilePropertyReader < string > = {
139140 getFileName : x => x ,
140141 getScriptKind : _ => undefined ,
141- hasMixedContent : _ => false
142+ hasMixedContent : ( fileName , extraFileExtensions ) => {
143+ const mixedContentExtensions = ts . map ( ts . filter ( extraFileExtensions , item => item . isMixedContent ) , item => item . extension ) ;
144+ return forEach ( mixedContentExtensions , extension => fileExtensionIs ( fileName , extension ) )
145+ }
142146 } ;
143147
144148 const externalFilePropertyReader : FilePropertyReader < protocol . ExternalFile > = {
@@ -282,7 +286,8 @@ namespace ts.server {
282286
283287 this . hostConfiguration = {
284288 formatCodeOptions : getDefaultFormatCodeSettings ( this . host ) ,
285- hostInfo : "Unknown host"
289+ hostInfo : "Unknown host" ,
290+ extraFileExtensions : [ ]
286291 } ;
287292
288293 this . documentRegistry = createDocumentRegistry ( host . useCaseSensitiveFileNames , host . getCurrentDirectory ( ) ) ;
@@ -486,7 +491,7 @@ namespace ts.server {
486491 // If a change was made inside "folder/file", node will trigger the callback twice:
487492 // one with the fileName being "folder/file", and the other one with "folder".
488493 // We don't respond to the second one.
489- if ( fileName && ! ts . isSupportedSourceFileName ( fileName , project . getCompilerOptions ( ) ) ) {
494+ if ( fileName && ! ts . isSupportedSourceFileName ( fileName , project . getCompilerOptions ( ) , this . hostConfiguration . extraFileExtensions ) ) {
490495 return ;
491496 }
492497
@@ -642,6 +647,9 @@ namespace ts.server {
642647 let projectsToRemove : Project [ ] ;
643648 for ( const p of info . containingProjects ) {
644649 if ( p . projectKind === ProjectKind . Configured ) {
650+ if ( info . hasMixedContent ) {
651+ info . registerFileUpdate ( ) ;
652+ }
645653 // last open file in configured project - close it
646654 if ( ( < ConfiguredProject > p ) . deleteOpenRef ( ) === 0 ) {
647655 ( projectsToRemove || ( projectsToRemove = [ ] ) ) . push ( p ) ;
@@ -810,7 +818,9 @@ namespace ts.server {
810818 this . host ,
811819 getDirectoryPath ( configFilename ) ,
812820 /*existingOptions*/ { } ,
813- configFilename ) ;
821+ configFilename ,
822+ /*resolutionStack*/ [ ] ,
823+ this . hostConfiguration . extraFileExtensions ) ;
814824
815825 if ( parsedCommandLine . errors . length ) {
816826 errors = concatenate ( errors , parsedCommandLine . errors ) ;
@@ -914,7 +924,7 @@ namespace ts.server {
914924 for ( const f of files ) {
915925 const rootFilename = propertyReader . getFileName ( f ) ;
916926 const scriptKind = propertyReader . getScriptKind ( f ) ;
917- const hasMixedContent = propertyReader . hasMixedContent ( f ) ;
927+ const hasMixedContent = propertyReader . hasMixedContent ( f , this . hostConfiguration . extraFileExtensions ) ;
918928 if ( this . host . fileExists ( rootFilename ) ) {
919929 const info = this . getOrCreateScriptInfoForNormalizedPath ( toNormalizedPath ( rootFilename ) , /*openedByClient*/ clientFileName == rootFilename , /*fileContent*/ undefined , scriptKind , hasMixedContent ) ;
920930 project . addRoot ( info ) ;
@@ -960,7 +970,7 @@ namespace ts.server {
960970 rootFilesChanged = true ;
961971 if ( ! scriptInfo ) {
962972 const scriptKind = propertyReader . getScriptKind ( f ) ;
963- const hasMixedContent = propertyReader . hasMixedContent ( f ) ;
973+ const hasMixedContent = propertyReader . hasMixedContent ( f , this . hostConfiguration . extraFileExtensions ) ;
964974 scriptInfo = this . getOrCreateScriptInfoForNormalizedPath ( normalizedPath , /*openedByClient*/ false , /*fileContent*/ undefined , scriptKind , hasMixedContent ) ;
965975 }
966976 }
@@ -1110,6 +1120,9 @@ namespace ts.server {
11101120 if ( info ) {
11111121 if ( openedByClient && ! info . isScriptOpen ( ) ) {
11121122 info . open ( fileContent ) ;
1123+ if ( hasMixedContent ) {
1124+ info . registerFileUpdate ( ) ;
1125+ }
11131126 }
11141127 else if ( fileContent !== undefined ) {
11151128 info . reload ( fileContent ) ;
@@ -1144,6 +1157,10 @@ namespace ts.server {
11441157 mergeMaps ( this . hostConfiguration . formatCodeOptions , convertFormatOptions ( args . formatOptions ) ) ;
11451158 this . logger . info ( "Format host information updated" ) ;
11461159 }
1160+ if ( args . extraFileExtensions ) {
1161+ this . hostConfiguration . extraFileExtensions = args . extraFileExtensions ;
1162+ this . logger . info ( "Host file extension mappings updated" ) ;
1163+ }
11471164 }
11481165 }
11491166
0 commit comments