@@ -148,7 +148,7 @@ namespace ts {
148
148
/**
149
149
* true if build info is emitted
150
150
*/
151
- emittedBuildInfo ? : boolean ;
151
+ buildInfoEmitPending : boolean ;
152
152
/**
153
153
* Already seen emitted files
154
154
*/
@@ -250,14 +250,14 @@ namespace ts {
250
250
BuilderState . getAllFilesExcludingDefaultLibraryFile ( state , newProgram , /*firstSourceFile*/ undefined )
251
251
. forEach ( file => state . changedFilesSet . set ( file . resolvedPath , true ) ) ;
252
252
}
253
- else if ( oldCompilerOptions && compilerOptionsAffectEmit ( compilerOptions , oldCompilerOptions ) ) {
253
+ else if ( oldCompilerOptions && ! outFile ( compilerOptions ) && compilerOptionsAffectEmit ( compilerOptions , oldCompilerOptions ) ) {
254
254
// Add all files to affectedFilesPendingEmit since emit changed
255
255
newProgram . getSourceFiles ( ) . forEach ( f => addToAffectedFilesPendingEmit ( state , f . resolvedPath , BuilderFileEmit . Full ) ) ;
256
256
Debug . assert ( ! state . seenAffectedFiles || ! state . seenAffectedFiles . size ) ;
257
257
state . seenAffectedFiles = state . seenAffectedFiles || createMap < true > ( ) ;
258
258
}
259
259
260
- state . emittedBuildInfo = ! state . changedFilesSet . size && ! state . affectedFilesPendingEmit ;
260
+ state . buildInfoEmitPending = ! ! state . changedFilesSet . size ;
261
261
return state ;
262
262
}
263
263
@@ -611,7 +611,7 @@ namespace ts {
611
611
isBuildInfoEmit ?: boolean
612
612
) {
613
613
if ( isBuildInfoEmit ) {
614
- state . emittedBuildInfo = true ;
614
+ state . buildInfoEmitPending = false ;
615
615
}
616
616
else if ( affected === state . program ) {
617
617
state . changedFilesSet . clear ( ) ;
@@ -624,6 +624,7 @@ namespace ts {
624
624
}
625
625
if ( isPendingEmit ) {
626
626
state . affectedFilesPendingEmitIndex ! ++ ;
627
+ state . buildInfoEmitPending = true ;
627
628
}
628
629
else {
629
630
state . affectedFilesIndex ! ++ ;
@@ -688,12 +689,14 @@ namespace ts {
688
689
}
689
690
690
691
export type ProgramBuildInfoDiagnostic = string | [ string , readonly ReusableDiagnostic [ ] ] ;
692
+ export type ProgramBuilderInfoFilePendingEmit = [ string , BuilderFileEmit ] ;
691
693
export interface ProgramBuildInfo {
692
694
fileInfos : MapLike < BuilderState . FileInfo > ;
693
695
options : CompilerOptions ;
694
696
referencedMap ?: MapLike < string [ ] > ;
695
697
exportedModulesMap ?: MapLike < string [ ] > ;
696
698
semanticDiagnosticsPerFile ?: ProgramBuildInfoDiagnostic [ ] ;
699
+ affectedFilesPendingEmit ?: ProgramBuilderInfoFilePendingEmit [ ] ;
697
700
}
698
701
699
702
/**
@@ -751,6 +754,17 @@ namespace ts {
751
754
result . semanticDiagnosticsPerFile = semanticDiagnosticsPerFile ;
752
755
}
753
756
757
+ if ( state . affectedFilesPendingEmit ) {
758
+ const affectedFilesPendingEmit : ProgramBuilderInfoFilePendingEmit [ ] = [ ] ;
759
+ const seenFiles = createMap < true > ( ) ;
760
+ for ( let i = state . affectedFilesPendingEmitIndex ! ; i < state . affectedFilesPendingEmit . length ; i ++ ) {
761
+ const path = state . affectedFilesPendingEmit [ i ] ;
762
+ if ( ! addToSeen ( seenFiles , path ) ) continue ;
763
+ affectedFilesPendingEmit . push ( [ relativeToBuildInfo ( path ) , state . affectedFilesPendingEmitKind ! . get ( path ) ! ] ) ;
764
+ }
765
+ result . affectedFilesPendingEmit = affectedFilesPendingEmit ;
766
+ }
767
+
754
768
return result ;
755
769
756
770
function relativeToBuildInfoEnsuringAbsolutePath ( path : string ) {
@@ -916,13 +930,23 @@ namespace ts {
916
930
else if ( kind === BuilderProgramKind . EmitAndSemanticDiagnosticsBuilderProgram ) {
917
931
( builderProgram as EmitAndSemanticDiagnosticsBuilderProgram ) . getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile ;
918
932
( builderProgram as EmitAndSemanticDiagnosticsBuilderProgram ) . emitNextAffectedFile = emitNextAffectedFile ;
933
+ builderProgram . emitBuildInfo = emitBuildInfo ;
919
934
}
920
935
else {
921
936
notImplemented ( ) ;
922
937
}
923
938
924
939
return builderProgram ;
925
940
941
+ function emitBuildInfo ( writeFile ?: WriteFileCallback , cancellationToken ?: CancellationToken ) : EmitResult {
942
+ if ( state . buildInfoEmitPending ) {
943
+ const result = Debug . checkDefined ( state . program ) . emitBuildInfo ( writeFile || maybeBind ( host , host . writeFile ) , cancellationToken ) ;
944
+ state . buildInfoEmitPending = false ;
945
+ return result ;
946
+ }
947
+ return emitSkippedWithNoDiagnostics ;
948
+ }
949
+
926
950
/**
927
951
* Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
928
952
* The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
@@ -936,7 +960,7 @@ namespace ts {
936
960
if ( ! outFile ( state . compilerOptions ) ) {
937
961
const pendingAffectedFile = getNextAffectedFilePendingEmit ( state ) ;
938
962
if ( ! pendingAffectedFile ) {
939
- if ( state . emittedBuildInfo ) {
963
+ if ( ! state . buildInfoEmitPending ) {
940
964
return undefined ;
941
965
}
942
966
@@ -993,7 +1017,7 @@ namespace ts {
993
1017
function emit ( targetSourceFile ?: SourceFile , writeFile ?: WriteFileCallback , cancellationToken ?: CancellationToken , emitOnlyDtsFiles ?: boolean , customTransformers ?: CustomTransformers ) : EmitResult {
994
1018
if ( kind === BuilderProgramKind . EmitAndSemanticDiagnosticsBuilderProgram ) {
995
1019
assertSourceFileOkWithoutNextAffectedCall ( state , targetSourceFile ) ;
996
- const result = handleNoEmitOptions ( builderProgram , targetSourceFile , cancellationToken ) ;
1020
+ const result = handleNoEmitOptions ( builderProgram , targetSourceFile , writeFile , cancellationToken ) ;
997
1021
if ( result ) return result ;
998
1022
if ( ! targetSourceFile ) {
999
1023
// Emit and report any errors we ran into.
@@ -1142,7 +1166,10 @@ namespace ts {
1142
1166
referencedMap : getMapOfReferencedSet ( program . referencedMap , toPath ) ,
1143
1167
exportedModulesMap : getMapOfReferencedSet ( program . exportedModulesMap , toPath ) ,
1144
1168
semanticDiagnosticsPerFile : program . semanticDiagnosticsPerFile && arrayToMap ( program . semanticDiagnosticsPerFile , value => toPath ( isString ( value ) ? value : value [ 0 ] ) , value => isString ( value ) ? emptyArray : value [ 1 ] ) ,
1145
- hasReusableDiagnostic : true
1169
+ hasReusableDiagnostic : true ,
1170
+ affectedFilesPendingEmit : map ( program . affectedFilesPendingEmit , value => toPath ( value [ 0 ] ) ) ,
1171
+ affectedFilesPendingEmitKind : program . affectedFilesPendingEmit && arrayToMap ( program . affectedFilesPendingEmit , value => toPath ( value [ 0 ] ) , value => value [ 1 ] ) ,
1172
+ affectedFilesPendingEmitIndex : program . affectedFilesPendingEmit && 0 ,
1146
1173
} ;
1147
1174
return {
1148
1175
getState : ( ) => state ,
@@ -1165,6 +1192,7 @@ namespace ts {
1165
1192
getCurrentDirectory : notImplemented ,
1166
1193
emitNextAffectedFile : notImplemented ,
1167
1194
getSemanticDiagnosticsOfNextAffectedFile : notImplemented ,
1195
+ emitBuildInfo : notImplemented ,
1168
1196
close : noop ,
1169
1197
} ;
1170
1198
@@ -1195,6 +1223,7 @@ namespace ts {
1195
1223
getDeclarationDiagnostics : ( sourceFile , cancellationToken ) => getProgram ( ) . getDeclarationDiagnostics ( sourceFile , cancellationToken ) ,
1196
1224
getSemanticDiagnostics : ( sourceFile , cancellationToken ) => getProgram ( ) . getSemanticDiagnostics ( sourceFile , cancellationToken ) ,
1197
1225
emit : ( sourceFile , writeFile , cancellationToken , emitOnlyDts , customTransformers ) => getProgram ( ) . emit ( sourceFile , writeFile , cancellationToken , emitOnlyDts , customTransformers ) ,
1226
+ emitBuildInfo : ( writeFile , cancellationToken ) => getProgram ( ) . emitBuildInfo ( writeFile , cancellationToken ) ,
1198
1227
getAllDependencies : notImplemented ,
1199
1228
getCurrentDirectory : ( ) => getProgram ( ) . getCurrentDirectory ( ) ,
1200
1229
close : noop ,
0 commit comments