@@ -93,12 +93,14 @@ namespace ts {
93
93
signature : string ;
94
94
}
95
95
96
- export function createBuilder (
97
- getCanonicalFileName : ( fileName : string ) => string ,
98
- getEmitOutput : ( program : Program , sourceFile : SourceFile , emitOnlyDtsFiles : boolean , isDetailed : boolean ) => EmitOutput | EmitOutputDetailed ,
99
- computeHash : ( data : string ) => string ,
100
- shouldEmitFile : ( sourceFile : SourceFile ) => boolean
101
- ) : Builder {
96
+ export interface BuilderOptions {
97
+ getCanonicalFileName : ( fileName : string ) => string ;
98
+ getEmitOutput : ( program : Program , sourceFile : SourceFile , emitOnlyDtsFiles : boolean , isDetailed : boolean ) => EmitOutput | EmitOutputDetailed ;
99
+ computeHash : ( data : string ) => string ;
100
+ shouldEmitFile : ( sourceFile : SourceFile ) => boolean ;
101
+ }
102
+
103
+ export function createBuilder ( options : BuilderOptions ) : Builder {
102
104
let isModuleEmit : boolean | undefined ;
103
105
const fileInfos = createMap < FileInfo > ( ) ;
104
106
const semanticDiagnosticsPerFile = createMap < ReadonlyArray < Diagnostic > > ( ) ;
@@ -181,7 +183,7 @@ namespace ts {
181
183
ensureProgramGraph ( program ) ;
182
184
183
185
const sourceFile = program . getSourceFile ( path ) ;
184
- const singleFileResult = sourceFile && shouldEmitFile ( sourceFile ) ? [ sourceFile . fileName ] : [ ] ;
186
+ const singleFileResult = sourceFile && options . shouldEmitFile ( sourceFile ) ? [ sourceFile . fileName ] : [ ] ;
185
187
const info = fileInfos . get ( path ) ;
186
188
if ( ! info || ! updateShapeSignature ( program , sourceFile , info ) ) {
187
189
return singleFileResult ;
@@ -197,7 +199,7 @@ namespace ts {
197
199
return { outputFiles : [ ] , emitSkipped : true } ;
198
200
}
199
201
200
- return getEmitOutput ( program , program . getSourceFileByPath ( path ) , /*emitOnlyDtsFiles*/ false , /*isDetailed*/ false ) ;
202
+ return options . getEmitOutput ( program , program . getSourceFileByPath ( path ) , /*emitOnlyDtsFiles*/ false , /*isDetailed*/ false ) ;
201
203
}
202
204
203
205
function enumerateChangedFilesSet (
@@ -220,21 +222,21 @@ namespace ts {
220
222
onChangedFile : ( fileName : string , path : Path ) => void ,
221
223
onEmitOutput : ( emitOutput : EmitOutputDetailed , sourceFile : SourceFile ) => void
222
224
) {
223
- const seenFiles = createMap < SourceFile > ( ) ;
225
+ const seenFiles = createMap < true > ( ) ;
224
226
enumerateChangedFilesSet ( program , onChangedFile , ( fileName , sourceFile ) => {
225
227
if ( ! seenFiles . has ( fileName ) ) {
226
- seenFiles . set ( fileName , sourceFile ) ;
228
+ seenFiles . set ( fileName , true ) ;
227
229
if ( sourceFile ) {
228
230
// Any affected file shouldnt have the cached diagnostics
229
231
semanticDiagnosticsPerFile . delete ( sourceFile . path ) ;
230
232
231
- const emitOutput = getEmitOutput ( program , sourceFile , emitOnlyDtsFiles , /*isDetailed*/ true ) as EmitOutputDetailed ;
233
+ const emitOutput = options . getEmitOutput ( program , sourceFile , emitOnlyDtsFiles , /*isDetailed*/ true ) as EmitOutputDetailed ;
232
234
onEmitOutput ( emitOutput , sourceFile ) ;
233
235
234
236
// mark all the emitted source files as seen
235
237
if ( emitOutput . emittedSourceFiles ) {
236
238
for ( const file of emitOutput . emittedSourceFiles ) {
237
- seenFiles . set ( file . fileName , file ) ;
239
+ seenFiles . set ( file . fileName , true ) ;
238
240
}
239
241
}
240
242
}
@@ -309,13 +311,13 @@ namespace ts {
309
311
const prevSignature = info . signature ;
310
312
let latestSignature : string ;
311
313
if ( sourceFile . isDeclarationFile ) {
312
- latestSignature = computeHash ( sourceFile . text ) ;
314
+ latestSignature = options . computeHash ( sourceFile . text ) ;
313
315
info . signature = latestSignature ;
314
316
}
315
317
else {
316
- const emitOutput = getEmitOutput ( program , sourceFile , /*emitOnlyDtsFiles*/ true , /*isDetailed*/ false ) ;
318
+ const emitOutput = options . getEmitOutput ( program , sourceFile , /*emitOnlyDtsFiles*/ true , /*isDetailed*/ false ) ;
317
319
if ( emitOutput . outputFiles && emitOutput . outputFiles . length > 0 ) {
318
- latestSignature = computeHash ( emitOutput . outputFiles [ 0 ] . text ) ;
320
+ latestSignature = options . computeHash ( emitOutput . outputFiles [ 0 ] . text ) ;
319
321
info . signature = latestSignature ;
320
322
}
321
323
else {
@@ -352,7 +354,7 @@ namespace ts {
352
354
// Handle triple slash references
353
355
if ( sourceFile . referencedFiles && sourceFile . referencedFiles . length > 0 ) {
354
356
for ( const referencedFile of sourceFile . referencedFiles ) {
355
- const referencedPath = toPath ( referencedFile . fileName , sourceFileDirectory , getCanonicalFileName ) ;
357
+ const referencedPath = toPath ( referencedFile . fileName , sourceFileDirectory , options . getCanonicalFileName ) ;
356
358
addReferencedFile ( referencedPath ) ;
357
359
}
358
360
}
@@ -365,7 +367,7 @@ namespace ts {
365
367
}
366
368
367
369
const fileName = resolvedTypeReferenceDirective . resolvedFileName ;
368
- const typeFilePath = toPath ( fileName , sourceFileDirectory , getCanonicalFileName ) ;
370
+ const typeFilePath = toPath ( fileName , sourceFileDirectory , options . getCanonicalFileName ) ;
369
371
addReferencedFile ( typeFilePath ) ;
370
372
} ) ;
371
373
}
@@ -381,18 +383,26 @@ namespace ts {
381
383
}
382
384
383
385
/**
384
- * Gets all the emittable files from the program
386
+ * Gets all the emittable files from the program.
387
+ * @param firstSourceFile This one will be emitted first. See https://github.com/Microsoft/TypeScript/issues/16888
385
388
*/
386
- function getAllEmittableFiles ( program : Program ) {
389
+ function getAllEmittableFiles ( program : Program , firstSourceFile : SourceFile ) : string [ ] {
387
390
const defaultLibraryFileName = getDefaultLibFileName ( program . getCompilerOptions ( ) ) ;
388
391
const sourceFiles = program . getSourceFiles ( ) ;
389
392
const result : string [ ] = [ ] ;
393
+ add ( firstSourceFile ) ;
390
394
for ( const sourceFile of sourceFiles ) {
391
- if ( getBaseFileName ( sourceFile . fileName ) !== defaultLibraryFileName && shouldEmitFile ( sourceFile ) ) {
392
- result . push ( sourceFile . fileName ) ;
395
+ if ( sourceFile !== firstSourceFile ) {
396
+ add ( sourceFile ) ;
393
397
}
394
398
}
395
399
return result ;
400
+
401
+ function add ( sourceFile : SourceFile ) : void {
402
+ if ( getBaseFileName ( sourceFile . fileName ) !== defaultLibraryFileName && options . shouldEmitFile ( sourceFile ) ) {
403
+ result . push ( sourceFile . fileName ) ;
404
+ }
405
+ }
396
406
}
397
407
398
408
function getNonModuleEmitHandler ( ) : EmitHandler {
@@ -404,14 +414,14 @@ namespace ts {
404
414
getFilesAffectedByUpdatedShape
405
415
} ;
406
416
407
- function getFilesAffectedByUpdatedShape ( program : Program , _sourceFile : SourceFile , singleFileResult : string [ ] ) : string [ ] {
417
+ function getFilesAffectedByUpdatedShape ( program : Program , sourceFile : SourceFile , singleFileResult : string [ ] ) : string [ ] {
408
418
const options = program . getCompilerOptions ( ) ;
409
419
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
410
420
// so returning the file itself is good enough.
411
421
if ( options && ( options . out || options . outFile ) ) {
412
422
return singleFileResult ;
413
423
}
414
- return getAllEmittableFiles ( program ) ;
424
+ return getAllEmittableFiles ( program , sourceFile ) ;
415
425
}
416
426
}
417
427
@@ -484,11 +494,11 @@ namespace ts {
484
494
485
495
function getFilesAffectedByUpdatedShape ( program : Program , sourceFile : SourceFile , singleFileResult : string [ ] ) : string [ ] {
486
496
if ( ! isExternalModule ( sourceFile ) && ! containsOnlyAmbientModules ( sourceFile ) ) {
487
- return getAllEmittableFiles ( program ) ;
497
+ return getAllEmittableFiles ( program , sourceFile ) ;
488
498
}
489
499
490
- const options = program . getCompilerOptions ( ) ;
491
- if ( options && ( options . isolatedModules || options . out || options . outFile ) ) {
500
+ const compilerOptions = program . getCompilerOptions ( ) ;
501
+ if ( compilerOptions && ( compilerOptions . isolatedModules || compilerOptions . out || compilerOptions . outFile ) ) {
492
502
return singleFileResult ;
493
503
}
494
504
@@ -498,7 +508,7 @@ namespace ts {
498
508
499
509
const seenFileNamesMap = createMap < string > ( ) ;
500
510
const setSeenFileName = ( path : Path , sourceFile : SourceFile ) => {
501
- seenFileNamesMap . set ( path , sourceFile && shouldEmitFile ( sourceFile ) ? sourceFile . fileName : undefined ) ;
511
+ seenFileNamesMap . set ( path , sourceFile && options . shouldEmitFile ( sourceFile ) ? sourceFile . fileName : undefined ) ;
502
512
} ;
503
513
504
514
// Start with the paths this file was referenced by
0 commit comments