Skip to content

Commit

Permalink
Merge pull request #71269 from dibarbet/revert_integration_failure
Browse files Browse the repository at this point in the history
Revert "Merge pull request #71258 from mavasani/RemoveFadingDiagnostics"
  • Loading branch information
dibarbet authored Dec 15, 2023
2 parents fd3194f + 9d85cb0 commit 462e180
Show file tree
Hide file tree
Showing 22 changed files with 891 additions and 530 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;

Expand All @@ -24,13 +23,12 @@ internal static class Constants
}

[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class InvokeDelegateWithConditionalAccessAnalyzer : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer
internal class InvokeDelegateWithConditionalAccessAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
{
public InvokeDelegateWithConditionalAccessAnalyzer()
: base(IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId,
EnforceOnBuildValues.InvokeDelegateWithConditionalAccess,
CSharpCodeStyleOptions.PreferConditionalDelegateCall,
fadingOption: null,
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Delegate_invocation_can_be_simplified), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)))
{
}
Expand Down Expand Up @@ -172,40 +170,42 @@ private void ReportDiagnostics(
ImmutableArray<Location> additionalLocations,
string kind)
{
var location = expressionStatement.GetLocation();
var fadingLocations = GetLocationsToFade();
var tree = syntaxContext.Node.SyntaxTree;

var properties = ImmutableDictionary<string, string?>.Empty.Add(
Constants.Kind, kind);

var previousToken = expressionStatement.GetFirstToken().GetPreviousToken();
var nextToken = expressionStatement.GetLastToken().GetNextToken();

// Fade out the code up to the expression statement.
var fadeLocation = Location.Create(tree, TextSpan.FromBounds(firstStatement.SpanStart, previousToken.Span.End));
syntaxContext.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
location,
notificationOption,
fadeLocation,
NotificationOption2.ForSeverity(Descriptor.DefaultSeverity),
additionalLocations,
fadingLocations,
additionalUnnecessaryLocations: ImmutableArray.Create(fadeLocation),
properties));

return;
// Put a diagnostic with the appropriate severity on the expression-statement itself.
syntaxContext.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
expressionStatement.GetLocation(),
notificationOption,
additionalLocations, properties));

ImmutableArray<Location> GetLocationsToFade()
// If the if-statement extends past the expression statement, then fade out the rest.
if (nextToken.Span.Start < ifStatement.Span.End)
{
var tree = syntaxContext.Node.SyntaxTree;
var previousToken = expressionStatement.GetFirstToken().GetPreviousToken();
var nextToken = expressionStatement.GetLastToken().GetNextToken();

// Fade out the code up to the expression statement.
using var _ = ArrayBuilder<Location>.GetInstance(out var fadingLocations);
fadingLocations.Add(
Location.Create(tree, TextSpan.FromBounds(firstStatement.SpanStart, previousToken.Span.End)));

// If the if-statement extends past the expression statement, then fade out the rest.
if (nextToken.Span.Start < ifStatement.Span.End)
{
fadingLocations.Add(
Location.Create(tree, TextSpan.FromBounds(nextToken.Span.Start, ifStatement.Span.End)));
}

return fadingLocations.ToImmutable();
fadeLocation = Location.Create(tree, TextSpan.FromBounds(nextToken.Span.Start, ifStatement.Span.End));
syntaxContext.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
fadeLocation,
NotificationOption2.ForSeverity(Descriptor.DefaultSeverity),
additionalLocations,
additionalUnnecessaryLocations: ImmutableArray.Create(fadeLocation),
properties));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,31 @@ namespace Microsoft.CodeAnalysis.CSharp.UseCollectionExpression;
/// Base type for all analyzers that offer to update code to use a collection-expression.
/// </summary>
internal abstract class AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer
: AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer
: AbstractBuiltInCodeStyleDiagnosticAnalyzer
{
protected new readonly DiagnosticDescriptor Descriptor;
protected readonly DiagnosticDescriptor UnnecessaryCodeDescriptor;

protected AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer(string diagnosticId, EnforceOnBuild enforceOnBuild)
: base(diagnosticId, enforceOnBuild, CodeStyleOptions2.PreferCollectionExpression,
fadingOption: null,
title: new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)),
messageFormat: new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)))
: base(ImmutableDictionary<DiagnosticDescriptor, IOption2>.Empty
// Ugly hack. We need to create a descriptor to pass to our base *and* assign to one of our fields.
// The conditional pattern form lets us do that.
.Add(CreateDescriptor(diagnosticId, enforceOnBuild, isUnnecessary: false) is var descriptor ? descriptor : null, CodeStyleOptions2.PreferCollectionExpression)
.Add(CreateDescriptor(diagnosticId, enforceOnBuild, isUnnecessary: true) is var unnecessaryCodeDescriptor ? unnecessaryCodeDescriptor : null, CodeStyleOptions2.PreferCollectionExpression))
{
Descriptor = descriptor;
UnnecessaryCodeDescriptor = unnecessaryCodeDescriptor;
}

private static DiagnosticDescriptor CreateDescriptor(string diagnosticId, EnforceOnBuild enforceOnBuild, bool isUnnecessary)
=> CreateDescriptorWithId(
diagnosticId,
enforceOnBuild,
hasAnyCodeStyleOption: true,
new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)),
new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)),
isUnnecessary: isUnnecessary);

protected abstract void InitializeWorker(CodeBlockStartAnalysisContext<SyntaxKind> context, INamedTypeSymbol? expressionType);

protected virtual bool IsSupported(Compilation compilation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,21 +162,26 @@ private void AnalyzeArrayInitializerExpression(SyntaxNodeAnalysisContext context

private void ReportArrayCreationDiagnostics(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, CodeStyleOption2<bool> option, ExpressionSyntax expression)
{
var location = expression.GetFirstToken().GetLocation();
var additionalLocations = ImmutableArray.Create(expression.GetLocation());
var fadingLocations = ImmutableArray.Create(
var locations = ImmutableArray.Create(expression.GetLocation());
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
expression.GetFirstToken().GetLocation(),
option.Notification,
additionalLocations: locations,
properties: null));

var additionalUnnecessaryLocations = ImmutableArray.Create(
syntaxTree.GetLocation(TextSpan.FromBounds(
expression.SpanStart,
expression is ArrayCreationExpressionSyntax arrayCreationExpression
? arrayCreationExpression.Type.Span.End
: ((ImplicitArrayCreationExpressionSyntax)expression).CloseBracketToken.Span.End)));

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
location,
option.Notification,
additionalLocations,
fadingLocations,
properties: null));
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,47 @@ private void AnalyzeInvocationExpression(
if (AnalyzeInvocation(semanticModel, invocationExpression, expressionType, cancellationToken) is not { } analysisResult)
return;

var location = analysisResult.DiagnosticLocation;
var additionalLocations = ImmutableArray.Create(invocationExpression.GetLocation());
var fadingLocations = GetLocationsToFade(analysisResult);

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
var locations = ImmutableArray.Create(invocationExpression.GetLocation());
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
location,
analysisResult.DiagnosticLocation,
option.Notification,
additionalLocations,
fadingLocations,
additionalLocations: locations,
properties: null));

FadeOutCode(context, analysisResult, locations);
}

private static ImmutableArray<Location> GetLocationsToFade(AnalysisResult analysisResult)
private void FadeOutCode(SyntaxNodeAnalysisContext context, AnalysisResult analysisResult, ImmutableArray<Location> locations)
{
using var _ = ArrayBuilder<Location>.GetInstance(out var fadingLocations);
fadingLocations.Add(analysisResult.LocalDeclarationStatement.GetLocation());
var additionalUnnecessaryLocations = ImmutableArray.Create(
analysisResult.LocalDeclarationStatement.GetLocation());

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations,
properties: null));

foreach (var statementMatch in analysisResult.Matches)
{
var locations = UseCollectionInitializerHelpers.GetLocationsToFade(
additionalUnnecessaryLocations = UseCollectionInitializerHelpers.GetLocationsToFade(
CSharpSyntaxFacts.Instance, statementMatch);
if (!locations.IsDefaultOrEmpty)
fadingLocations.AddRange(locations);
}
if (additionalUnnecessaryLocations.IsDefaultOrEmpty)
continue;

return fadingLocations.ToImmutable();
// Report the diagnostic at the first unnecessary location. This is the location where the code fix
// will be offered.
context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations,
properties: null));
}
}

public static AnalysisResult? AnalyzeInvocation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,28 @@ private void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context, INam
if (!CanReplaceWithCollectionExpression(semanticModel, invocationExpression, expressionType, skipVerificationForReplacedNode: true, cancellationToken))
return;

var location = memberAccess.Name.Identifier.GetLocation();
var additionalLocations = ImmutableArray.Create(invocationExpression.GetLocation());
var fadingLocations = ImmutableArray.Create(
var locations = ImmutableArray.Create(invocationExpression.GetLocation());
var properties = unwrapArgument ? s_unwrapArgumentProperties : null;

context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
memberAccess.Name.Identifier.GetLocation(),
option.Notification,
additionalLocations: locations,
properties));

var additionalUnnecessaryLocations = ImmutableArray.Create(
syntaxTree.GetLocation(TextSpan.FromBounds(
invocationExpression.SpanStart,
invocationExpression.ArgumentList.OpenParenToken.Span.End)),
invocationExpression.ArgumentList.CloseParenToken.GetLocation());

var properties = unwrapArgument ? s_unwrapArgumentProperties : null;

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
location,
option.Notification,
additionalLocations,
fadingLocations,
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations,
properties));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,25 @@ private void AnalyzeImplicitStackAllocExpression(SyntaxNodeAnalysisContext conte
return;
}

var location = expression.GetFirstToken().GetLocation();
var additionalLocations = ImmutableArray.Create(expression.GetLocation());
var fadingLocations = ImmutableArray.Create(
var locations = ImmutableArray.Create(expression.GetLocation());
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
expression.GetFirstToken().GetLocation(),
option.Notification,
additionalLocations: locations,
properties: null));

var additionalUnnecessaryLocations = ImmutableArray.Create(
syntaxTree.GetLocation(TextSpan.FromBounds(
expression.SpanStart,
expression.CloseBracketToken.Span.End)));

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
location,
option.Notification,
additionalLocations,
fadingLocations,
properties: null));
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations));
}

private void AnalyzeExplicitStackAllocExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol? expressionType)
Expand All @@ -84,20 +89,25 @@ private void AnalyzeExplicitStackAllocExpression(SyntaxNodeAnalysisContext conte
if (matches.IsDefault)
return;

var location = expression.GetFirstToken().GetLocation();
var additionalLocations = ImmutableArray.Create(expression.GetLocation());
var fadingLocations = ImmutableArray.Create(
var locations = ImmutableArray.Create(expression.GetLocation());
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
expression.GetFirstToken().GetLocation(),
option.Notification,
additionalLocations: locations,
properties: null));

var additionalUnnecessaryLocations = ImmutableArray.Create(
syntaxTree.GetLocation(TextSpan.FromBounds(
expression.SpanStart,
expression.Type.Span.End)));

context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags(
Descriptor,
location,
option.Notification,
additionalLocations,
fadingLocations,
properties: null));
UnnecessaryCodeDescriptor,
additionalUnnecessaryLocations[0],
NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity),
additionalLocations: locations,
additionalUnnecessaryLocations: additionalUnnecessaryLocations));
}

public static ImmutableArray<CollectionExpressionMatch<StatementSyntax>> TryGetMatches(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public InvokeDelegateWithConditionalAccessCodeFixProvider()

public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId);

// Filter out the diagnostics we created for the faded out code. We don't want
// to try to fix those as well as the normal diagnostics we created.
protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
=> !diagnostic.Properties.ContainsKey(WellKnownDiagnosticTags.Unnecessary);

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
RegisterCodeFix(context, CSharpAnalyzersResources.Simplify_delegate_invocation, nameof(CSharpAnalyzersResources.Simplify_delegate_invocation));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public CSharpUseCollectionExpressionForEmptyCodeFixProvider()

public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseCollectionExpressionForEmptyDiagnosticId);

protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
=> !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary);

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
RegisterCodeFix(context, CSharpCodeFixesResources.Use_collection_expression, IDEDiagnosticIds.UseCollectionExpressionForEmptyDiagnosticId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public UseThrowExpressionCodeFixProvider()
public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.UseThrowExpressionDiagnosticId);

protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
=> !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary);

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
RegisterCodeFix(context, AnalyzersResources.Use_throw_expression, nameof(AnalyzersResources.Use_throw_expression));
Expand Down
Loading

0 comments on commit 462e180

Please sign in to comment.