@@ -69,6 +69,7 @@ namespace ts {
6969 export function createCompilerHost ( options : CompilerOptions , setParentNodes ?: boolean ) : CompilerHost {
7070 return createCompilerHostWorker ( options , setParentNodes ) ;
7171 }
72+
7273 /*@internal */
7374 // TODO(shkamat): update this after reworking ts build API
7475 export function createCompilerHostWorker ( options : CompilerOptions , setParentNodes ?: boolean , system = sys ) : CompilerHost {
@@ -93,7 +94,6 @@ namespace ts {
9394 }
9495 text = "" ;
9596 }
96-
9797 return text !== undefined ? createSourceFile ( fileName , text , languageVersion , setParentNodes ) : undefined ;
9898 }
9999
@@ -203,18 +203,25 @@ namespace ts {
203203 return compilerHost ;
204204 }
205205
206+ interface CompilerHostLikeForCache {
207+ fileExists ( fileName : string ) : boolean ;
208+ readFile ( fileName : string , encoding ?: string ) : string | undefined ;
209+ directoryExists ?( directory : string ) : boolean ;
210+ createDirectory ?( directory : string ) : void ;
211+ writeFile ?: WriteFileCallback ;
212+ }
213+
206214 /*@internal */
207- export function changeCompilerHostToUseCache (
208- host : CompilerHost ,
215+ export function changeCompilerHostLikeToUseCache (
216+ host : CompilerHostLikeForCache ,
209217 toPath : ( fileName : string ) => Path ,
210- useCacheForSourceFile : boolean
218+ getSourceFile ?: CompilerHost [ "getSourceFile" ]
211219 ) {
212220 const originalReadFile = host . readFile ;
213221 const originalFileExists = host . fileExists ;
214222 const originalDirectoryExists = host . directoryExists ;
215223 const originalCreateDirectory = host . createDirectory ;
216224 const originalWriteFile = host . writeFile ;
217- const originalGetSourceFile = host . getSourceFile ;
218225 const readFileCache = createMap < string | false > ( ) ;
219226 const fileExistsCache = createMap < boolean > ( ) ;
220227 const directoryExistsCache = createMap < boolean > ( ) ;
@@ -242,19 +249,17 @@ namespace ts {
242249 return setReadFileCache ( key , fileName ) ;
243250 } ;
244251
245- if ( useCacheForSourceFile ) {
246- host . getSourceFile = ( fileName , languageVersion , onError , shouldCreateNewSourceFile ) => {
247- const key = toPath ( fileName ) ;
248- const value = sourceFileCache . get ( key ) ;
249- if ( value ) return value ;
252+ const getSourceFileWithCache : CompilerHost [ "getSourceFile" ] | undefined = getSourceFile ? ( fileName , languageVersion , onError , shouldCreateNewSourceFile ) => {
253+ const key = toPath ( fileName ) ;
254+ const value = sourceFileCache . get ( key ) ;
255+ if ( value ) return value ;
250256
251- const sourceFile = originalGetSourceFile . call ( host , fileName , languageVersion , onError , shouldCreateNewSourceFile ) ;
252- if ( sourceFile && ( isDeclarationFileName ( fileName ) || fileExtensionIs ( fileName , Extension . Json ) ) ) {
253- sourceFileCache . set ( key , sourceFile ) ;
254- }
255- return sourceFile ;
256- } ;
257- }
257+ const sourceFile = getSourceFile ( fileName , languageVersion , onError , shouldCreateNewSourceFile ) ;
258+ if ( sourceFile && ( isDeclarationFileName ( fileName ) || fileExtensionIs ( fileName , Extension . Json ) ) ) {
259+ sourceFileCache . set ( key , sourceFile ) ;
260+ }
261+ return sourceFile ;
262+ } : undefined ;
258263
259264 // fileExists for any kind of extension
260265 host . fileExists = fileName => {
@@ -265,23 +270,25 @@ namespace ts {
265270 fileExistsCache . set ( key , ! ! newValue ) ;
266271 return newValue ;
267272 } ;
268- host . writeFile = ( fileName , data , writeByteOrderMark , onError , sourceFiles ) => {
269- const key = toPath ( fileName ) ;
270- fileExistsCache . delete ( key ) ;
273+ if ( originalWriteFile ) {
274+ host . writeFile = ( fileName , data , writeByteOrderMark , onError , sourceFiles ) => {
275+ const key = toPath ( fileName ) ;
276+ fileExistsCache . delete ( key ) ;
271277
272- const value = readFileCache . get ( key ) ;
273- if ( value && value !== data ) {
274- readFileCache . delete ( key ) ;
275- sourceFileCache . delete ( key ) ;
276- }
277- else if ( useCacheForSourceFile ) {
278- const sourceFile = sourceFileCache . get ( key ) ;
279- if ( sourceFile && sourceFile . text !== data ) {
278+ const value = readFileCache . get ( key ) ;
279+ if ( value && value !== data ) {
280+ readFileCache . delete ( key ) ;
280281 sourceFileCache . delete ( key ) ;
281282 }
282- }
283- originalWriteFile . call ( host , fileName , data , writeByteOrderMark , onError , sourceFiles ) ;
284- } ;
283+ else if ( getSourceFileWithCache ) {
284+ const sourceFile = sourceFileCache . get ( key ) ;
285+ if ( sourceFile && sourceFile . text !== data ) {
286+ sourceFileCache . delete ( key ) ;
287+ }
288+ }
289+ originalWriteFile . call ( host , fileName , data , writeByteOrderMark , onError , sourceFiles ) ;
290+ } ;
291+ }
285292
286293 // directoryExists
287294 if ( originalDirectoryExists && originalCreateDirectory ) {
@@ -306,7 +313,7 @@ namespace ts {
306313 originalDirectoryExists,
307314 originalCreateDirectory,
308315 originalWriteFile,
309- originalGetSourceFile ,
316+ getSourceFileWithCache ,
310317 readFileWithCache
311318 } ;
312319 }
@@ -735,7 +742,7 @@ namespace ts {
735742 performance . mark ( "beforeProgram" ) ;
736743
737744 const host = createProgramOptions . host || createCompilerHost ( options ) ;
738- const configParsingHost = parseConfigHostFromCompilerHost ( host ) ;
745+ const configParsingHost = parseConfigHostFromCompilerHostLike ( host ) ;
739746
740747 let skipDefaultLib = options . noLib ;
741748 const getDefaultLibraryFileName = memoize ( ( ) => host . getDefaultLibFileName ( options ) ) ;
@@ -3104,18 +3111,28 @@ namespace ts {
31043111 }
31053112 }
31063113
3114+ interface CompilerHostLike {
3115+ useCaseSensitiveFileNames ( ) : boolean ;
3116+ getCurrentDirectory ( ) : string ;
3117+ fileExists ( fileName : string ) : boolean ;
3118+ readFile ( fileName : string ) : string | undefined ;
3119+ readDirectory ?( rootDir : string , extensions : ReadonlyArray < string > , excludes : ReadonlyArray < string > | undefined , includes : ReadonlyArray < string > , depth ?: number ) : string [ ] ;
3120+ trace ?( s : string ) : void ;
3121+ onUnRecoverableConfigFileDiagnostic ?: DiagnosticReporter ;
3122+ }
3123+
31073124 /* @internal */
3108- export function parseConfigHostFromCompilerHost ( host : CompilerHost ) : ParseConfigFileHost {
3125+ export function parseConfigHostFromCompilerHostLike ( host : CompilerHostLike , directoryStructureHost : DirectoryStructureHost = host ) : ParseConfigFileHost {
31093126 return {
3110- fileExists : f => host . fileExists ( f ) ,
3127+ fileExists : f => directoryStructureHost . fileExists ( f ) ,
31113128 readDirectory ( root , extensions , excludes , includes , depth ) {
3112- Debug . assertDefined ( host . readDirectory , "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'" ) ;
3113- return host . readDirectory ! ( root , extensions , excludes , includes , depth ) ;
3129+ Debug . assertDefined ( directoryStructureHost . readDirectory , "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'" ) ;
3130+ return directoryStructureHost . readDirectory ! ( root , extensions , excludes , includes , depth ) ;
31143131 } ,
3115- readFile : f => host . readFile ( f ) ,
3132+ readFile : f => directoryStructureHost . readFile ( f ) ,
31163133 useCaseSensitiveFileNames : host . useCaseSensitiveFileNames ( ) ,
31173134 getCurrentDirectory : ( ) => host . getCurrentDirectory ( ) ,
3118- onUnRecoverableConfigFileDiagnostic : ( ) => undefined ,
3135+ onUnRecoverableConfigFileDiagnostic : host . onUnRecoverableConfigFileDiagnostic || ( ( ) => undefined ) ,
31193136 trace : host . trace ? ( s ) => host . trace ! ( s ) : undefined
31203137 } ;
31213138 }
0 commit comments