Skip to content

Commit 26e546a

Browse files
authored
Merge pull request microsoft#29626 from Microsoft/toLowerCase
Handle get from readFileCache correctly.
2 parents e4f3b23 + 55b8e4f commit 26e546a

File tree

6 files changed

+118
-55
lines changed

6 files changed

+118
-55
lines changed

src/compiler/program.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,18 @@ namespace ts {
230230
const readFileWithCache = (fileName: string): string | undefined => {
231231
const key = toPath(fileName);
232232
const value = readFileCache.get(key);
233-
if (value !== undefined) return value || undefined;
233+
if (value !== undefined) return value !== false ? value : undefined;
234234
return setReadFileCache(key, fileName);
235235
};
236236
const setReadFileCache = (key: Path, fileName: string) => {
237237
const newValue = originalReadFile.call(host, fileName);
238-
readFileCache.set(key, newValue || false);
238+
readFileCache.set(key, newValue !== undefined ? newValue : false);
239239
return newValue;
240240
};
241241
host.readFile = fileName => {
242242
const key = toPath(fileName);
243243
const value = readFileCache.get(key);
244-
if (value !== undefined) return value; // could be .d.ts from output
244+
if (value !== undefined) return value !== false ? value : undefined; // could be .d.ts from output
245245
if (!fileExtensionIs(fileName, Extension.Json)) {
246246
return originalReadFile.call(host, fileName);
247247
}

src/harness/fakes.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ namespace fakes {
375375
}
376376
}
377377

378+
export type ExpectedDiagnostic = [ts.DiagnosticMessage, ...(string | number)[]];
379+
function expectedDiagnosticToText([message, ...args]: ExpectedDiagnostic) {
380+
let text = ts.getLocaleSpecificMessage(message);
381+
if (args.length) {
382+
text = ts.formatStringFromArgs(text, args);
383+
}
384+
return text;
385+
}
386+
378387
export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost<ts.BuilderProgram> {
379388
createProgram = ts.createAbstractBuilder;
380389
now() {
@@ -395,16 +404,10 @@ namespace fakes {
395404
this.diagnostics.length = 0;
396405
}
397406

398-
assertDiagnosticMessages(...expected: ts.DiagnosticMessage[]) {
399-
const actual = this.diagnostics.slice();
400-
if (actual.length !== expected.length) {
401-
assert.fail<any>(actual, expected, `Diagnostic arrays did not match - got\r\n${actual.map(a => " " + a.messageText).join("\r\n")}\r\nexpected\r\n${expected.map(e => " " + e.message).join("\r\n")}`);
402-
}
403-
for (let i = 0; i < actual.length; i++) {
404-
if (actual[i].code !== expected[i].code) {
405-
assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`);
406-
}
407-
}
407+
assertDiagnosticMessages(...expectedDiagnostics: ExpectedDiagnostic[]) {
408+
const actual = this.diagnostics.slice().map(d => d.messageText as string);
409+
const expected = expectedDiagnostics.map(expectedDiagnosticToText);
410+
assert.deepEqual(actual, expected, "Diagnostic arrays did not match");
408411
}
409412

410413
printDiagnostics(header = "== Diagnostics ==") {

src/testRunner/unittests/tsbuild.ts

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
namespace ts {
22
let currentTime = 100;
3+
4+
function getExpectedDiagnosticForProjectsInBuild(...projects: string[]): fakes.ExpectedDiagnostic {
5+
return [Diagnostics.Projects_in_this_build_Colon_0, projects.map(p => "\r\n * " + p).join("")];
6+
}
7+
38
export namespace Sample1 {
49
tick();
510
const projFs = loadProjectFromDisk("tests/projects/sample1");
@@ -67,7 +72,11 @@ namespace ts {
6772
const host = new fakes.SolutionBuilderHost(fs);
6873
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
6974
builder.buildAllProjects();
70-
host.assertDiagnosticMessages(Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0);
75+
host.assertDiagnosticMessages(
76+
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/core/tsconfig.json"],
77+
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/logic/tsconfig.json"],
78+
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/tests/tsconfig.json"]
79+
);
7180

7281
// Check for outputs to not be written. Not an exhaustive list
7382
for (const output of allExpectedOutputs) {
@@ -86,7 +95,11 @@ namespace ts {
8695
host.clearDiagnostics();
8796
builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
8897
builder.buildAllProjects();
89-
host.assertDiagnosticMessages(Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date);
98+
host.assertDiagnosticMessages(
99+
[Diagnostics.Project_0_is_up_to_date, "/src/core/tsconfig.json"],
100+
[Diagnostics.Project_0_is_up_to_date, "/src/logic/tsconfig.json"],
101+
[Diagnostics.Project_0_is_up_to_date, "/src/tests/tsconfig.json"]
102+
);
90103
});
91104
});
92105

@@ -146,13 +159,15 @@ namespace ts {
146159
host.clearDiagnostics();
147160
builder.resetBuildContext();
148161
builder.buildAllProjects();
149-
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
150-
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
151-
Diagnostics.Building_project_0,
152-
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
153-
Diagnostics.Building_project_0,
154-
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
155-
Diagnostics.Building_project_0);
162+
host.assertDiagnosticMessages(
163+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
164+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
165+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
166+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"],
167+
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
168+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"],
169+
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
170+
);
156171
tick();
157172
});
158173

@@ -161,10 +176,12 @@ namespace ts {
161176
host.clearDiagnostics();
162177
builder.resetBuildContext();
163178
builder.buildAllProjects();
164-
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
165-
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
166-
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
167-
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2);
179+
host.assertDiagnosticMessages(
180+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
181+
[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"],
182+
[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"],
183+
[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"]
184+
);
168185
tick();
169186
});
170187

@@ -175,11 +192,13 @@ namespace ts {
175192
builder.resetBuildContext();
176193
builder.buildAllProjects();
177194

178-
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
179-
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
180-
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
181-
Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2,
182-
Diagnostics.Building_project_0);
195+
host.assertDiagnosticMessages(
196+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
197+
[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"],
198+
[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"],
199+
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/index.ts"],
200+
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
201+
);
183202
tick();
184203
});
185204

@@ -190,13 +209,15 @@ namespace ts {
190209
builder.resetBuildContext();
191210
builder.buildAllProjects();
192211

193-
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
194-
Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2,
195-
Diagnostics.Building_project_0,
196-
Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies,
197-
Diagnostics.Updating_output_timestamps_of_project_0,
198-
Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies,
199-
Diagnostics.Updating_output_timestamps_of_project_0);
212+
host.assertDiagnosticMessages(
213+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
214+
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/core/tsconfig.json", "src/core/anotherModule.js", "src/core/index.ts"],
215+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
216+
[Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, "src/logic/tsconfig.json"],
217+
[Diagnostics.Updating_output_timestamps_of_project_0, "/src/logic/tsconfig.json"],
218+
[Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, "src/tests/tsconfig.json"],
219+
[Diagnostics.Updating_output_timestamps_of_project_0, "/src/tests/tsconfig.json"]
220+
);
200221
});
201222
});
202223

@@ -210,14 +231,14 @@ namespace ts {
210231
replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`);
211232
builder.buildAllProjects();
212233
host.assertDiagnosticMessages(
213-
Diagnostics.Projects_in_this_build_Colon_0,
214-
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
215-
Diagnostics.Building_project_0,
216-
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
217-
Diagnostics.Building_project_0,
218-
Diagnostics.Property_0_does_not_exist_on_type_1,
219-
Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors,
220-
Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors
234+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
235+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
236+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
237+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"],
238+
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
239+
[Diagnostics.Property_0_does_not_exist_on_type_1, "muitply", `typeof import("/src/core/index")`],
240+
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, "src/tests/tsconfig.json", "src/logic"],
241+
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, "/src/tests/tsconfig.json", "/src/logic"]
221242
);
222243
});
223244
});
@@ -281,12 +302,12 @@ export class cNew {}`);
281302
const projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite");
282303
const allExpectedOutputs = ["/src/tests/dist/src/index.js", "/src/tests/dist/src/index.d.ts", "/src/tests/dist/src/hello.json"];
283304

284-
function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: DiagnosticMessage[]) {
305+
function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: fakes.ExpectedDiagnostic[]) {
285306
const fs = projFs.shadow();
286307
verifyProjectWithResolveJsonModuleWithFs(fs, configFile, allExpectedOutputs, ...expectedDiagnosticMessages);
287308
}
288309

289-
function verifyProjectWithResolveJsonModuleWithFs(fs: vfs.FileSystem, configFile: string, allExpectedOutputs: ReadonlyArray<string>, ...expectedDiagnosticMessages: DiagnosticMessage[]) {
310+
function verifyProjectWithResolveJsonModuleWithFs(fs: vfs.FileSystem, configFile: string, allExpectedOutputs: ReadonlyArray<string>, ...expectedDiagnosticMessages: fakes.ExpectedDiagnostic[]) {
290311
const host = new fakes.SolutionBuilderHost(fs);
291312
const builder = createSolutionBuilder(host, [configFile], { dry: false, force: false, verbose: false });
292313
builder.buildAllProjects();
@@ -300,7 +321,10 @@ export class cNew {}`);
300321
}
301322

302323
it("with resolveJsonModule and include only", () => {
303-
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern);
324+
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", [
325+
Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern,
326+
"/src/tests/src/hello.json"
327+
]);
304328
});
305329

306330
it("with resolveJsonModule and include of *.json along with other include", () => {
@@ -415,7 +439,7 @@ export default hello.hello`);
415439
"/src/c.ts"
416440
];
417441

418-
function verifyBuild(modifyDiskLayout: (fs: vfs.FileSystem) => void, allExpectedOutputs: ReadonlyArray<string>, expectedDiagnostics: DiagnosticMessage[], expectedFileTraces: ReadonlyArray<string>) {
442+
function verifyBuild(modifyDiskLayout: (fs: vfs.FileSystem) => void, allExpectedOutputs: ReadonlyArray<string>, expectedFileTraces: ReadonlyArray<string>, ...expectedDiagnostics: fakes.ExpectedDiagnostic[]) {
419443
const fs = projFs.shadow();
420444
const host = new fakes.SolutionBuilderHost(fs);
421445
modifyDiskLayout(fs);
@@ -442,11 +466,11 @@ export const b = new A();`);
442466
}
443467

444468
it("verify that it builds correctly", () => {
445-
verifyBuild(noop, allExpectedOutputs, emptyArray, expectedFileTraces);
469+
verifyBuild(noop, allExpectedOutputs, expectedFileTraces);
446470
});
447471

448472
it("verify that it builds correctly when the referenced project uses different module resolution", () => {
449-
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "classic"), allExpectedOutputs, emptyArray, expectedFileTraces);
473+
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "classic"), allExpectedOutputs, expectedFileTraces);
450474
});
451475

452476
it("verify that it build reports error about module not found with node resolution with external module name", () => {
@@ -458,10 +482,25 @@ export const b = new A();`);
458482
];
459483
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "node"),
460484
allExpectedOutputs,
461-
[Diagnostics.Cannot_find_module_0],
462-
expectedFileTraces);
485+
expectedFileTraces,
486+
[Diagnostics.Cannot_find_module_0, "a"],
487+
);
463488
});
464489
});
490+
491+
it("unittests:: tsbuild - when tsconfig extends the missing file", () => {
492+
const projFs = loadProjectFromDisk("tests/projects/missingExtendedConfig");
493+
const fs = projFs.shadow();
494+
const host = new fakes.SolutionBuilderHost(fs);
495+
const builder = createSolutionBuilder(host, ["/src/tsconfig.json"], {});
496+
builder.buildAllProjects();
497+
host.assertDiagnosticMessages(
498+
[Diagnostics.The_specified_path_does_not_exist_Colon_0, "/src/foobar.json"],
499+
[Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, "/src/tsconfig.first.json", "[\"**/*\"]", "[]"],
500+
[Diagnostics.The_specified_path_does_not_exist_Colon_0, "/src/foobar.json"],
501+
[Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, "/src/tsconfig.second.json", "[\"**/*\"]", "[]"]
502+
);
503+
});
465504
}
466505

467506
export namespace OutFile {
@@ -564,7 +603,7 @@ export const b = new A();`);
564603

565604
host.clearDiagnostics();
566605
builder.buildAllProjects();
567-
host.assertDiagnosticMessages(Diagnostics.The_files_list_in_config_file_0_is_empty);
606+
host.assertDiagnosticMessages([Diagnostics.The_files_list_in_config_file_0_is_empty, "/src/no-references/tsconfig.json"]);
568607

569608
// Check for outputs to not be written.
570609
for (const output of allExpectedOutputs) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "./foobar.json",
3+
"compilerOptions": {
4+
"composite": true
5+
}
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true
4+
},
5+
"references": [
6+
{ "path": "./tsconfig.first.json" },
7+
{ "path": "./tsconfig.second.json" }
8+
]
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "./foobar.json",
3+
"compilerOptions": {
4+
"composite": true
5+
}
6+
}

0 commit comments

Comments
 (0)