Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix analyzer RCS1032 #1289

Merged
merged 3 commits into from Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix analyzer [RCS1203](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1203) ([PR](https://github.com/dotnet/roslynator/pull/1282))
- Fix analyzer [RCS1046](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1046) ([PR](https://github.com/dotnet/roslynator/pull/1283))
- Fix analyzer [RCS1158](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1158) ([PR](https://github.com/dotnet/roslynator/pull/1288))
- Fix analyzer [RCS1032](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1032) ([PR](https://github.com/dotnet/roslynator/pull/1289))

## [4.6.4] - 2023-11-24

Expand Down
52 changes: 36 additions & 16 deletions src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs
Expand Up @@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;

namespace Roslynator.CSharp.Analysis;

Expand Down Expand Up @@ -83,7 +84,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
case SyntaxKind.SwitchStatement:
case SyntaxKind.ArrayRankSpecifier:
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
break;
}
case SyntaxKind.LessThanExpression:
Expand All @@ -97,7 +98,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
if (expression.IsKind(SyntaxKind.IdentifierName)
|| expression is LiteralExpressionSyntax)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}

break;
Expand All @@ -120,12 +121,12 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
if (kind == SyntaxKind.IdentifierName
|| expression is LiteralExpressionSyntax)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}
else if (kind == parentKind
&& ((BinaryExpressionSyntax)parent).Left == parenthesizedExpression)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}

break;
Expand All @@ -141,7 +142,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
case SyntaxKind.ElementAccessExpression:
case SyntaxKind.ConditionalAccessExpression:
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
break;
}
}
Expand All @@ -162,12 +163,12 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
{
if (((AssignmentExpressionSyntax)parent).Left == parenthesizedExpression)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}
else if (expression.IsKind(SyntaxKind.IdentifierName)
|| expression is LiteralExpressionSyntax)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}

break;
Expand All @@ -178,7 +179,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
&& !expression.DescendantNodes().Any(f => f.IsKind(SyntaxKind.AliasQualifiedName))
&& ((InterpolationSyntax)parent).Expression == parenthesizedExpression)
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
}

break;
Expand All @@ -189,15 +190,15 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
return;

if (CSharpFacts.GetOperatorPrecedence(expression.Kind()) <= CSharpFacts.GetOperatorPrecedence(SyntaxKind.AwaitExpression))
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);

break;
}
case SyntaxKind.ArrayInitializerExpression:
case SyntaxKind.CollectionInitializerExpression:
{
if (expression is not AssignmentExpressionSyntax)
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);

break;
}
Expand All @@ -215,7 +216,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
case SyntaxKind.AddAssignmentExpression:
case SyntaxKind.SubtractAssignmentExpression:
{
ReportDiagnostic();
ReportDiagnostic(context, parenthesizedExpression);
break;
}
#if DEBUG
Expand All @@ -231,16 +232,35 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con
}
}

void ReportDiagnostic()
static void ReportDiagnostic(SyntaxNodeAnalysisContext context, ParenthesizedExpressionSyntax parenthesizedExpression)
{
if (parenthesizedExpression.Expression.IsKind(SyntaxKind.LessThanExpression)
&& parenthesizedExpression.IsParentKind(SyntaxKind.Argument)
&& parenthesizedExpression.Parent.Parent is BaseArgumentListSyntax argumentList)
{
SeparatedSyntaxList<ArgumentSyntax> arguments = argumentList.Arguments;
int index = arguments.IndexOf((ArgumentSyntax)parenthesizedExpression.Parent);

if (index < arguments.Count - 1)
{
string syntax = parenthesizedExpression.Expression
+ argumentList.ToString(TextSpan.FromBounds(arguments[index].Span.End, arguments[index + 1].Span.End));

NameSyntax name = SyntaxFactory.ParseName(syntax);

if (name.IsKind(SyntaxKind.GenericName))
return;
}
}

DiagnosticHelpers.ReportDiagnostic(
context,
DiagnosticRules.RemoveRedundantParentheses,
openParen.GetLocation(),
additionalLocations: ImmutableArray.Create(closeParen.GetLocation()));
parenthesizedExpression.OpenParenToken.GetLocation(),
additionalLocations: ImmutableArray.Create(parenthesizedExpression.CloseParenToken.GetLocation()));

DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantParenthesesFadeOut, openParen);
DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantParenthesesFadeOut, closeParen);
DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantParenthesesFadeOut, parenthesizedExpression.OpenParenToken);
DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantParenthesesFadeOut, parenthesizedExpression.CloseParenToken);
}
}
}
Expand Up @@ -589,6 +589,31 @@ async Task<string> M()
});
}
}
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantParentheses)]
public async Task TestNoDiagnostic_GrammarAmbiguity()
{
await VerifyNoDiagnosticAsync(@"
using System;

public class Foo
{
public static void F(bool p1, bool p2)
{
int x = 0;
int y = 0;
Bar d = null;
F((x < y), d > (d ?? d));
}
}

public class Bar
{
public static bool operator >(Bar left, Bar right) => throw new NotImplementedException();
public static bool operator <(Bar left, Bar right) => throw new NotImplementedException();
}
");
}
}