12
12
using Microsoft . CodeAnalysis . CodeActions ;
13
13
using Microsoft . CodeAnalysis . CodeFixes ;
14
14
using Microsoft . CodeAnalysis . Diagnostics ;
15
+ using Microsoft . CodeAnalysis . ErrorReporting ;
15
16
using Microsoft . CodeAnalysis . Host ;
16
17
using Microsoft . CodeAnalysis . Host . Mef ;
17
18
using Microsoft . CodeAnalysis . PooledObjects ;
@@ -255,30 +256,44 @@ private async Task<CopilotCodeFixAnalysis> ComputeCodeFixAnalysisAsync(
255
256
var diagnosticIdToProviderName = new Dictionary < string , HashSet < string > > ( ) ;
256
257
var providerNameToApplicationTime = new Dictionary < string , TimeSpan > ( ) ;
257
258
var providerNameToHasConflict = new Dictionary < string , bool > ( ) ;
259
+ var providerNameToTotalCount = new Dictionary < string , int > ( ) ;
260
+ var providerNameToSuccessCount = new Dictionary < string , int > ( ) ;
258
261
259
262
var totalApplicationTimeStopWatch = SharedStopwatch . StartNew ( ) ;
260
- await ProducerConsumer < ( CodeFixCollection collection , TimeSpan elapsedTime ) > . RunParallelAsync (
263
+ await ProducerConsumer < ( CodeFixCollection collection , bool success , TimeSpan elapsedTime ) > . RunParallelAsync (
261
264
codeFixCollections ,
262
265
produceItems : static async ( codeFixCollection , callback , args , cancellationToken ) =>
263
266
{
264
- var ( @this , solution , _, _, _, _, _) = args ;
267
+ var ( @this , solution , _, _, _, _, _, _ , _ ) = args ;
265
268
var firstAction = GetFirstAction ( codeFixCollection . Fixes [ 0 ] ) ;
266
269
267
270
var applicationTimeStopWatch = SharedStopwatch . StartNew ( ) ;
268
- var result = await firstAction . GetPreviewOperationsAsync ( solution , cancellationToken ) . ConfigureAwait ( false ) ;
269
- callback ( ( codeFixCollection , applicationTimeStopWatch . Elapsed ) ) ;
271
+ var success = true ;
272
+ try
273
+ {
274
+ await firstAction
275
+ . GetPreviewOperationsAsync ( solution , cancellationToken )
276
+ . ConfigureAwait ( false ) ;
277
+ }
278
+ catch ( Exception e ) when ( FatalError . ReportAndCatchUnlessCanceled ( e , cancellationToken ) )
279
+ {
280
+ success = false ;
281
+ }
282
+
283
+ callback ( ( codeFixCollection , success , applicationTimeStopWatch . Elapsed ) ) ;
270
284
} ,
271
285
consumeItems : static async ( values , args , cancellationToken ) =>
272
286
{
273
- var ( @this , solution , diagnosticIdToCount , diagnosticIdToApplicationTime , diagnosticIdToProviderName , providerNameToApplicationTime , providerNameToHasConflict ) = args ;
287
+ var ( @this , solution , diagnosticIdToCount , diagnosticIdToApplicationTime , diagnosticIdToProviderName ,
288
+ providerNameToApplicationTime , providerNameToHasConflict , providerNameToTotalCount , providerNameToSuccessCount ) = args ;
274
289
275
290
// Track which text span each code fix says it will be fixing. We can use this to efficiently determine
276
291
// which codefixes 'conflict' with some other codefix (in that that multiple features think they can fix
277
292
// the same span of code). We would need some mechanism to determine which we would prefer to take in
278
293
// order to have a good experience in such a case.
279
294
var intervalTree = new SimpleMutableIntervalTree < CodeFixCollection , CodeFixCollectionIntervalIntrospector > ( new CodeFixCollectionIntervalIntrospector ( ) ) ;
280
295
281
- await foreach ( var ( codeFixCollection , applicationTime ) in values )
296
+ await foreach ( var ( codeFixCollection , success , applicationTime ) in values )
282
297
{
283
298
var diagnosticId = codeFixCollection . FirstDiagnostic . Id ;
284
299
var providerName = GetProviderName ( codeFixCollection ) ;
@@ -287,6 +302,10 @@ private async Task<CopilotCodeFixAnalysis> ComputeCodeFixAnalysisAsync(
287
302
IncrementElapsedTime ( diagnosticIdToApplicationTime , diagnosticId , applicationTime ) ;
288
303
diagnosticIdToProviderName . MultiAdd ( diagnosticId , providerName ) ;
289
304
IncrementElapsedTime ( providerNameToApplicationTime , providerName , applicationTime ) ;
305
+ IncrementCount ( providerNameToTotalCount , providerName ) ;
306
+
307
+ if ( success )
308
+ IncrementCount ( providerNameToSuccessCount , providerName ) ;
290
309
291
310
intervalTree . AddIntervalInPlace ( codeFixCollection ) ;
292
311
}
@@ -311,7 +330,8 @@ private async Task<CopilotCodeFixAnalysis> ComputeCodeFixAnalysisAsync(
311
330
providerNameToHasConflict [ providerName ] = storedHasConflictValue || newHasConflictValue ;
312
331
}
313
332
} ,
314
- args : ( @this : this , newDocument . Project . Solution , diagnosticIdToCount , diagnosticIdToApplicationTime , diagnosticIdToProviderName , providerNameToApplicationTime , providerNameToHasConflict ) ,
333
+ args : ( @this : this , newDocument . Project . Solution , diagnosticIdToCount , diagnosticIdToApplicationTime , diagnosticIdToProviderName ,
334
+ providerNameToApplicationTime , providerNameToHasConflict , providerNameToTotalCount , providerNameToSuccessCount ) ,
315
335
cancellationToken ) . ConfigureAwait ( false ) ;
316
336
var totalApplicationTime = totalApplicationTimeStopWatch . Elapsed ;
317
337
@@ -322,7 +342,9 @@ private async Task<CopilotCodeFixAnalysis> ComputeCodeFixAnalysisAsync(
322
342
diagnosticIdToApplicationTime ,
323
343
diagnosticIdToProviderName ,
324
344
providerNameToApplicationTime ,
325
- providerNameToHasConflict ) ;
345
+ providerNameToHasConflict ,
346
+ providerNameToTotalCount ,
347
+ providerNameToSuccessCount ) ;
326
348
327
349
Task < ImmutableArray < CodeFixCollection > > ComputeCodeFixCollectionsAsync ( )
328
350
{
0 commit comments