diff --git a/ChangeLog.md b/ChangeLog.md index eb95598a7c..746500a917 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Replace type declaration's empty braces with semicolon ([RCS1251](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1251) ([PR](https://github.com/dotnet/roslynator/pull/1323)) +- Replace type declaration's empty braces with semicolon ([RCS1251](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1251) ([PR](https://github.com/dotnet/roslynator/pull/1323), [PR](https://github.com/dotnet/roslynator/pull/1327)) ## [4.7.0] - 2023-12-03 diff --git a/src/Analyzers.CodeFixes/CSharp/CodeFixes/RemoveUnnecessaryBracesCodeFixProvider.cs b/src/Analyzers.CodeFixes/CSharp/CodeFixes/RemoveUnnecessaryBracesCodeFixProvider.cs index a346892a34..2d971806a5 100644 --- a/src/Analyzers.CodeFixes/CSharp/CodeFixes/RemoveUnnecessaryBracesCodeFixProvider.cs +++ b/src/Analyzers.CodeFixes/CSharp/CodeFixes/RemoveUnnecessaryBracesCodeFixProvider.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; using Roslynator.CodeFixes; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; @@ -41,13 +42,22 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) "Remove unnecessary braces", ct => { - TypeDeclarationSyntax newTypeDeclaration = typeDeclaration + TypeDeclarationSyntax newNode = typeDeclaration .WithOpenBraceToken(default) .WithCloseBraceToken(default) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)) - .WithTrailingTrivia(typeDeclaration.GetTrailingTrivia()); + .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); - return document.ReplaceNodeAsync(typeDeclaration, newTypeDeclaration, ct); + SyntaxTriviaList trailing = typeDeclaration + .DescendantTrivia(TextSpan.FromBounds( + typeDeclaration.OpenBraceToken.GetPreviousToken().Span.End, + typeDeclaration.CloseBraceToken.SpanStart)) + .ToSyntaxTriviaList() + .EmptyIfWhitespace() + .AddRange(typeDeclaration.CloseBraceToken.TrailingTrivia); + + newNode = newNode.WithTrailingTrivia(trailing); + + return document.ReplaceNodeAsync(typeDeclaration, newNode, ct); }, GetEquivalenceKey(diagnostic)); diff --git a/src/Tests/Analyzers.Tests/RCS1251RemoveUnnecessaryBracesTests.cs b/src/Tests/Analyzers.Tests/RCS1251RemoveUnnecessaryBracesTests.cs index 9a231acaff..d5a6de11cb 100644 --- a/src/Tests/Analyzers.Tests/RCS1251RemoveUnnecessaryBracesTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1251RemoveUnnecessaryBracesTests.cs @@ -74,6 +74,42 @@ class C; "); } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveUnnecessaryBraces)] + public async Task Test_Class_WithBaseClass() + { + await VerifyDiagnosticAndFixAsync(@" +namespace N +{ + class C : object + [|{|] + } +} +", @" +namespace N +{ + class C : object; +} +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveUnnecessaryBraces)] + public async Task Test_Class_WhereConstraint() + { + await VerifyDiagnosticAndFixAsync(@" +namespace N +{ + class C where T : new() + [|{|] + } +} +", @" +namespace N +{ + class C where T : new(); +} +"); + } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveUnnecessaryBraces)] public async Task Test_Struct() { @@ -135,4 +171,17 @@ record struct R } "); } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveUnnecessaryBraces)] + public async Task TestNoDiagnostic_Class_WithParameterList() + { + await VerifyNoDiagnosticAsync(@" +namespace N +{ + class C(string P) + { + } +} +", options: Options.AddAllowedCompilerDiagnosticId("CS9113")); + } }