From 643fe6d1f35274cb7fdf60977de592096458075c Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sun, 26 Nov 2023 03:46:16 +0100 Subject: [PATCH 1/3] Fix analyzer RCS1032 --- .../RemoveRedundantParenthesesAnalyzer.cs | 51 +++++++++++++------ .../RCS1032RemoveRedundantParenthesesTests.cs | 25 +++++++++ 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs b/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs index 39a24105ad..3df7550778 100644 --- a/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs @@ -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; @@ -83,7 +84,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con case SyntaxKind.SwitchStatement: case SyntaxKind.ArrayRankSpecifier: { - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); break; } case SyntaxKind.LessThanExpression: @@ -97,7 +98,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con if (expression.IsKind(SyntaxKind.IdentifierName) || expression is LiteralExpressionSyntax) { - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); } break; @@ -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; @@ -141,7 +142,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con case SyntaxKind.ElementAccessExpression: case SyntaxKind.ConditionalAccessExpression: { - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); break; } } @@ -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; @@ -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; @@ -189,7 +190,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con return; if (CSharpFacts.GetOperatorPrecedence(expression.Kind()) <= CSharpFacts.GetOperatorPrecedence(SyntaxKind.AwaitExpression)) - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); break; } @@ -197,7 +198,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con case SyntaxKind.CollectionInitializerExpression: { if (expression is not AssignmentExpressionSyntax) - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); break; } @@ -215,7 +216,7 @@ private static void AnalyzeParenthesizedExpression(SyntaxNodeAnalysisContext con case SyntaxKind.AddAssignmentExpression: case SyntaxKind.SubtractAssignmentExpression: { - ReportDiagnostic(); + ReportDiagnostic(context, parenthesizedExpression); break; } #if DEBUG @@ -231,16 +232,34 @@ 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) + { + int index = argumentList.Arguments.IndexOf((ArgumentSyntax)parenthesizedExpression.Parent); + + if (index < argumentList.Arguments.Count - 1) + { + string syntax = parenthesizedExpression.Expression + + argumentList.ToString(TextSpan.FromBounds(argumentList.Arguments[index].Span.End, argumentList.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); } } } diff --git a/src/Tests/Analyzers.Tests/RCS1032RemoveRedundantParenthesesTests.cs b/src/Tests/Analyzers.Tests/RCS1032RemoveRedundantParenthesesTests.cs index 4235586f21..24f3d30b04 100644 --- a/src/Tests/Analyzers.Tests/RCS1032RemoveRedundantParenthesesTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1032RemoveRedundantParenthesesTests.cs @@ -589,6 +589,31 @@ async Task 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(); +} "); } } From 551f3e2046c5f2f1b8f27c74345c085f2abb8748 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sun, 26 Nov 2023 03:48:21 +0100 Subject: [PATCH 2/3] update --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 38a52973de..791a697856 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -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 From 32b4fdc15c7c14152d7499eb556692e61220d1f7 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sun, 26 Nov 2023 03:55:50 +0100 Subject: [PATCH 3/3] update --- .../CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs b/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs index 3df7550778..cb92ba36b2 100644 --- a/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/RemoveRedundantParenthesesAnalyzer.cs @@ -238,12 +238,13 @@ static void ReportDiagnostic(SyntaxNodeAnalysisContext context, ParenthesizedExp && parenthesizedExpression.IsParentKind(SyntaxKind.Argument) && parenthesizedExpression.Parent.Parent is BaseArgumentListSyntax argumentList) { - int index = argumentList.Arguments.IndexOf((ArgumentSyntax)parenthesizedExpression.Parent); + SeparatedSyntaxList arguments = argumentList.Arguments; + int index = arguments.IndexOf((ArgumentSyntax)parenthesizedExpression.Parent); - if (index < argumentList.Arguments.Count - 1) + if (index < arguments.Count - 1) { string syntax = parenthesizedExpression.Expression - + argumentList.ToString(TextSpan.FromBounds(argumentList.Arguments[index].Span.End, argumentList.Arguments[index + 1].Span.End)); + + argumentList.ToString(TextSpan.FromBounds(arguments[index].Span.End, arguments[index + 1].Span.End)); NameSyntax name = SyntaxFactory.ParseName(syntax);