diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1008CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1008CSharp9UnitTests.cs index effd6ee3f..e24b02734 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1008CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1008CSharp9UnitTests.cs @@ -3,9 +3,64 @@ namespace StyleCop.Analyzers.Test.CSharp9.SpacingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.CSharp; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.SpacingRules; + using Xunit; + using static StyleCop.Analyzers.SpacingRules.SA1008OpeningParenthesisMustBeSpacedCorrectly; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.SpacingRules.SA1008OpeningParenthesisMustBeSpacedCorrectly, + StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>; public class SA1008CSharp9UnitTests : SA1008CSharp8UnitTests { + [Fact] + [WorkItem(3230, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3230")] + public async Task TestParenthesizedPatternAsync() + { + const string testCode = @" +class C +{ + void Method(int b) + { + _ = b is{|#0:(|} >= 0 and <= 31) or 127; + _ = b is{|#1:(|}>= 0 and <= 31) or 127; + _ = b is {|#2:(|} >= 0 and <= 31) or 127; + } +}"; + const string fixedCode = @" +class C +{ + void Method(int b) + { + _ = b is (>= 0 and <= 31) or 127; + _ = b is (>= 0 and <= 31) or 127; + _ = b is (>= 0 and <= 31) or 127; + } +}"; + + await new CSharpTest(LanguageVersion.CSharp9) + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + ExpectedDiagnostics = + { + // /0/Test0.cs(6,17): warning SA1008: Opening parenthesis should be preceded by a space. + Diagnostic(DescriptorPreceded).WithLocation(0), + + // /0/Test0.cs(6,17): warning SA1008: Opening parenthesis should not be followed by a space. + Diagnostic(DescriptorNotFollowed).WithLocation(0), + + // /0/Test0.cs(7,17): warning SA1008: Opening parenthesis should be preceded by a space. + Diagnostic(DescriptorPreceded).WithLocation(1), + + // /0/Test0.cs(8,18): warning SA1008: Opening parenthesis should not be followed by a space. + Diagnostic(DescriptorNotFollowed).WithLocation(2), + }, + TestCode = testCode, + FixedCode = fixedCode, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs index 7c691a59f..d07e72561 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs @@ -44,6 +44,7 @@ internal static class SyntaxKindEx public const SyntaxKind SwitchExpression = (SyntaxKind)9025; public const SyntaxKind SwitchExpressionArm = (SyntaxKind)9026; public const SyntaxKind VarPattern = (SyntaxKind)9027; + public const SyntaxKind ParenthesizedPattern = (SyntaxKind)9028; public const SyntaxKind DeclarationExpression = (SyntaxKind)9040; public const SyntaxKind RefExpression = (SyntaxKind)9050; public const SyntaxKind RefType = (SyntaxKind)9051; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1008OpeningParenthesisMustBeSpacedCorrectly.cs b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1008OpeningParenthesisMustBeSpacedCorrectly.cs index 34e8fafb9..6f8220da2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1008OpeningParenthesisMustBeSpacedCorrectly.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1008OpeningParenthesisMustBeSpacedCorrectly.cs @@ -189,6 +189,11 @@ private static void HandleOpenParenToken(SyntaxTreeAnalysisContext context, Synt || prevToken.IsKind(SyntaxKind.CommaToken); break; + case SyntaxKindEx.ParenthesizedPattern: + var partOfCastExpression = prevToken.IsKind(SyntaxKind.CloseParenToken) && prevToken.Parent.IsKind(SyntaxKind.CastExpression); + haveLeadingSpace = !partOfCastExpression; + break; + case SyntaxKind.ArgumentList: case SyntaxKind.AttributeArgumentList: case SyntaxKind.CheckedExpression: @@ -216,7 +221,7 @@ private static void HandleOpenParenToken(SyntaxTreeAnalysisContext context, Synt partOfUnaryExpression = prevToken.Parent is PrefixUnaryExpressionSyntax; startOfIndexer = prevToken.IsKind(SyntaxKind.OpenBracketToken); - var partOfCastExpression = prevToken.IsKind(SyntaxKind.CloseParenToken) && prevToken.Parent.IsKind(SyntaxKind.CastExpression); + partOfCastExpression = prevToken.IsKind(SyntaxKind.CloseParenToken) && prevToken.Parent.IsKind(SyntaxKind.CastExpression); haveLeadingSpace = !partOfUnaryExpression && !startOfIndexer && !partOfCastExpression; break;