diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a88a63cc04..cdd3f2154a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3904,7 +3904,6 @@ "category": "Message", "code": 6353 }, - "Project '{0}' is up to date with .d.ts files from its dependencies": { "category": "Message", "code": 6354 @@ -3977,6 +3976,14 @@ "category": "Message", "code": 6371 }, + "Project '{0}' is out of date because output to prepend from its dependency '{1}' has changed": { + "category": "Message", + "code": 6372 + }, + "Updating output of project '{0}'...": { + "category": "Message", + "code": 6373 + }, "The expected type comes from property '{0}' which is declared here on type '{1}'": { "category": "Message", diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 0dafdf0cb7..b64017c127 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -67,6 +67,12 @@ namespace ts { * This means we can Pseudo-build (just touch timestamps), as if we had actually built this project. */ UpToDateWithUpstreamTypes, + /** + * The project appears out of date because its upstream inputs are newer than its outputs, + * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs. + * This means we can Pseudo-build (just manipulate outputs), as if we had actually built this project. + */ + OutOfDateWithPrepend, OutputMissing, OutOfDateWithSelf, OutOfDateWithUpstream, @@ -83,6 +89,7 @@ namespace ts { export type UpToDateStatus = | Status.Unbuildable | Status.UpToDate + | Status.OutOfDateWithPrepend | Status.OutputMissing | Status.OutOfDateWithSelf | Status.OutOfDateWithUpstream @@ -122,6 +129,15 @@ namespace ts { oldestOutputFileName: string; } + /** + * The project is up to date with respect to its inputs except for prepend output changed (no declaration file change in prepend). + */ + export interface OutOfDateWithPrepend { + type: UpToDateStatusType.OutOfDateWithPrepend; + outOfDateOutputFileName: string; + newerProjectName: string; + } + /** * One or more of the outputs of the project does not exist. */ @@ -842,7 +858,7 @@ namespace ts { if (usesPrepend && pseudoUpToDate) { return { - type: UpToDateStatusType.OutOfDateWithUpstream, + type: UpToDateStatusType.OutOfDateWithPrepend, outOfDateOutputFileName: oldestOutputFileName, newerProjectName: upstreamChangedProject! }; @@ -991,6 +1007,12 @@ namespace ts { return; } + //if (status.type === UpToDateStatusType.OutOfDateWithPrepend) { + // // Fake that files have been built by manipulating prepend and existing output + // //updateOutputTimestamps(proj); + // return; + //} + const buildResult = buildSingleProject(resolved); if (buildResult & BuildResultFlags.AnyErrors) return; @@ -1007,17 +1029,26 @@ namespace ts { // If declaration output is changed, build the project // otherwise mark the project UpToDateWithUpstreamTypes so it updates output time stamps const status = projectStatus.getValue(project); - if (prepend || !(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) { - if (status && (status.type === UpToDateStatusType.UpToDate || status.type === UpToDateStatusType.UpToDateWithUpstreamTypes)) { + if (!(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) { + if (status && (status.type === UpToDateStatusType.UpToDate || status.type === UpToDateStatusType.UpToDateWithUpstreamTypes || status.type === UpToDateStatusType.OutOfDateWithPrepend)) { projectStatus.setValue(project, { type: UpToDateStatusType.OutOfDateWithUpstream, - outOfDateOutputFileName: status.oldestOutputFileName, + outOfDateOutputFileName: status.type === UpToDateStatusType.OutOfDateWithPrepend ? status.outOfDateOutputFileName : status.oldestOutputFileName, newerProjectName: resolved }); } } else if (status && status.type === UpToDateStatusType.UpToDate) { - status.type = UpToDateStatusType.UpToDateWithUpstreamTypes; + if (prepend) { + projectStatus.setValue(project, { + type: UpToDateStatusType.OutOfDateWithPrepend, + outOfDateOutputFileName: status.oldestOutputFileName, + newerProjectName: resolved + }); + } + else { + status.type = UpToDateStatusType.UpToDateWithUpstreamTypes; + } } addProjToQueue(project); } @@ -1323,6 +1354,13 @@ namespace ts { continue; } + //if (status.type === UpToDateStatusType.OutOfDateWithPrepend && !options.force) { + // reportAndStoreErrors(next, errors); + // // Fake that files have been built by manipulating prepend and existing output + // // updateOutputTimestamps(proj); + // continue; + //} + if (status.type === UpToDateStatusType.UpstreamBlocked) { reportAndStoreErrors(next, errors); if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName); @@ -1445,6 +1483,10 @@ namespace ts { } // Don't report anything for "up to date because it was already built" -- too verbose break; + case UpToDateStatusType.OutOfDateWithPrepend: + return formatMessage(Diagnostics.Project_0_is_out_of_date_because_output_to_prepend_from_its_dependency_1_has_changed, + relName(configFileName), + relName(status.newerProjectName)); case UpToDateStatusType.UpToDateWithUpstreamTypes: return formatMessage(Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, relName(configFileName)); diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index 85306934f0..da27e1ae14 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -676,7 +676,7 @@ export const b = new A();`); [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/first/tsconfig.json", "src/first/bin/first-output.js", "src/first/first_PART1.ts"], [Diagnostics.Building_project_0, "/src/first/tsconfig.json"], [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/second/tsconfig.json", "src/second/second_part1.ts", "src/2/second-output.js"], - [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/third/tsconfig.json", "src/third/thirdjs/output/third-output.js", "src/first"], + [Diagnostics.Project_0_is_out_of_date_because_output_to_prepend_from_its_dependency_1_has_changed, "src/third/tsconfig.json", "src/first"], [Diagnostics.Building_project_0, "/src/third/tsconfig.json"] ); });