@@ -52,17 +52,20 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
5252 return ;
5353 }
5454
55+ // Get all additional locations we expect from the analyzer
56+ if ( ! TryGetAdditionalLocations (
57+ diagnostic ,
58+ out Location ? fieldLocation ,
59+ out Location ? propertyTypeExpressionLocation ,
60+ out Location ? defaultValueExpressionLocation ) )
61+ {
62+ return ;
63+ }
64+
5565 // Retrieve the properties passed by the analyzer
5666 string ? defaultValue = diagnostic . Properties [ UseGeneratedDependencyPropertyOnManualPropertyAnalyzer . DefaultValuePropertyName ] ;
5767 string ? defaultValueTypeReferenceId = diagnostic . Properties [ UseGeneratedDependencyPropertyOnManualPropertyAnalyzer . DefaultValueTypeReferenceIdPropertyName ] ;
5868
59- // Get all additional locations we expect from the analyzer
60- GetAdditionalLocations (
61- diagnostic ,
62- out Location fieldLocation ,
63- out Location propertyTypeExpressionLocation ,
64- out Location defaultValueExpressionLocation ) ;
65-
6669 SyntaxNode ? root = await context . Document . GetSyntaxRootAsync ( context . CancellationToken ) . ConfigureAwait ( false ) ;
6770
6871 // Get the property declaration and the field declaration from the target diagnostic
@@ -505,16 +508,29 @@ private static void RemoveLeftoverLeadingEndOfLines(IReadOnlyCollection<FieldDec
505508 /// <param name="fieldLocation">The location of the field to remove.</param>
506509 /// <param name="propertyTypeExpressionLocation">The location of the property type expression to use in metadata.</param>
507510 /// <param name="defaultValueExpressionLocation">The location for the default value.</param>
508- private static void GetAdditionalLocations (
511+ /// <returns>Whether the additional locations were retrieved correctly.</returns>
512+ private static bool TryGetAdditionalLocations (
509513 Diagnostic diagnostic ,
510- out Location fieldLocation ,
511- out Location propertyTypeExpressionLocation ,
512- out Location defaultValueExpressionLocation )
514+ [ NotNullWhen ( true ) ] out Location ? fieldLocation ,
515+ [ NotNullWhen ( true ) ] out Location ? propertyTypeExpressionLocation ,
516+ [ NotNullWhen ( true ) ] out Location ? defaultValueExpressionLocation )
513517 {
514- // We always expect 3 additional locations, as per contract with the analyzer
515- fieldLocation = diagnostic . AdditionalLocations [ 0 ] ;
516- propertyTypeExpressionLocation = diagnostic . AdditionalLocations [ 1 ] ;
517- defaultValueExpressionLocation = diagnostic . AdditionalLocations [ 2 ] ;
518+ // We always expect 3 additional locations, as per contract with the analyzer.
519+ // Do a sanity check just in case, as we've seen sporadic issues with this.
520+ if ( diagnostic . AdditionalLocations is not [ { } location1 , { } location2 , { } location3 ] )
521+ {
522+ fieldLocation = null ;
523+ propertyTypeExpressionLocation = null ;
524+ defaultValueExpressionLocation = null ;
525+
526+ return false ;
527+ }
528+
529+ fieldLocation = location1 ;
530+ propertyTypeExpressionLocation = location2 ;
531+ defaultValueExpressionLocation = location3 ;
532+
533+ return true ;
518534 }
519535
520536 /// <summary>
@@ -559,11 +575,14 @@ private sealed class FixAllProvider : DocumentBasedFixAllProvider
559575 }
560576
561577 // Get all additional locations we expect from the analyzer
562- GetAdditionalLocations (
578+ if ( ! TryGetAdditionalLocations (
563579 diagnostic ,
564- out Location fieldLocation ,
565- out Location propertyTypeExpressionLocation ,
566- out Location defaultValueExpressionLocation ) ;
580+ out Location ? fieldLocation ,
581+ out Location ? propertyTypeExpressionLocation ,
582+ out Location ? defaultValueExpressionLocation ) )
583+ {
584+ continue ;
585+ }
567586
568587 // Also check that we can find the target field to remove
569588 if ( root . FindNode ( fieldLocation . SourceSpan ) is not FieldDeclarationSyntax fieldDeclaration )
0 commit comments