Skip to content

Commit 68e28da

Browse files
committed
Build project if existing project was built with different compiler version
1 parent ecb2ce4 commit 68e28da

File tree

8 files changed

+65
-17
lines changed

8 files changed

+65
-17
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4044,6 +4044,10 @@
40444044
"category": "Message",
40454045
"code": 6380
40464046
},
4047+
"Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'": {
4048+
"category": "Message",
4049+
"code": 6381
4050+
},
40474051

40484052
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
40494053
"category": "Message",

src/compiler/emitter.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,11 @@ namespace ts {
466466
return JSON.stringify(buildInfo, undefined, 2);
467467
}
468468

469+
/*@internal*/
470+
export function getBuildInfo(buildInfoText: string) {
471+
return JSON.parse(buildInfoText) as BuildInfo;
472+
}
473+
469474
/*@internal*/
470475
export const notImplementedResolver: EmitResolver = {
471476
hasGlobalName: notImplemented,
@@ -560,7 +565,7 @@ namespace ts {
560565
// error if no source map or for now if inline sourcemap
561566
if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap) return declarationMapPath || "inline sourcemap decoding";
562567

563-
const buildInfo = JSON.parse(buildInfoText) as BuildInfo;
568+
const buildInfo = getBuildInfo(buildInfoText);
564569
if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts)) return buildInfoPath!;
565570
const ownPrependInput = createInputFiles(
566571
jsFileText,
@@ -599,7 +604,7 @@ namespace ts {
599604
if (sourceMapText === text) return;
600605
break;
601606
case buildInfoPath:
602-
const newBuildInfo = JSON.parse(text) as BuildInfo;
607+
const newBuildInfo = getBuildInfo(text);
603608
newBuildInfo.program = buildInfo.program;
604609
// Update sourceFileInfo
605610
const { js, dts, sourceFiles } = buildInfo.bundle!;

src/compiler/factory.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,10 +2891,10 @@ namespace ts {
28912891
return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`;
28922892
};
28932893
let buildInfo: BuildInfo | false;
2894-
const getBuildInfo = (getText: () => string | undefined) => {
2894+
const getAndCacheBuildInfo = (getText: () => string | undefined) => {
28952895
if (buildInfo === undefined) {
28962896
const result = getText();
2897-
buildInfo = result !== undefined ? JSON.parse(result) as BuildInfo : false;
2897+
buildInfo = result !== undefined ? getBuildInfo(result) : false;
28982898
}
28992899
return buildInfo || undefined;
29002900
};
@@ -2908,7 +2908,7 @@ namespace ts {
29082908
javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, // TODO:: if there is inline sourceMap in jsFile, use that
29092909
declarationText: { get() { return definedTextGetter(Debug.assertDefined(javascriptMapTextOrDeclarationPath)); } },
29102910
declarationMapText: { get() { return textGetter(declarationMapPath); } }, // TODO:: if there is inline sourceMap in dtsFile, use that
2911-
buildInfo: { get() { return getBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } }
2911+
buildInfo: { get() { return getAndCacheBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } }
29122912
});
29132913
}
29142914
else {

src/compiler/tsbuild.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace ts {
7979
UpstreamOutOfDate,
8080
UpstreamBlocked,
8181
ComputingUpstream,
82+
TsVersionOutputOfDate,
8283

8384
/**
8485
* Projects with no outputs (i.e. "solution" files)
@@ -96,6 +97,7 @@ namespace ts {
9697
| Status.UpstreamOutOfDate
9798
| Status.UpstreamBlocked
9899
| Status.ComputingUpstream
100+
| Status.TsVersionOutOfDate
99101
| Status.ContainerOnly;
100102

101103
export namespace Status {
@@ -181,6 +183,11 @@ namespace ts {
181183
type: UpToDateStatusType.ComputingUpstream;
182184
}
183185

186+
export interface TsVersionOutOfDate {
187+
type: UpToDateStatusType.TsVersionOutputOfDate;
188+
version: string;
189+
}
190+
184191
/**
185192
* One or more of the project's outputs is older than the newest output of
186193
* an upstream project.
@@ -454,6 +461,8 @@ namespace ts {
454461
return result;
455462
};
456463

464+
const buildInfoChecked = createFileMap<true>(toPath);
465+
457466
// Watch state
458467
const builderPrograms = createFileMap<T>(toPath);
459468
const diagnostics = createFileMap<ReadonlyArray<Diagnostic>>(toPath);
@@ -499,6 +508,7 @@ namespace ts {
499508
projectStatus.clear();
500509
missingRoots.clear();
501510
globalDependencyGraph = undefined;
511+
buildInfoChecked.clear();
502512

503513
diagnostics.clear();
504514
projectPendingBuild.clear();
@@ -844,6 +854,21 @@ namespace ts {
844854
};
845855
}
846856

857+
if (!buildInfoChecked.hasKey(project.options.configFilePath as ResolvedConfigFileName)) {
858+
buildInfoChecked.setValue(project.options.configFilePath as ResolvedConfigFileName, true);
859+
const buildInfoPath = getOutputPathForBuildInfo(project.options);
860+
if (buildInfoPath) {
861+
const value = readFileWithCache(buildInfoPath);
862+
const buildInfo = value && getBuildInfo(value);
863+
if (buildInfo && buildInfo.version !== version) {
864+
return {
865+
type: UpToDateStatusType.TsVersionOutputOfDate,
866+
version: buildInfo.version
867+
};
868+
}
869+
}
870+
}
871+
847872
if (usesPrepend && pseudoUpToDate) {
848873
return {
849874
type: UpToDateStatusType.OutOfDateWithPrepend,
@@ -1220,7 +1245,8 @@ namespace ts {
12201245
if (!buildInfoPath) return undefined;
12211246
const content = readFileWithCache(buildInfoPath);
12221247
if (!content) return undefined;
1223-
const buildInfo = JSON.parse(content) as BuildInfo;
1248+
const buildInfo = getBuildInfo(content);
1249+
if (buildInfo.version !== version) return undefined;
12241250
return buildInfo.program && createBuildProgramUsingProgramBuildInfo(buildInfo.program) as any as T;
12251251
}
12261252

@@ -1545,6 +1571,11 @@ namespace ts {
15451571
return formatMessage(Diagnostics.Failed_to_parse_file_0_Colon_1,
15461572
relName(configFileName),
15471573
status.reason);
1574+
case UpToDateStatusType.TsVersionOutputOfDate:
1575+
return formatMessage(Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2,
1576+
relName(configFileName),
1577+
status.version,
1578+
version);
15481579
case UpToDateStatusType.ContainerOnly:
15491580
// Don't report status on "solution" projects
15501581
case UpToDateStatusType.ComputingUpstream:

src/harness/fakes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ namespace fakes {
396396
readFile(path: string) {
397397
const value = super.readFile(path);
398398
if (!value || !ts.isBuildInfoFile(path)) return value;
399-
const buildInfo = JSON.parse(value) as ts.BuildInfo;
399+
const buildInfo = ts.getBuildInfo(value);
400400
if (buildInfo.program) {
401401
// Fix lib signatures
402402
for (const path of ts.getOwnKeys(buildInfo.program.fileInfos)) {
@@ -417,7 +417,7 @@ namespace fakes {
417417

418418
public writeFile(fileName: string, content: string, writeByteOrderMark: boolean) {
419419
if (!ts.isBuildInfoFile(fileName)) return super.writeFile(fileName, content, writeByteOrderMark);
420-
const buildInfo = JSON.parse(content) as ts.BuildInfo;
420+
const buildInfo = ts.getBuildInfo(content);
421421
if (buildInfo.program) {
422422
// Fix lib signatures
423423
for (const path of ts.getOwnKeys(buildInfo.program.fileInfos)) {

src/testRunner/unittests/tsbuild/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace ts {
88
host.readFile = path => {
99
const value = originalReadFile.call(host, path);
1010
if (!value || !isBuildInfoFile(path)) return value;
11-
const buildInfo = JSON.parse(value) as BuildInfo;
11+
const buildInfo = getBuildInfo(value);
1212
buildInfo.version = fakes.version;
1313
return getBuildInfoText(buildInfo);
1414
};
@@ -101,7 +101,7 @@ namespace ts {
101101
for (const [file, jsFile, dtsFile] of buildInfoFileNames) {
102102
if (!fs.existsSync(file)) continue;
103103

104-
const buildInfo = JSON.parse(fs.readFileSync(file, "utf8")) as BuildInfo;
104+
const buildInfo = getBuildInfo(fs.readFileSync(file, "utf8"));
105105
const bundle = buildInfo.bundle;
106106
if (!bundle || (!length(bundle.js && bundle.js.sections) && !length(bundle.dts && bundle.dts.sections))) continue;
107107

src/testRunner/unittests/tsbuild/outFile.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,12 @@ namespace ts {
451451
host.assertDiagnosticMessages(
452452
// TODO:: This should build all instead
453453
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
454-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.first][source.config], relSources[project.first][source.ts][part.one], relOutputFiles[project.first][ext.js]],
455-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
456-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.third][source.config], relSources[project.third][source.ts][part.one], relOutputFiles[project.third][ext.js]],
454+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relSources[project.first][source.config], fakes.version, version],
455+
[Diagnostics.Building_project_0, sources[project.first][source.config]],
456+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relSources[project.second][source.config], fakes.version, version],
457+
[Diagnostics.Building_project_0, sources[project.second][source.config]],
458+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relSources[project.third][source.config], fakes.version, version],
459+
[Diagnostics.Building_project_0, sources[project.third][source.config]],
457460
);
458461
});
459462

src/testRunner/unittests/tsbuild/sample.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,13 @@ namespace ts {
245245
changeCompilerVersion(host);
246246
builder.buildAllProjects();
247247
host.assertDiagnosticMessages(
248-
// TODO:: This should build all instead
249248
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
250-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"],
251-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
252-
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/tests/tsconfig.json", "src/tests/index.ts", "src/tests/index.js"]
249+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, "src/core/tsconfig.json", fakes.version, version],
250+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
251+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, "src/logic/tsconfig.json", fakes.version, version],
252+
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
253+
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, "src/tests/tsconfig.json", fakes.version, version],
254+
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"],
253255
);
254256
});
255257
});
@@ -508,6 +510,8 @@ class someClass { }`),
508510

509511
// build info
510512
"/src/core/tsconfig.tsbuildinfo",
513+
"/src/logic/tsconfig.tsbuildinfo",
514+
"/src/tests/tsconfig.tsbuildinfo",
511515
],
512516
)
513517
},
@@ -571,6 +575,7 @@ class someClass { }`),
571575
"/src/logic/decls/index.d.ts",
572576

573577
// build info
578+
"/src/core/tsconfig.tsbuildinfo",
574579
"/src/logic/tsconfig.tsbuildinfo",
575580
"/src/tests/tsconfig.tsbuildinfo",
576581

0 commit comments

Comments
 (0)