@@ -31,11 +31,18 @@ namespace ts {
3131 } ;
3232 }
3333
34+ const nonClearingMessageCodes : number [ ] = [
35+ Diagnostics . Compilation_complete_Watching_for_file_changes . code ,
36+ Diagnostics . Found_1_error_in_1_file . code ,
37+ Diagnostics . Found_0_errors_in_1_file . code ,
38+ Diagnostics . Found_0_errors_in_1_files . code ,
39+ ] ;
40+
3441 function clearScreenIfNotWatchingForFileChanges ( system : System , diagnostic : Diagnostic , options : CompilerOptions ) {
3542 if ( system . clearScreen &&
36- diagnostic . code !== Diagnostics . Compilation_complete_Watching_for_file_changes . code &&
3743 ! options . extendedDiagnostics &&
38- ! options . diagnostics ) {
44+ ! options . diagnostics &&
45+ ! contains ( nonClearingMessageCodes , diagnostic . code ) ) {
3946 system . clearScreen ( ) ;
4047 }
4148 }
@@ -120,10 +127,15 @@ namespace ts {
120127 emit ( ) : EmitResult ;
121128 }
122129
123- /**
124- * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
125- */
126- export function emitFilesAndReportErrors ( program : ProgramToEmitFilesAndReportErrors , reportDiagnostic : DiagnosticReporter , writeFileName ?: ( s : string ) => void ) {
130+ /** @internal */
131+ export interface ProgramDiagnosticsAndEmit {
132+ diagnostics : Diagnostic [ ] ;
133+ emittedFiles : string [ ] ;
134+ emitSkipped : boolean ;
135+ }
136+
137+ /** @internal */
138+ export function getProgramDiagnosticsAndEmit ( program : ProgramToEmitFilesAndReportErrors ) : ProgramDiagnosticsAndEmit {
127139 // First get and report any syntactic errors.
128140 const diagnostics = program . getSyntacticDiagnostics ( ) . slice ( ) ;
129141 let reportSemanticDiagnostics = false ;
@@ -147,6 +159,15 @@ namespace ts {
147159 addRange ( diagnostics , program . getSemanticDiagnostics ( ) ) ;
148160 }
149161
162+ return { diagnostics, emittedFiles, emitSkipped } ;
163+ }
164+
165+ /**
166+ * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
167+ */
168+ export function reportDiagnosticErrors ( program : ProgramToEmitFilesAndReportErrors , diagnosticsAndEmit : ProgramDiagnosticsAndEmit , reportDiagnostic : DiagnosticReporter , writeFileName ?: ( s : string ) => void ) {
169+ const { diagnostics, emittedFiles, emitSkipped } = diagnosticsAndEmit ;
170+
150171 sortAndDeduplicateDiagnostics ( diagnostics ) . forEach ( reportDiagnostic ) ;
151172 if ( writeFileName ) {
152173 const currentDir = program . getCurrentDirectory ( ) ;
@@ -174,6 +195,34 @@ namespace ts {
174195 return ExitStatus . Success ;
175196 }
176197
198+ function summarizeDiagnosticsAcrossFiles ( diagnostics : Diagnostic [ ] , reporter : WatchStatusReporter , newLine : string , compilerOptions : CompilerOptions ) : void {
199+ if ( diagnostics . length === 1 ) {
200+ reporter ( createCompilerDiagnostic ( Diagnostics . Found_1_error_in_1_file ) , newLine , compilerOptions ) ;
201+ return ;
202+ }
203+
204+ const uniqueFileNamesCount = countUniqueDiagnosticFileNames ( diagnostics ) ;
205+
206+ if ( uniqueFileNamesCount === 1 ) {
207+ reporter ( createCompilerDiagnostic ( Diagnostics . Found_0_errors_in_1_file , diagnostics . length ) , newLine , compilerOptions ) ;
208+ }
209+ else if ( uniqueFileNamesCount !== 0 ) {
210+ reporter ( createCompilerDiagnostic ( Diagnostics . Found_0_errors_in_1_files , diagnostics . length , uniqueFileNamesCount ) , newLine , compilerOptions ) ;
211+ }
212+ }
213+
214+ function countUniqueDiagnosticFileNames ( diagnostics : Diagnostic [ ] ) : number {
215+ const fileNames = createMap < boolean > ( ) ;
216+
217+ for ( const diagnostic of diagnostics ) {
218+ if ( diagnostic . file ) {
219+ fileNames . set ( diagnostic . file . fileName , true ) ;
220+ }
221+ }
222+
223+ return fileNames . size ;
224+ }
225+
177226 const noopFileWatcher : FileWatcher = { close : noop } ;
178227
179228 /**
@@ -187,6 +236,7 @@ namespace ts {
187236 let host : DirectoryStructureHost = system ;
188237 const useCaseSensitiveFileNames = ( ) => system . useCaseSensitiveFileNames ;
189238 const writeFileName = ( s : string ) => system . write ( s + system . newLine ) ;
239+ const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter ( system ) ;
190240 return {
191241 useCaseSensitiveFileNames,
192242 getNewLine : ( ) => system . newLine ,
@@ -205,7 +255,7 @@ namespace ts {
205255 setTimeout : system . setTimeout ? ( ( callback , ms , ...args : any [ ] ) => system . setTimeout . call ( system , callback , ms , ...args ) ) : noop ,
206256 clearTimeout : system . clearTimeout ? ( timeoutId => system . clearTimeout ( timeoutId ) ) : noop ,
207257 trace : s => system . write ( s ) ,
208- onWatchStatusChange : reportWatchStatus || createWatchStatusReporter ( system ) ,
258+ onWatchStatusChange,
209259 createDirectory : path => system . createDirectory ( path ) ,
210260 writeFile : ( path , data , writeByteOrderMark ) => system . writeFile ( path , data , writeByteOrderMark ) ,
211261 onCachedDirectoryStructureHostCreate : cacheHost => host = cacheHost || system ,
@@ -219,7 +269,13 @@ namespace ts {
219269 }
220270
221271 function emitFilesAndReportErrorUsingBuilder ( builderProgram : BuilderProgram ) {
222- emitFilesAndReportErrors ( builderProgram , reportDiagnostic , writeFileName ) ;
272+ const diagnosticsAndEmit = getProgramDiagnosticsAndEmit ( builderProgram ) ;
273+ reportDiagnosticErrors ( builderProgram , diagnosticsAndEmit , reportDiagnostic , writeFileName ) ;
274+
275+ const compilerOptions = builderProgram . getCompilerOptions ( ) ;
276+ if ( compilerOptions . pretty ) {
277+ summarizeDiagnosticsAcrossFiles ( diagnosticsAndEmit . diagnostics , onWatchStatusChange , system . newLine , compilerOptions ) ;
278+ }
223279 }
224280 }
225281
0 commit comments