Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dedb2ae

Browse filesBrowse files
committed
Combine buildHost methods into SolutionBuilderHost's reportDiagnostic and reportStatus
1 parent 26b4b6c commit dedb2ae
Copy full SHA for dedb2ae

5 files changed

+132-138Lines changed: 132 additions & 138 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/tsbuild.ts‎

Copy file name to clipboardExpand all lines: src/compiler/tsbuild.ts
+41-25Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -392,21 +392,37 @@ namespace ts {
392392
getModifiedTime(fileName: string): Date | undefined;
393393
setModifiedTime(fileName: string, date: Date): void;
394394
deleteFile(fileName: string): void;
395+
396+
reportDiagnostic: DiagnosticReporter; // Technically we want to move it out and allow steps of actions on Solution, but for now just merge stuff in build host here
397+
reportSolutionBuilderStatus: DiagnosticReporter;
395398
}
396399

397400
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost, WatchHost {
398401
}
399402

400-
export function createSolutionBuilderHost(system = sys) {
403+
/**
404+
* Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
405+
*/
406+
export function createBuilderStatusReporter(system: System, pretty?: boolean): DiagnosticReporter {
407+
return diagnostic => {
408+
let output = pretty ? `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] ` : `${new Date().toLocaleTimeString()} - `;
409+
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${system.newLine + system.newLine}`;
410+
system.write(output);
411+
};
412+
}
413+
414+
export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
401415
const host = createCompilerHost({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost;
402416
host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined;
403417
host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop;
404418
host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop;
419+
host.reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
420+
host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system);
405421
return host;
406422
}
407423

408-
export function createSolutionBuilderWithWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter) {
409-
const host = createSolutionBuilderHost(system) as SolutionBuilderWithWatchHost;
424+
export function createSolutionBuilderWithWatchHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) {
425+
const host = createSolutionBuilderHost(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost;
410426
const watchHost = createWatchHost(system, reportWatchStatus);
411427
host.onWatchStatusChange = watchHost.onWatchStatusChange;
412428
host.watchFile = watchHost.watchFile;
@@ -422,7 +438,7 @@ namespace ts {
422438
* TODO: use SolutionBuilderWithWatchHost => watchedSolution
423439
* use SolutionBuilderHost => Solution
424440
*/
425-
export function createSolutionBuilder(host: SolutionBuilderHost, buildHost: BuildHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions) {
441+
export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions) {
426442
const hostWithWatch = host as SolutionBuilderWithWatchHost;
427443
const configFileCache = createConfigFileCache(host);
428444
let context = createBuildContext(defaultOptions);
@@ -445,6 +461,10 @@ namespace ts {
445461
startWatching
446462
};
447463

464+
function reportStatus(message: DiagnosticMessage, ...args: string[]) {
465+
host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args));
466+
}
467+
448468
function startWatching() {
449469
const graph = getGlobalDependencyGraph()!;
450470
if (!graph.buildQueue) {
@@ -743,7 +763,7 @@ namespace ts {
743763
verboseReportProjectStatus(next, status);
744764

745765
if (status.type === UpToDateStatusType.UpstreamBlocked) {
746-
if (context.options.verbose) buildHost.verbose(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName);
766+
if (context.options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName);
747767
continue;
748768
}
749769

@@ -780,7 +800,7 @@ namespace ts {
780800
if (temporaryMarks[projPath]) {
781801
if (!inCircularContext) {
782802
hadError = true;
783-
buildHost.error(Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n"));
803+
reportStatus(Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n"));
784804
return;
785805
}
786806
}
@@ -812,11 +832,11 @@ namespace ts {
812832

813833
function buildSingleProject(proj: ResolvedConfigFileName): BuildResultFlags {
814834
if (context.options.dry) {
815-
buildHost.message(Diagnostics.A_non_dry_build_would_build_project_0, proj);
835+
reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj);
816836
return BuildResultFlags.Success;
817837
}
818838

819-
if (context.options.verbose) buildHost.verbose(Diagnostics.Building_project_0, proj);
839+
if (context.options.verbose) reportStatus(Diagnostics.Building_project_0, proj);
820840

821841
let resultFlags = BuildResultFlags.None;
822842
resultFlags |= BuildResultFlags.DeclarationOutputUnchanged;
@@ -850,7 +870,7 @@ namespace ts {
850870
if (syntaxDiagnostics.length) {
851871
resultFlags |= BuildResultFlags.SyntaxErrors;
852872
for (const diag of syntaxDiagnostics) {
853-
buildHost.errorDiagnostic(diag);
873+
host.reportDiagnostic(diag);
854874
}
855875
context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Syntactic errors" });
856876
return resultFlags;
@@ -862,7 +882,7 @@ namespace ts {
862882
if (declDiagnostics.length) {
863883
resultFlags |= BuildResultFlags.DeclarationEmitErrors;
864884
for (const diag of declDiagnostics) {
865-
buildHost.errorDiagnostic(diag);
885+
host.reportDiagnostic(diag);
866886
}
867887
context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Declaration file errors" });
868888
return resultFlags;
@@ -874,7 +894,7 @@ namespace ts {
874894
if (semanticDiagnostics.length) {
875895
resultFlags |= BuildResultFlags.TypeErrors;
876896
for (const diag of semanticDiagnostics) {
877-
buildHost.errorDiagnostic(diag);
897+
host.reportDiagnostic(diag);
878898
}
879899
context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Semantic errors" });
880900
return resultFlags;
@@ -913,11 +933,11 @@ namespace ts {
913933

914934
function updateOutputTimestamps(proj: ParsedCommandLine) {
915935
if (context.options.dry) {
916-
return buildHost.message(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!);
936+
return reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!);
917937
}
918938

919939
if (context.options.verbose) {
920-
buildHost.verbose(Diagnostics.Updating_output_timestamps_of_project_0, proj.options.configFilePath!);
940+
reportStatus(Diagnostics.Updating_output_timestamps_of_project_0, proj.options.configFilePath!);
921941
}
922942

923943
const now = new Date();
@@ -970,18 +990,18 @@ namespace ts {
970990
function cleanAllProjects() {
971991
const resolvedNames: ReadonlyArray<ResolvedConfigFileName> | undefined = getAllProjectsInScope();
972992
if (resolvedNames === undefined) {
973-
buildHost.message(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located);
993+
reportStatus(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located);
974994
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
975995
}
976996

977997
const filesToDelete = getFilesToClean(resolvedNames);
978998
if (filesToDelete === undefined) {
979-
buildHost.message(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located);
999+
reportStatus(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located);
9801000
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
9811001
}
9821002

9831003
if (context.options.dry) {
984-
buildHost.message(Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(f => `\r\n * ${f}`).join(""));
1004+
reportStatus(Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(f => `\r\n * ${f}`).join(""));
9851005
return ExitStatus.Success;
9861006
}
9871007

@@ -1001,7 +1021,7 @@ namespace ts {
10011021
if (host.fileExists(fullPathWithTsconfig)) {
10021022
return fullPathWithTsconfig as ResolvedConfigFileName;
10031023
}
1004-
buildHost.error(Diagnostics.File_0_not_found, relName(fullPath));
1024+
host.reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_not_found, relName(fullPath)));
10051025
return undefined;
10061026
}
10071027

@@ -1039,7 +1059,7 @@ namespace ts {
10391059
// Up to date, skip
10401060
if (defaultOptions.dry) {
10411061
// In a dry build, inform the user of this fact
1042-
buildHost.message(Diagnostics.Project_0_is_up_to_date, projName);
1062+
reportStatus(Diagnostics.Project_0_is_up_to_date, projName);
10431063
}
10441064
continue;
10451065
}
@@ -1051,7 +1071,7 @@ namespace ts {
10511071
}
10521072

10531073
if (status.type === UpToDateStatusType.UpstreamBlocked) {
1054-
if (context.options.verbose) buildHost.verbose(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
1074+
if (context.options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
10551075
continue;
10561076
}
10571077

@@ -1076,23 +1096,19 @@ namespace ts {
10761096
for (const name of graph.buildQueue) {
10771097
names.push(name);
10781098
}
1079-
if (context.options.verbose) buildHost.verbose(Diagnostics.Projects_in_this_build_Colon_0, names.map(s => "\r\n * " + relName(s)).join(""));
1099+
if (context.options.verbose) reportStatus(Diagnostics.Projects_in_this_build_Colon_0, names.map(s => "\r\n * " + relName(s)).join(""));
10801100
}
10811101

10821102
function relName(path: string): string {
10831103
return convertToRelativePath(path, host.getCurrentDirectory(), f => host.getCanonicalFileName(f));
10841104
}
10851105

1086-
function reportVerbose(message: DiagnosticMessage, ...args: string[]) {
1087-
buildHost.verbose(message, ...args);
1088-
}
1089-
10901106
/**
10911107
* Report the up-to-date status of a project if we're in verbose mode
10921108
*/
10931109
function verboseReportProjectStatus(configFileName: string, status: UpToDateStatus) {
10941110
if (!context.options.verbose) return;
1095-
return formatUpToDateStatus(configFileName, status, relName, reportVerbose);
1111+
return formatUpToDateStatus(configFileName, status, relName, reportStatus);
10961112
}
10971113
}
10981114

Collapse file

‎src/harness/fakes.ts‎

Copy file name to clipboardExpand all lines: src/harness/fakes.ts
+37-1Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ namespace fakes {
205205
/**
206206
* A fake `ts.CompilerHost` that leverages a virtual file system.
207207
*/
208-
export class CompilerHost implements ts.CompilerHost, ts.SolutionBuilderHost {
208+
export class CompilerHost implements ts.CompilerHost {
209209
public readonly sys: System;
210210
public readonly defaultLibLocation: string;
211211
public readonly outputs: documents.TextDocument[] = [];
@@ -374,5 +374,41 @@ namespace fakes {
374374
return parsed;
375375
}
376376
}
377+
378+
export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost {
379+
diagnostics: ts.Diagnostic[] = [];
380+
381+
reportDiagnostic(diagnostic: ts.Diagnostic) {
382+
this.diagnostics.push(diagnostic);
383+
}
384+
385+
reportSolutionBuilderStatus(diagnostic: ts.Diagnostic) {
386+
this.diagnostics.push(diagnostic);
387+
}
388+
389+
clearDiagnostics() {
390+
this.diagnostics.length = 0;
391+
}
392+
393+
assertDiagnosticMessages(...expected: ts.DiagnosticMessage[]) {
394+
const actual = this.diagnostics.slice();
395+
if (actual.length !== expected.length) {
396+
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")}`);
397+
}
398+
for (let i = 0; i < actual.length; i++) {
399+
if (actual[i].code !== expected[i].code) {
400+
assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`);
401+
}
402+
}
403+
}
404+
405+
printDiagnostics(header = "== Diagnostics ==") {
406+
const out = ts.createDiagnosticReporter(ts.sys);
407+
ts.sys.write(header + "\r\n");
408+
for (const d of this.diagnostics) {
409+
out(d);
410+
}
411+
}
412+
}
377413
}
378414

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.