Report error summary in pretty mode during normal compilation

This commit is contained in:
Sheetal Nandi 2018-11-01 10:12:46 -07:00
parent c780186a92
commit 77ef9cedab
18 changed files with 134 additions and 53 deletions

View File

@ -104,6 +104,13 @@ namespace ts {
category: Diagnostics.Advanced_Options,
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
},
{
name: "pretty",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
},
{
name: "traceResolution",
@ -157,13 +164,6 @@ namespace ts {
category: Diagnostics.Command_line_Options,
description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
},
{
name: "pretty",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
},
{
name: "showConfig",
type: "boolean",

View File

@ -3771,6 +3771,14 @@
"category": "Message",
"code": 6215
},
"Found 1 error.": {
"category": "Message",
"code": 6216
},
"Found {0} errors.": {
"category": "Message",
"code": 6217
},
"Projects to reference": {
"category": "Message",

View File

@ -29,6 +29,9 @@ namespace ts {
preserveWatchOutput?: boolean;
listEmittedFiles?: boolean;
listFiles?: boolean;
pretty?: boolean;
traceResolution?: boolean;
}
enum BuildResultFlags {
@ -316,7 +319,7 @@ namespace ts {
return fileExtensionIs(fileName, Extension.Dts);
}
export interface SolutionBuilderHost extends CompilerHost {
export interface SolutionBuilderHostBase extends CompilerHost {
getModifiedTime(fileName: string): Date | undefined;
setModifiedTime(fileName: string, date: Date): void;
deleteFile(fileName: string): void;
@ -325,13 +328,18 @@ namespace ts {
reportSolutionBuilderStatus: DiagnosticReporter;
}
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost, WatchHost {
export interface SolutionBuilderHost extends SolutionBuilderHostBase {
reportErrorSummary?: ReportEmitErrorSummary;
}
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHostBase, WatchHost {
}
export interface SolutionBuilder {
buildAllProjects(): ExitStatus;
cleanAllProjects(): ExitStatus;
// TODO:: All the below ones should technically only be in watch mode. but thats for later time
/*@internal*/ resolveProjectName(name: string): ResolvedConfigFileName;
/*@internal*/ getUpToDateStatusOfFile(configFileName: ResolvedConfigFileName): UpToDateStatus;
/*@internal*/ getBuildGraph(configFileNames: ReadonlyArray<string>): DependencyGraph;
@ -340,7 +348,9 @@ namespace ts {
/*@internal*/ buildInvalidatedProject(): void;
/*@internal*/ resetBuildContext(opts?: BuildOptions): void;
}
export interface SolutionBuilderWithWatch extends SolutionBuilder {
/*@internal*/ startWatching(): void;
}
@ -355,8 +365,8 @@ namespace ts {
};
}
export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
const host = createCompilerHostWorker({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost;
function createSolutionBuilderHostBase(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
const host = createCompilerHostWorker({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHostBase;
host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined;
host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop;
host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop;
@ -365,8 +375,14 @@ namespace ts {
return host;
}
export function createSolutionBuilderWithWatchHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) {
const host = createSolutionBuilderHost(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost;
export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportErrorSummary?: ReportEmitErrorSummary) {
const host = createSolutionBuilderHostBase(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderHost;
host.reportErrorSummary = reportErrorSummary;
return host;
}
export function createSolutionBuilderWithWatchHost(system?: System, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) {
const host = createSolutionBuilderHostBase(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost;
const watchHost = createWatchHost(system, reportWatchStatus);
host.onWatchStatusChange = watchHost.onWatchStatusChange;
host.watchFile = watchHost.watchFile;
@ -390,7 +406,9 @@ namespace ts {
* TODO: use SolutionBuilderWithWatchHost => watchedSolution
* use SolutionBuilderHost => Solution
*/
export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder {
export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder;
export function createSolutionBuilder(host: SolutionBuilderWithWatchHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilderWithWatch;
export function createSolutionBuilder(host: SolutionBuilderHost | SolutionBuilderWithWatchHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilderWithWatch {
const hostWithWatch = host as SolutionBuilderWithWatchHost;
const currentDirectory = host.getCurrentDirectory();
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
@ -803,9 +821,7 @@ namespace ts {
globalDependencyGraph = undefined;
}
projectStatus.removeKey(resolved);
if (options.watch) {
diagnostics.removeKey(resolved);
}
diagnostics.removeKey(resolved);
addProjToQueue(resolved, reloadLevel);
}
@ -874,7 +890,7 @@ namespace ts {
}
function reportErrorSummary() {
if (options.watch) {
if (options.watch || (host as SolutionBuilderHost).reportErrorSummary) {
// Report errors from the other projects
getGlobalDependencyGraph().buildQueue.forEach(project => {
if (!projectErrorsReported.hasKey(project)) {
@ -882,8 +898,13 @@ namespace ts {
}
});
let totalErrors = 0;
diagnostics.forEach(singleProjectErrors => totalErrors += singleProjectErrors.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
reportWatchStatus(totalErrors === 1 ? Diagnostics.Found_1_error_Watching_for_file_changes : Diagnostics.Found_0_errors_Watching_for_file_changes, totalErrors);
diagnostics.forEach(singleProjectErrors => totalErrors += getErrorCountForSummary(singleProjectErrors));
if (options.watch) {
reportWatchStatus(getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
}
else {
(host as SolutionBuilderHost).reportErrorSummary!(totalErrors);
}
}
}
@ -1066,9 +1087,7 @@ namespace ts {
type: UpToDateStatusType.UpToDate,
newestDeclarationFileContentChangedTime: anyDtsChanged ? maximumDate : newestDeclarationFileContentChangedTime
};
if (options.watch) {
diagnostics.removeKey(proj);
}
diagnostics.removeKey(proj);
projectStatus.setValue(proj, status);
return resultFlags;
@ -1207,10 +1226,8 @@ namespace ts {
function reportAndStoreErrors(proj: ResolvedConfigFileName, errors: ReadonlyArray<Diagnostic>) {
reportErrors(errors);
if (options.watch) {
projectErrorsReported.setValue(proj, true);
diagnostics.setValue(proj, errors);
}
projectErrorsReported.setValue(proj, true);
diagnostics.setValue(proj, errors);
}
function reportErrors(errors: ReadonlyArray<Diagnostic>) {

View File

@ -106,6 +106,21 @@ namespace ts {
export type ReportEmitErrorSummary = (errorCount: number) => void;
export function getErrorCountForSummary(diagnostics: ReadonlyArray<Diagnostic>) {
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
}
export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) {
return errorCount === 1 ?
Diagnostics.Found_1_error_Watching_for_file_changes :
Diagnostics.Found_0_errors_Watching_for_file_changes;
}
export function getErrorSummaryText(errorCount: number, newLine: string) {
const d = createCompilerDiagnostic(errorCount === 1 ? Diagnostics.Found_1_error : Diagnostics.Found_0_errors, errorCount);
return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`;
}
/**
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
*/
@ -151,7 +166,7 @@ namespace ts {
}
if (reportSummary) {
reportSummary(diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
reportSummary(getErrorCountForSummary(diagnostics));
}
if (emitSkipped && diagnostics.length > 0) {
@ -227,16 +242,16 @@ namespace ts {
const compilerOptions = builderProgram.getCompilerOptions();
const newLine = getNewLineCharacter(compilerOptions, () => system.newLine);
const reportSummary = (errorCount: number) => {
if (errorCount === 1) {
onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions);
}
else {
onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions);
}
};
emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, reportSummary);
emitFilesAndReportErrors(
builderProgram,
reportDiagnostic,
writeFileName,
errorCount => onWatchStatusChange!(
createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount),
newLine,
compilerOptions
)
);
}
}

View File

@ -1325,6 +1325,9 @@ namespace Harness {
const [, content] = value;
outputLines += content;
}
if (pretty) {
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), IO.newLine());
}
return outputLines;
}

View File

@ -200,19 +200,28 @@ namespace ts {
}
// TODO: change this to host if watch => watchHost otherwiue without wathc
const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()), projects, buildOptions);
const builder = createSolutionBuilder(buildOptions.watch ?
createSolutionBuilderWithWatchHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()) :
createSolutionBuilderHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createReportErrorSummary(buildOptions)),
projects, buildOptions);
if (buildOptions.clean) {
return sys.exit(builder.cleanAllProjects());
}
if (buildOptions.watch) {
builder.buildAllProjects();
return builder.startWatching();
return (builder as SolutionBuilderWithWatch).startWatching();
}
return sys.exit(builder.buildAllProjects());
}
function createReportErrorSummary(options: CompilerOptions | BuildOptions): ReportEmitErrorSummary | undefined {
return shouldBePretty(options) ?
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine)) :
undefined;
}
function performCompilation(rootNames: string[], projectReferences: ReadonlyArray<ProjectReference> | undefined, options: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
const host = createCompilerHost(options);
enableStatistics(options);
@ -225,7 +234,12 @@ namespace ts {
configFileParsingDiagnostics
};
const program = createProgram(programOptions);
const exitStatus = emitFilesAndReportErrors(program, reportDiagnostic, s => sys.write(s + sys.newLine));
const exitStatus = emitFilesAndReportErrors(
program,
reportDiagnostic,
s => sys.write(s + sys.newLine),
createReportErrorSummary(options)
);
reportStatistics(program);
return sys.exit(exitStatus);
}

View File

@ -58,4 +58,6 @@
}
}
}
Found 2 errors.

View File

@ -91,4 +91,6 @@
~~~
!!! error TS2451: Cannot redeclare block-scoped variable 'Bar'.
!!! related TS6203 tests/cases/compiler/file1.ts:2:7: 'Bar' was also declared here.
Found 6 errors.

View File

@ -44,4 +44,6 @@
class G { }
class H { }
class I { }
Found 2 errors.

View File

@ -84,4 +84,6 @@
!!! error TS2300: Duplicate identifier 'duplicate3'.
!!! related TS6203 tests/cases/compiler/file1.ts:4:5: 'duplicate3' was also declared here.
}
Found 6 errors.

View File

@ -46,4 +46,6 @@
duplicate7(): number;
duplicate8(): number;
}
Found 2 errors.

View File

@ -91,4 +91,6 @@
}
}
export {}
Found 6 errors.

View File

@ -91,4 +91,6 @@
!!! error TS2300: Duplicate identifier 'duplicate3'.
!!! related TS6203 tests/cases/compiler/file2.ts:7:9: 'duplicate3' was also declared here.
}
}
}
Found 6 errors.

View File

@ -55,4 +55,6 @@
duplicate8: () => string;
duplicate9: () => string;
}
}
}
Found 2 errors.

View File

@ -22,4 +22,6 @@
!!! error TS2345: Argument of type '{ default: () => void; }' is not assignable to parameter of type '() => void'.
!!! error TS2345: Type '{ default: () => void; }' provides no match for the signature '(): void'.
!!! related TS7038 tests/cases/compiler/index.ts:1:1: Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.
Found 1 error.

View File

@ -20,4 +20,6 @@
!!! error TS2322: Type '{ a: { b: string; }; }' is not assignable to type '{ c: string; }'.
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ c: string; }'.
};
Found 1 error.

View File

@ -8,4 +8,6 @@
if (true) {
!!! error TS1005: '}' expected.
!!! error TS1005: '}' expected.
Found 1 error.

View File

@ -55,4 +55,6 @@
~~~
!!! error TS2451: Cannot redeclare block-scoped variable 'Bar'.
!!! related TS6203 tests/cases/conformance/jsdoc/mod1.js:2:7: 'Bar' was also declared here.
Found 4 errors.