@@ -7,7 +7,7 @@ namespace ts {
7
7
} : undefined ;
8
8
9
9
/**
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
11
11
*/
12
12
export function createDiagnosticReporter ( system : System , pretty ?: boolean ) : DiagnosticReporter {
13
13
const host : FormatDiagnosticsHost = system === sys && sysFormatDiagnosticsHost ? sysFormatDiagnosticsHost : {
@@ -101,16 +101,87 @@ namespace ts {
101
101
return countWhere ( diagnostics , diagnostic => diagnostic . category === DiagnosticCategory . Error ) ;
102
102
}
103
103
104
+ export function getFilesInErrorForSummary ( diagnostics : readonly Diagnostic [ ] ) : ( ReportFileInError | undefined ) [ ] {
105
+ const filesInError =
106
+ filter ( diagnostics , diagnostic => diagnostic . category === DiagnosticCategory . Error )
107
+ . map (
108
+ errorDiagnostic => {
109
+ if ( errorDiagnostic . file === undefined ) return ;
110
+ return `${ errorDiagnostic . file . fileName } ` ;
111
+ } ) ;
112
+ return filesInError . 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 {
120
+ fileName,
121
+ line : line + 1 ,
122
+ } ;
123
+ }
124
+ } ) ;
125
+ }
126
+
104
127
export function getWatchErrorSummaryDiagnosticMessage ( errorCount : number ) {
105
128
return errorCount === 1 ?
106
129
Diagnostics . Found_1_error_Watching_for_file_changes :
107
130
Diagnostics . Found_0_errors_Watching_for_file_changes ;
108
131
}
109
132
110
- export function getErrorSummaryText ( errorCount : number , newLine : string ) {
133
+ export function getErrorSummaryText (
134
+ errorCount : number ,
135
+ filesInError : readonly ( ReportFileInError | undefined ) [ ] ,
136
+ newLine : string
137
+ ) {
111
138
if ( errorCount === 0 ) return "" ;
112
- const d = createCompilerDiagnostic ( errorCount === 1 ? Diagnostics . Found_1_error : Diagnostics . Found_0_errors , errorCount ) ;
113
- return `${ newLine } ${ flattenDiagnosticMessageText ( d . messageText , newLine ) } ${ newLine } ${ newLine } ` ;
139
+ const nonNilFiles = filesInError . filter ( fileInError => fileInError !== undefined ) ;
140
+ const distinctFileNamesWithLines = nonNilFiles . map ( fileInError => `${ fileInError ! . fileName } :${ fileInError ! . line } ` )
141
+ . filter ( ( value , index , self ) => self . indexOf ( value ) === index ) ;
142
+ const d = errorCount === 1 ?
143
+ createCompilerDiagnostic (
144
+ filesInError [ 0 ] !== undefined ?
145
+ Diagnostics . Found_1_error_in_1 :
146
+ Diagnostics . Found_1_error ,
147
+ errorCount ,
148
+ distinctFileNamesWithLines [ 0 ] ) :
149
+ createCompilerDiagnostic (
150
+ distinctFileNamesWithLines . length === 0 ?
151
+ Diagnostics . Found_0_errors :
152
+ distinctFileNamesWithLines . length === 1 ?
153
+ Diagnostics . Found_0_errors_in_1_file :
154
+ Diagnostics . Found_0_errors_in_1_files ,
155
+ errorCount ,
156
+ distinctFileNamesWithLines . length ) ;
157
+ return `${ newLine } ${ flattenDiagnosticMessageText ( d . messageText , newLine ) } ${ newLine } ${ newLine } ${ errorCount > 1 ? createTabularErrorsDisplay ( nonNilFiles ) : "" } ` ;
158
+ }
159
+
160
+ function createTabularErrorsDisplay ( filesInError : ( ReportFileInError | undefined ) [ ] ) {
161
+ const distinctFiles = filesInError . filter ( ( value , index , self ) => index === self . findIndex ( file => file ?. fileName === value ?. fileName ) ) ;
162
+ if ( distinctFiles . length === 0 ) return "" ;
163
+
164
+ const numberLength = ( num : number ) => Math . log ( num ) * Math . LOG10E + 1 ;
165
+ const fileToErrorCount = distinctFiles . map ( file => ( [ file , countWhere ( filesInError , fileInError => fileInError ! . fileName === file ! . fileName ) ] as const ) ) ;
166
+ const maxErrors = fileToErrorCount . reduce ( ( acc , value ) => Math . max ( acc , value [ 1 ] || 0 ) , 0 ) ;
167
+
168
+ const headerRow = Diagnostics . Errors_Files . message ;
169
+ const leftColumnHeadingLength = headerRow . split ( " " ) [ 0 ] . length ;
170
+ const leftPaddingGoal = Math . max ( leftColumnHeadingLength , numberLength ( maxErrors ) ) ;
171
+ const headerPadding = Math . max ( numberLength ( maxErrors ) - leftColumnHeadingLength , 0 ) ;
172
+
173
+ let tabularData = "" ;
174
+ tabularData += " " . repeat ( headerPadding ) + headerRow + "\n" ;
175
+ fileToErrorCount . forEach ( ( row ) => {
176
+ const [ file , errorCount ] = row ;
177
+ const errorCountDigitsLength = Math . log ( errorCount ) * Math . LOG10E + 1 | 0 ;
178
+ const leftPadding = errorCountDigitsLength < leftPaddingGoal ?
179
+ " " . repeat ( leftPaddingGoal - errorCountDigitsLength )
180
+ : "" ;
181
+ tabularData += `${ leftPadding } ${ errorCount } ${ file ! . fileName } :${ file ! . line } \n` ;
182
+ } ) ;
183
+
184
+ return tabularData ;
114
185
}
115
186
116
187
export function isBuilderProgram ( program : Program | BuilderProgram ) : program is BuilderProgram {
@@ -350,7 +421,7 @@ namespace ts {
350
421
}
351
422
352
423
if ( reportSummary ) {
353
- reportSummary ( getErrorCountForSummary ( diagnostics ) ) ;
424
+ reportSummary ( getErrorCountForSummary ( diagnostics ) , getFilesInErrorForSummary ( diagnostics ) ) ;
354
425
}
355
426
356
427
return {
@@ -656,7 +727,7 @@ namespace ts {
656
727
builderProgram ,
657
728
input . reportDiagnostic || createDiagnosticReporter ( system ) ,
658
729
s => host . trace && host . trace ( s ) ,
659
- input . reportErrorSummary || input . options . pretty ? errorCount => system . write ( getErrorSummaryText ( errorCount , system . newLine ) ) : undefined
730
+ input . reportErrorSummary || input . options . pretty ? ( errorCount , filesInError ) => system . write ( getErrorSummaryText ( errorCount , filesInError , system . newLine ) ) : undefined
660
731
) ;
661
732
if ( input . afterProgramEmitAndDiagnostics ) input . afterProgramEmitAndDiagnostics ( builderProgram ) ;
662
733
return exitStatus ;
0 commit comments