diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index f03de2be1aa14..8b29c3a7669f9 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -1019,10 +1019,34 @@ namespace ts { * in that order would be used to write the files */ function emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult { + let restorePendingEmitOnHandlingNoEmitSuccess = false; + let savedAffectedFilesPendingEmit; + let savedAffectedFilesPendingEmitKind; + let savedAffectedFilesPendingEmitIndex; + // Backup and restore affected pendings emit state for non emit Builder if noEmitOnError is enabled and emitBuildInfo could be written in case there are errors + // This ensures pending files to emit is updated in tsbuildinfo + // Note that when there are no errors, emit proceeds as if everything is emitted as it is callers reponsibility to write the files to disk if at all (because its builder that doesnt track files to emit) + if (kind !== BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram && + !targetSourceFile && + !outFile(state.compilerOptions) && + !state.compilerOptions.noEmit && + state.compilerOptions.noEmitOnError) { + restorePendingEmitOnHandlingNoEmitSuccess = true; + savedAffectedFilesPendingEmit = state.affectedFilesPendingEmit && state.affectedFilesPendingEmit.slice(); + savedAffectedFilesPendingEmitKind = state.affectedFilesPendingEmitKind && new Map(state.affectedFilesPendingEmitKind); + savedAffectedFilesPendingEmitIndex = state.affectedFilesPendingEmitIndex; + } + if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile); const result = handleNoEmitOptions(builderProgram, targetSourceFile, writeFile, cancellationToken); if (result) return result; + if (restorePendingEmitOnHandlingNoEmitSuccess) { + state.affectedFilesPendingEmit = savedAffectedFilesPendingEmit; + state.affectedFilesPendingEmitKind = savedAffectedFilesPendingEmitKind; + state.affectedFilesPendingEmitIndex = savedAffectedFilesPendingEmitIndex; + } + // Emit only affected files if using builder for emit if (!targetSourceFile && kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) { // Emit and report any errors we ran into. @@ -1070,7 +1094,7 @@ namespace ts { // Add file to affected file pending emit to handle for later emit time // Apart for emit builder do this for tsbuildinfo, do this for non emit builder when noEmit is set as tsbuildinfo is written and reused between emitters - if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram || state.compilerOptions.noEmit) { + if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram || state.compilerOptions.noEmit || state.compilerOptions.noEmitOnError) { addToAffectedFilesPendingEmit(state, (affected as SourceFile).resolvedPath, BuilderFileEmit.Full); }