Skip to content

Commit 0638417

Browse files
committed
Improve error report summaries (#45713)
1 parent 8894262 commit 0638417

File tree

47 files changed

+155
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+155
-99
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,6 +4834,18 @@
48344834
"category": "Message",
48354835
"code": 6257
48364836
},
4837+
"Found 1 error in {1}": {
4838+
"category": "Message",
4839+
"code": 6258
4840+
},
4841+
"Found {0} errors in 1 file.": {
4842+
"category": "Message",
4843+
"code": 6259
4844+
},
4845+
"Found {0} errors in {1} files.": {
4846+
"category": "Message",
4847+
"code": 6260
4848+
},
48374849

48384850
"Enable project compilation": {
48394851
"category": "Message",

src/compiler/tsbuildPublic.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace ts {
7676
return fileExtensionIs(fileName, Extension.Dts);
7777
}
7878

79-
export type ReportEmitErrorSummary = (errorCount: number) => void;
79+
export type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
8080

8181
export interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
8282
createDirectory?(path: string): void;
@@ -2002,10 +2002,12 @@ namespace ts {
20022002
const canReportSummary = state.watch || !!state.host.reportErrorSummary;
20032003
const { diagnostics } = state;
20042004
let totalErrors = 0;
2005+
let filesInError: (string | undefined)[] = [];
20052006
if (isCircularBuildOrder(buildOrder)) {
20062007
reportBuildQueue(state, buildOrder.buildOrder);
20072008
reportErrors(state, buildOrder.circularDiagnostics);
20082009
if (canReportSummary) totalErrors += getErrorCountForSummary(buildOrder.circularDiagnostics);
2010+
if (canReportSummary) filesInError = [...filesInError, ...getFilesInErrorForSummary(buildOrder.circularDiagnostics)];
20092011
}
20102012
else {
20112013
// Report errors from the other projects
@@ -2016,13 +2018,14 @@ namespace ts {
20162018
}
20172019
});
20182020
if (canReportSummary) diagnostics.forEach(singleProjectErrors => totalErrors += getErrorCountForSummary(singleProjectErrors));
2021+
if (canReportSummary) diagnostics.forEach(singleProjectErrors => [...filesInError, ...getFilesInErrorForSummary(singleProjectErrors)]);
20192022
}
20202023

20212024
if (state.watch) {
20222025
reportWatchStatus(state, getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
20232026
}
20242027
else if (state.host.reportErrorSummary) {
2025-
state.host.reportErrorSummary(totalErrors);
2028+
state.host.reportErrorSummary(totalErrors, filesInError);
20262029
}
20272030
}
20282031

src/compiler/watch.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace ts {
77
} : undefined;
88

99
/**
10-
* Create a function that reports error by writing to the system and handles the formating of the diagnostic
10+
* Create a function that reports error by writing to the system and handles the formatting of the diagnostic
1111
*/
1212
export function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter {
1313
const host: FormatDiagnosticsHost = system === sys && sysFormatDiagnosticsHost ? sysFormatDiagnosticsHost : {
@@ -101,15 +101,51 @@ namespace ts {
101101
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
102102
}
103103

104+
export function getFilesInErrorForSummary(diagnostics: readonly Diagnostic[]) {
105+
return filter(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error)
106+
.map(
107+
errorDiagnostic => {
108+
if(errorDiagnostic.file === undefined) return;
109+
return `${errorDiagnostic.file.fileName}`;
110+
})
111+
.filter((value, index, self) => self !== undefined && self.indexOf(value) === index)
112+
.map((fileName: string) => {
113+
const diagnosticForFileName = find(diagnostics, diagnostic =>
114+
diagnostic.file !== undefined && diagnostic.file.fileName === fileName
115+
);
116+
117+
if(diagnosticForFileName !== undefined) {
118+
const { line } = getLineAndCharacterOfPosition(diagnosticForFileName.file!, diagnosticForFileName.start!);
119+
return `${fileName}:${line + 1}`;
120+
}
121+
});
122+
}
123+
104124
export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) {
105125
return errorCount === 1 ?
106126
Diagnostics.Found_1_error_Watching_for_file_changes :
107127
Diagnostics.Found_0_errors_Watching_for_file_changes;
108128
}
109129

110-
export function getErrorSummaryText(errorCount: number, newLine: string) {
130+
export function getErrorSummaryText(
131+
errorCount: number,
132+
filesInError: readonly (string | undefined)[],
133+
newLine: string
134+
) {
111135
if (errorCount === 0) return "";
112-
const d = createCompilerDiagnostic(errorCount === 1 ? Diagnostics.Found_1_error : Diagnostics.Found_0_errors, errorCount);
136+
const d = errorCount === 1 ?
137+
createCompilerDiagnostic(
138+
filesInError[0] !== undefined ?
139+
Diagnostics.Found_1_error_in_1 :
140+
Diagnostics.Found_1_error,
141+
errorCount,
142+
filesInError[0]) :
143+
createCompilerDiagnostic(
144+
filesInError.length === 1 ?
145+
Diagnostics.Found_0_errors_in_1_file :
146+
Diagnostics.Found_0_errors_in_1_files,
147+
errorCount,
148+
filesInError.length);
113149
return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`;
114150
}
115151

@@ -350,7 +386,7 @@ namespace ts {
350386
}
351387

352388
if (reportSummary) {
353-
reportSummary(getErrorCountForSummary(diagnostics));
389+
reportSummary(getErrorCountForSummary(diagnostics), getFilesInErrorForSummary(diagnostics));
354390
}
355391

356392
return {
@@ -656,7 +692,7 @@ namespace ts {
656692
builderProgram,
657693
input.reportDiagnostic || createDiagnosticReporter(system),
658694
s => host.trace && host.trace(s),
659-
input.reportErrorSummary || input.options.pretty ? errorCount => system.write(getErrorSummaryText(errorCount, system.newLine)) : undefined
695+
input.reportErrorSummary || input.options.pretty ? (errorCount, filesInError) => system.write(getErrorSummaryText(errorCount, filesInError, system.newLine)) : undefined
660696
);
661697
if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
662698
return exitStatus;

src/executeCommandLine/executeCommandLine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ namespace ts {
749749

750750
function createReportErrorSummary(sys: System, options: CompilerOptions | BuildOptions): ReportEmitErrorSummary | undefined {
751751
return shouldBePretty(sys, options) ?
752-
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine)) :
752+
(errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine)) :
753753
undefined;
754754
}
755755

src/harness/harnessIO.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ namespace Harness {
536536
outputLines += content;
537537
}
538538
if (pretty) {
539-
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), IO.newLine());
539+
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), ts.getFilesInErrorForSummary(diagnostics), IO.newLine());
540540
}
541541
return outputLines;
542542
}

src/testRunner/unittests/tsbuild/publicApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function f22() { } // trailing`,
5454
/*createProgram*/ undefined,
5555
createDiagnosticReporter(sys, /*pretty*/ true),
5656
createBuilderStatusReporter(sys, /*pretty*/ true),
57-
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine))
57+
(errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine))
5858
);
5959
buildHost.afterProgramEmitAndDiagnostics = cb;
6060
buildHost.afterEmitBundle = cb;

src/testRunner/unittests/tscWatch/helpers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,18 @@ namespace ts.tscWatch {
204204
assert.equal(host.exitCode, expectedExitCode);
205205
}
206206

207-
export function checkNormalBuildErrors(host: WatchedSystem, errors: readonly Diagnostic[] | readonly string[], reportErrorSummary?: boolean) {
207+
export function checkNormalBuildErrors(
208+
host: WatchedSystem,
209+
errors: readonly Diagnostic[] | readonly string[],
210+
files: readonly string[],
211+
reportErrorSummary?: boolean
212+
) {
208213
checkOutputErrors(
209214
host,
210215
[
211216
...map(errors, hostOutputDiagnostic),
212217
...reportErrorSummary ?
213-
[hostOutputWatchDiagnostic(getErrorSummaryText(errors.length, host.newLine))] :
218+
[hostOutputWatchDiagnostic(getErrorSummaryText(errors.length, files, host.newLine))] :
214219
emptyArray
215220
]
216221
);

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5249,7 +5249,7 @@ declare namespace ts {
52495249
traceResolution?: boolean;
52505250
[option: string]: CompilerOptionsValue | undefined;
52515251
}
5252-
type ReportEmitErrorSummary = (errorCount: number) => void;
5252+
type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
52535253
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
52545254
createDirectory?(path: string): void;
52555255
/**

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5249,7 +5249,7 @@ declare namespace ts {
52495249
traceResolution?: boolean;
52505250
[option: string]: CompilerOptionsValue | undefined;
52515251
}
5252-
type ReportEmitErrorSummary = (errorCount: number) => void;
5252+
type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
52535253
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
52545254
createDirectory?(path: string): void;
52555255
/**

tests/baselines/reference/deeplyNestedAssignabilityIssue.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@
6565
}
6666
}
6767

68-
Found 2 errors.
68+
Found 2 errors in 1 file.
6969

0 commit comments

Comments
 (0)