@@ -69,6 +69,7 @@ namespace ts {
69
69
export function createCompilerHost ( options : CompilerOptions , setParentNodes ?: boolean ) : CompilerHost {
70
70
return createCompilerHostWorker ( options , setParentNodes ) ;
71
71
}
72
+
72
73
/*@internal */
73
74
// TODO(shkamat): update this after reworking ts build API
74
75
export function createCompilerHostWorker ( options : CompilerOptions , setParentNodes ?: boolean , system = sys ) : CompilerHost {
@@ -93,7 +94,6 @@ namespace ts {
93
94
}
94
95
text = "" ;
95
96
}
96
-
97
97
return text !== undefined ? createSourceFile ( fileName , text , languageVersion , setParentNodes ) : undefined ;
98
98
}
99
99
@@ -203,18 +203,25 @@ namespace ts {
203
203
return compilerHost ;
204
204
}
205
205
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
+
206
214
/*@internal */
207
- export function changeCompilerHostToUseCache (
208
- host : CompilerHost ,
215
+ export function changeCompilerHostLikeToUseCache (
216
+ host : CompilerHostLikeForCache ,
209
217
toPath : ( fileName : string ) => Path ,
210
- useCacheForSourceFile : boolean
218
+ getSourceFile ?: CompilerHost [ "getSourceFile" ]
211
219
) {
212
220
const originalReadFile = host . readFile ;
213
221
const originalFileExists = host . fileExists ;
214
222
const originalDirectoryExists = host . directoryExists ;
215
223
const originalCreateDirectory = host . createDirectory ;
216
224
const originalWriteFile = host . writeFile ;
217
- const originalGetSourceFile = host . getSourceFile ;
218
225
const readFileCache = createMap < string | false > ( ) ;
219
226
const fileExistsCache = createMap < boolean > ( ) ;
220
227
const directoryExistsCache = createMap < boolean > ( ) ;
@@ -242,19 +249,17 @@ namespace ts {
242
249
return setReadFileCache ( key , fileName ) ;
243
250
} ;
244
251
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 ;
250
256
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 ;
258
263
259
264
// fileExists for any kind of extension
260
265
host . fileExists = fileName => {
@@ -265,23 +270,25 @@ namespace ts {
265
270
fileExistsCache . set ( key , ! ! newValue ) ;
266
271
return newValue ;
267
272
} ;
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 ) ;
271
277
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 ) ;
280
281
sourceFileCache . delete ( key ) ;
281
282
}
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
+ }
285
292
286
293
// directoryExists
287
294
if ( originalDirectoryExists && originalCreateDirectory ) {
@@ -306,7 +313,7 @@ namespace ts {
306
313
originalDirectoryExists,
307
314
originalCreateDirectory,
308
315
originalWriteFile,
309
- originalGetSourceFile ,
316
+ getSourceFileWithCache ,
310
317
readFileWithCache
311
318
} ;
312
319
}
@@ -735,7 +742,7 @@ namespace ts {
735
742
performance . mark ( "beforeProgram" ) ;
736
743
737
744
const host = createProgramOptions . host || createCompilerHost ( options ) ;
738
- const configParsingHost = parseConfigHostFromCompilerHost ( host ) ;
745
+ const configParsingHost = parseConfigHostFromCompilerHostLike ( host ) ;
739
746
740
747
let skipDefaultLib = options . noLib ;
741
748
const getDefaultLibraryFileName = memoize ( ( ) => host . getDefaultLibFileName ( options ) ) ;
@@ -3104,18 +3111,28 @@ namespace ts {
3104
3111
}
3105
3112
}
3106
3113
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
+
3107
3124
/* @internal */
3108
- export function parseConfigHostFromCompilerHost ( host : CompilerHost ) : ParseConfigFileHost {
3125
+ export function parseConfigHostFromCompilerHostLike ( host : CompilerHostLike , directoryStructureHost : DirectoryStructureHost = host ) : ParseConfigFileHost {
3109
3126
return {
3110
- fileExists : f => host . fileExists ( f ) ,
3127
+ fileExists : f => directoryStructureHost . fileExists ( f ) ,
3111
3128
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 ) ;
3114
3131
} ,
3115
- readFile : f => host . readFile ( f ) ,
3132
+ readFile : f => directoryStructureHost . readFile ( f ) ,
3116
3133
useCaseSensitiveFileNames : host . useCaseSensitiveFileNames ( ) ,
3117
3134
getCurrentDirectory : ( ) => host . getCurrentDirectory ( ) ,
3118
- onUnRecoverableConfigFileDiagnostic : ( ) => undefined ,
3135
+ onUnRecoverableConfigFileDiagnostic : host . onUnRecoverableConfigFileDiagnostic || ( ( ) => undefined ) ,
3119
3136
trace : host . trace ? ( s ) => host . trace ! ( s ) : undefined
3120
3137
} ;
3121
3138
}
0 commit comments