diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index e17057b9140..1bf5bed76a2 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -1050,14 +1050,6 @@ namespace ts { return buildErrors(syntaxDiagnostics, BuildResultFlags.SyntaxErrors, "Syntactic"); } - // Don't emit .d.ts if there are decl file errors - if (getEmitDeclarations(program.getCompilerOptions())) { - const declDiagnostics = program.getDeclarationDiagnostics(); - if (declDiagnostics.length) { - return buildErrors(declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file"); - } - } - // Same as above but now for semantic diagnostics const semanticDiagnostics = program.getSemanticDiagnostics(); if (semanticDiagnostics.length) { @@ -1066,14 +1058,23 @@ namespace ts { let newestDeclarationFileContentChangedTime = minimumDate; let anyDtsChanged = false; - let emitDiagnostics: Diagnostic[] | undefined; - const reportEmitDiagnostic = (d: Diagnostic) => (emitDiagnostics || (emitDiagnostics = [])).push(d); - emitFilesAndReportErrors(program, reportEmitDiagnostic, writeFileName, /*reportSummary*/ undefined, (fileName, content, writeBom, onError) => { + let declDiagnostics: Diagnostic[] | undefined; + const reportDeclarationDiagnostics = (d: Diagnostic) => (declDiagnostics || (declDiagnostics = [])).push(d); + const outputFiles: OutputFile[] = []; + emitFilesAndReportErrors(program, reportDeclarationDiagnostics, writeFileName, /*reportSummary*/ undefined, (name, text, writeByteOrderMark) => outputFiles.push({ name, text, writeByteOrderMark })); + // Don't emit .d.ts if there are decl file errors + if (declDiagnostics) { + return buildErrors(declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file"); + } + + // Actual Emit + const emitterDiagnostics = createDiagnosticCollection(); + outputFiles.forEach(({ name, text, writeByteOrderMark }) => { let priorChangeTime: Date | undefined; - if (!anyDtsChanged && isDeclarationFile(fileName)) { + if (!anyDtsChanged && isDeclarationFile(name)) { // Check for unchanged .d.ts files - if (host.fileExists(fileName) && host.readFile(fileName) === content) { - priorChangeTime = host.getModifiedTime(fileName); + if (host.fileExists(name) && host.readFile(name) === text) { + priorChangeTime = host.getModifiedTime(name); } else { resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged; @@ -1081,14 +1082,15 @@ namespace ts { } } - host.writeFile(fileName, content, writeBom, onError, emptyArray); + writeFile(host, emitterDiagnostics, name, text, writeByteOrderMark); if (priorChangeTime !== undefined) { newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime); - unchangedOutputs.setValue(fileName, priorChangeTime); + unchangedOutputs.setValue(name, priorChangeTime); } }); - if (emitDiagnostics) { + const emitDiagnostics = emitterDiagnostics.getDiagnostics(); + if (emitDiagnostics.length) { return buildErrors(emitDiagnostics, BuildResultFlags.EmitErrors, "Emit"); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8ed85db3a23..30fd1ca1784 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3402,7 +3402,7 @@ namespace ts { return combinePaths(newDirPath, sourceFilePath); } - export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: ReadonlyArray) { + export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: ReadonlyArray) { host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => { diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage)); }, sourceFiles);