mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-16 07:13:43 -05:00
Added an errors summary for --pretty --watch results
Reports a "Found X error(s) across Y file(s)." message on each recompile if in both pretty and watch modes. This commit intentionally doesn't include tests as I have a few questions about implementation details. Will ask in PR first.
This commit is contained in:
@@ -3472,6 +3472,18 @@
|
||||
"category": "Message",
|
||||
"code": 6190
|
||||
},
|
||||
"Found 1 error in 1 file.": {
|
||||
"category": "Message",
|
||||
"code": 6191
|
||||
},
|
||||
"Found {0} errors in 1 file.": {
|
||||
"category": "Message",
|
||||
"code": 6192
|
||||
},
|
||||
"Found {0} errors in {1} files.": {
|
||||
"category": "Message",
|
||||
"code": 6193
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
@@ -144,7 +144,8 @@ namespace ts {
|
||||
enableStatistics(compilerOptions);
|
||||
|
||||
const program = createProgram(rootFileNames, compilerOptions, compilerHost);
|
||||
const exitStatus = emitFilesAndReportErrors(program, reportDiagnostic, s => sys.write(s + sys.newLine));
|
||||
const diagnosticsAndEmit = getProgramDiagnosticsAndEmit(program);
|
||||
const exitStatus = reportDiagnosticErrors(program, diagnosticsAndEmit, reportDiagnostic, s => sys.write(s + sys.newLine));
|
||||
reportStatistics(program);
|
||||
return sys.exit(exitStatus);
|
||||
}
|
||||
|
||||
@@ -31,11 +31,18 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
const nonClearingMessageCodes: number[] = [
|
||||
Diagnostics.Compilation_complete_Watching_for_file_changes.code,
|
||||
Diagnostics.Found_1_error_in_1_file.code,
|
||||
Diagnostics.Found_0_errors_in_1_file.code,
|
||||
Diagnostics.Found_0_errors_in_1_files.code,
|
||||
];
|
||||
|
||||
function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) {
|
||||
if (system.clearScreen &&
|
||||
diagnostic.code !== Diagnostics.Compilation_complete_Watching_for_file_changes.code &&
|
||||
!options.extendedDiagnostics &&
|
||||
!options.diagnostics) {
|
||||
!options.diagnostics &&
|
||||
!contains(nonClearingMessageCodes, diagnostic.code)) {
|
||||
system.clearScreen();
|
||||
}
|
||||
}
|
||||
@@ -120,10 +127,15 @@ namespace ts {
|
||||
emit(): EmitResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
|
||||
*/
|
||||
export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void) {
|
||||
/** @internal */
|
||||
export interface ProgramDiagnosticsAndEmit {
|
||||
diagnostics: Diagnostic[];
|
||||
emittedFiles: string[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getProgramDiagnosticsAndEmit(program: ProgramToEmitFilesAndReportErrors): ProgramDiagnosticsAndEmit {
|
||||
// First get and report any syntactic errors.
|
||||
const diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
let reportSemanticDiagnostics = false;
|
||||
@@ -147,6 +159,15 @@ namespace ts {
|
||||
addRange(diagnostics, program.getSemanticDiagnostics());
|
||||
}
|
||||
|
||||
return { diagnostics, emittedFiles, emitSkipped };
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
|
||||
*/
|
||||
export function reportDiagnosticErrors(program: ProgramToEmitFilesAndReportErrors, diagnosticsAndEmit: ProgramDiagnosticsAndEmit, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void) {
|
||||
const { diagnostics, emittedFiles, emitSkipped } = diagnosticsAndEmit;
|
||||
|
||||
sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
|
||||
if (writeFileName) {
|
||||
const currentDir = program.getCurrentDirectory();
|
||||
@@ -174,6 +195,34 @@ namespace ts {
|
||||
return ExitStatus.Success;
|
||||
}
|
||||
|
||||
function summarizeDiagnosticsAcrossFiles(diagnostics: Diagnostic[], reporter: WatchStatusReporter, newLine: string, compilerOptions: CompilerOptions): void {
|
||||
if (diagnostics.length === 1) {
|
||||
reporter(createCompilerDiagnostic(Diagnostics.Found_1_error_in_1_file), newLine, compilerOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
const uniqueFileNamesCount = countUniqueDiagnosticFileNames(diagnostics);
|
||||
|
||||
if (uniqueFileNamesCount === 1) {
|
||||
reporter(createCompilerDiagnostic(Diagnostics.Found_0_errors_in_1_file, diagnostics.length), newLine, compilerOptions);
|
||||
}
|
||||
else if (uniqueFileNamesCount !== 0) {
|
||||
reporter(createCompilerDiagnostic(Diagnostics.Found_0_errors_in_1_files, diagnostics.length, uniqueFileNamesCount), newLine, compilerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
function countUniqueDiagnosticFileNames(diagnostics: Diagnostic[]): number {
|
||||
const fileNames = createMap<boolean>();
|
||||
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.file) {
|
||||
fileNames.set(diagnostic.file.fileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
return fileNames.size;
|
||||
}
|
||||
|
||||
const noopFileWatcher: FileWatcher = { close: noop };
|
||||
|
||||
/**
|
||||
@@ -187,6 +236,7 @@ namespace ts {
|
||||
let host: DirectoryStructureHost = system;
|
||||
const useCaseSensitiveFileNames = () => system.useCaseSensitiveFileNames;
|
||||
const writeFileName = (s: string) => system.write(s + system.newLine);
|
||||
const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
|
||||
return {
|
||||
useCaseSensitiveFileNames,
|
||||
getNewLine: () => system.newLine,
|
||||
@@ -205,7 +255,7 @@ namespace ts {
|
||||
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout.call(system, callback, ms, ...args)) : noop,
|
||||
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout(timeoutId)) : noop,
|
||||
trace: s => system.write(s),
|
||||
onWatchStatusChange: reportWatchStatus || createWatchStatusReporter(system),
|
||||
onWatchStatusChange,
|
||||
createDirectory: path => system.createDirectory(path),
|
||||
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
|
||||
onCachedDirectoryStructureHostCreate: cacheHost => host = cacheHost || system,
|
||||
@@ -219,7 +269,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitFilesAndReportErrorUsingBuilder(builderProgram: BuilderProgram) {
|
||||
emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName);
|
||||
const diagnosticsAndEmit = getProgramDiagnosticsAndEmit(builderProgram);
|
||||
reportDiagnosticErrors(builderProgram, diagnosticsAndEmit, reportDiagnostic, writeFileName);
|
||||
|
||||
const compilerOptions = builderProgram.getCompilerOptions();
|
||||
if (compilerOptions.pretty) {
|
||||
summarizeDiagnosticsAcrossFiles(diagnosticsAndEmit.diagnostics, onWatchStatusChange, system.newLine, compilerOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user