diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1003CSharp11UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1003CSharp11UnitTests.cs index 01deb1d65..b4b2dcebf 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1003CSharp11UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1003CSharp11UnitTests.cs @@ -3,9 +3,92 @@ namespace StyleCop.Analyzers.Test.CSharp11.SpacingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp10.SpacingRules; + using Xunit; + + using static StyleCop.Analyzers.SpacingRules.SA1003SymbolsMustBeSpacedCorrectly; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.SpacingRules.SA1003SymbolsMustBeSpacedCorrectly, + StyleCop.Analyzers.SpacingRules.SA1003CodeFixProvider>; public partial class SA1003CSharp11UnitTests : SA1003CSharp10UnitTests { + [Fact] + [WorkItem(3822, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3822")] + public async Task TestUnsignedRightShiftAssignmentOperatorAsync() + { + var testCode = @" +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod(int x) + { + x{|#0:>>>=|}0; + } + } +} +"; + + var fixedCode = @" +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod(int x) + { + x >>>= 0; + } + } +} +"; + + var expected = new[] + { + Diagnostic(DescriptorPrecededByWhitespace).WithLocation(0).WithArguments(">>>="), + Diagnostic(DescriptorFollowedByWhitespace).WithLocation(0).WithArguments(">>>="), + }; + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + [WorkItem(3822, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3822")] + public async Task TestUnsignedRightShiftOperatorAsync() + { + var testCode = @" +namespace TestNamespace +{ + public class TestClass + { + public int TestMethod(int x) + { + return x{|#0:>>>|}0; + } + } +} +"; + + var fixedCode = @" +namespace TestNamespace +{ + public class TestClass + { + public int TestMethod(int x) + { + return x >>> 0; + } + } +} +"; + + var expected = new[] + { + Diagnostic(DescriptorPrecededByWhitespace).WithLocation(0).WithArguments(">>>"), + Diagnostic(DescriptorFollowedByWhitespace).WithLocation(0).WithArguments(">>>"), + }; + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1003CSharp8UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1003CSharp8UnitTests.cs index 39133b371..c2f49151e 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1003CSharp8UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1003CSharp8UnitTests.cs @@ -66,5 +66,81 @@ public void TestMethod() FixedCode = fixedCode, }.RunAsync(CancellationToken.None).ConfigureAwait(false); } + + [Fact] + [WorkItem(3822, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3822")] + public async Task TestNullCoalescingAssignmentOperatorAsync() + { + var testCode = @" +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod(int? x) + { + x{|#0:??=|}0; + } + } +} +"; + + var fixedCode = @" +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod(int? x) + { + x ??= 0; + } + } +} +"; + + var expected = new[] + { + Diagnostic(DescriptorPrecededByWhitespace).WithLocation(0).WithArguments("??="), + Diagnostic(DescriptorFollowedByWhitespace).WithLocation(0).WithArguments("??="), + }; + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + [WorkItem(3822, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3822")] + public async Task TestNullForgivingOperatorAsync() + { + var testCode = @" +namespace TestNamespace +{ + public class TestClass + { + public string TestMethod(string? x) + { + return x {|#0:!|} ; + } + } +} +"; + + var fixedCode = @" +namespace TestNamespace +{ + public class TestClass + { + public string TestMethod(string? x) + { + return x!; + } + } +} +"; + + var expected = new[] + { + Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(0).WithArguments("!"), + Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(0).WithArguments("!"), + }; + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs index 920ac7d12..b1d189550 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Lightup/SyntaxKindEx.cs @@ -27,7 +27,9 @@ internal static class SyntaxKindEx public const SyntaxKind IsPatternExpression = (SyntaxKind)8657; public const SyntaxKind RangeExpression = (SyntaxKind)8658; public const SyntaxKind ImplicitObjectCreationExpression = (SyntaxKind)8659; + public const SyntaxKind UnsignedRightShiftExpression = (SyntaxKind)8692; public const SyntaxKind CoalesceAssignmentExpression = (SyntaxKind)8725; + public const SyntaxKind UnsignedRightShiftAssignmentExpression = (SyntaxKind)8726; public const SyntaxKind IndexExpression = (SyntaxKind)8741; public const SyntaxKind DefaultLiteralExpression = (SyntaxKind)8755; public const SyntaxKind LocalFunctionStatement = (SyntaxKind)8830; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs index 9e0d5316e..ec9ea57fd 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs @@ -86,6 +86,7 @@ internal class SA1003SymbolsMustBeSpacedCorrectly : DiagnosticAnalyzer SyntaxKind.GreaterThanOrEqualExpression, SyntaxKind.LeftShiftExpression, SyntaxKind.RightShiftExpression, + SyntaxKindEx.UnsignedRightShiftExpression, SyntaxKind.AddExpression, SyntaxKind.SubtractExpression, SyntaxKind.MultiplyExpression, @@ -105,7 +106,10 @@ internal class SA1003SymbolsMustBeSpacedCorrectly : DiagnosticAnalyzer SyntaxKind.AddressOfExpression); private static readonly ImmutableArray PostfixUnaryExpressionKinds = - ImmutableArray.Create(SyntaxKind.PostIncrementExpression, SyntaxKind.PostDecrementExpression); + ImmutableArray.Create( + SyntaxKind.PostIncrementExpression, + SyntaxKind.PostDecrementExpression, + SyntaxKindEx.SuppressNullableWarningExpression); private static readonly ImmutableArray AssignmentExpressionKinds = ImmutableArray.Create( @@ -114,11 +118,13 @@ internal class SA1003SymbolsMustBeSpacedCorrectly : DiagnosticAnalyzer SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression, + SyntaxKindEx.UnsignedRightShiftAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.SubtractAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, + SyntaxKindEx.CoalesceAssignmentExpression, SyntaxKind.SimpleAssignmentExpression); private static readonly Action ConstructorDeclarationAction = HandleConstructorDeclaration;