Skip to content

Commit

Permalink
Add blank line after file scoped namespace declaration (RCS0060) (dot…
Browse files Browse the repository at this point in the history
  • Loading branch information
josefpihrt authored and JochemHarmes committed Oct 30, 2023
1 parent 28c5f9d commit 5b30f8d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix [RCS1084](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1084.md) ([#1006](https://github.com/josefpihrt/roslynator/pull/1006)).
- Fix [RCS1244](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1244.md) ([#1007](https://github.com/josefpihrt/roslynator/pull/1007)).
- [CLI] Add nullable reference type modifier when creating a list of symbols (`list-symbols` command) ([#1013](https://github.com/josefpihrt/roslynator/pull/1013)).
- Add/remove blank line after file scoped namespace declaration ([RCS0060](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS0060.md)) ([#1014](https://github.com/josefpihrt/roslynator/pull/1014)).

## [4.2.0] - 2022-11-27

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,26 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)

Document document = context.Document;
Diagnostic diagnostic = context.Diagnostics[0];
MemberDeclarationSyntax member = fileScopedNamespace.Members[0];
BlankLineStyle style = BlankLineAfterFileScopedNamespaceDeclarationAnalyzer.GetCurrentStyle(fileScopedNamespace, member);
SyntaxNode node = BlankLineAfterFileScopedNamespaceDeclarationAnalyzer.GetNodeAfterNamespaceDeclaration(fileScopedNamespace);
BlankLineStyle style = BlankLineAfterFileScopedNamespaceDeclarationAnalyzer.GetCurrentStyle(fileScopedNamespace, node);

if (style == BlankLineStyle.Add)
{
CodeAction codeAction = CodeAction.Create(
CodeFixTitles.AddBlankLine,
ct =>
{
MemberDeclarationSyntax newMember;
SyntaxNode newNode;
if (!fileScopedNamespace.SemicolonToken.TrailingTrivia.Contains(SyntaxKind.EndOfLineTrivia))
{
newMember = member.PrependToLeadingTrivia(new SyntaxTrivia[] { CSharpFactory.NewLine(), CSharpFactory.NewLine() });
newNode = node.PrependToLeadingTrivia(new SyntaxTrivia[] { CSharpFactory.NewLine(), CSharpFactory.NewLine() });
}
else
{
newMember = member.PrependEndOfLineToLeadingTrivia();
newNode = node.PrependEndOfLineToLeadingTrivia();
}

return document.ReplaceNodeAsync(member, newMember, ct);
return document.ReplaceNodeAsync(node, newNode, ct);
},
GetEquivalenceKey(diagnostic));

Expand All @@ -63,7 +63,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
CodeAction codeAction = CodeAction.Create(
CodeFixTitles.RemoveBlankLine,
ct => CodeFixHelpers.RemoveBlankLinesBeforeAsync(document, member.GetFirstToken(), ct),
ct => CodeFixHelpers.RemoveBlankLinesBeforeAsync(document, node.GetFirstToken(), ct),
GetEquivalenceKey(diagnostic));

context.RegisterCodeFix(codeAction, diagnostic);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,27 @@ private static void AnalyzeFileScopedNamespaceDeclaration(SyntaxNodeAnalysisCont
{
var namespaceDeclaration = (FileScopedNamespaceDeclarationSyntax)context.Node;

MemberDeclarationSyntax memberDeclaration = namespaceDeclaration.Members.FirstOrDefault();

if (memberDeclaration is null)
return;
SyntaxNode node = GetNodeAfterNamespaceDeclaration(namespaceDeclaration);

BlankLineStyle style = context.GetBlankLineAfterFileScopedNamespaceDeclaration();

if (style == BlankLineStyle.None)
return;

BlankLineStyle currentStyle = GetCurrentStyle(namespaceDeclaration, memberDeclaration);
BlankLineStyle currentStyle = GetCurrentStyle(namespaceDeclaration, node);

if (style != currentStyle)
return;

context.ReportDiagnostic(
DiagnosticRules.BlankLineAfterFileScopedNamespaceDeclaration,
Location.Create(namespaceDeclaration.SyntaxTree, new TextSpan(memberDeclaration.FullSpan.Start, 0)),
Location.Create(namespaceDeclaration.SyntaxTree, new TextSpan(node.FullSpan.Start, 0)),
(style == BlankLineStyle.Add) ? "Add" : "Remove");
}

internal static BlankLineStyle GetCurrentStyle(
FileScopedNamespaceDeclarationSyntax namespaceDeclaration,
MemberDeclarationSyntax memberDeclaration)
SyntaxNode node)
{
(bool add, bool remove) = AnalyzeTrailingTrivia();

Expand Down Expand Up @@ -109,7 +106,7 @@ internal static BlankLineStyle GetCurrentStyle(

BlankLineStyle AnalyzeLeadingTrivia()
{
SyntaxTriviaList.Enumerator en = memberDeclaration.GetLeadingTrivia().GetEnumerator();
SyntaxTriviaList.Enumerator en = node.GetLeadingTrivia().GetEnumerator();

if (!en.MoveNext())
return BlankLineStyle.Add;
Expand All @@ -132,4 +129,14 @@ BlankLineStyle AnalyzeLeadingTrivia()
return BlankLineStyle.None;
}
}

internal static SyntaxNode GetNodeAfterNamespaceDeclaration(FileScopedNamespaceDeclarationSyntax namespaceDeclaration)
{
MemberDeclarationSyntax memberDeclaration = namespaceDeclaration.Members.FirstOrDefault();
UsingDirectiveSyntax usingDirective = namespaceDeclaration.Usings.FirstOrDefault();

return (usingDirective?.SpanStart > namespaceDeclaration.SpanStart)
? usingDirective
: memberDeclaration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,27 @@ class C
", options: Options.AddConfigOption(ConfigOptionKeys.BlankLineAfterFileScopedNamespaceDeclaration, true));
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.BlankLineAfterFileScopedNamespaceDeclaration)]
public async Task Test_RemoveEmptyLine_UsingAfter()
{
await VerifyDiagnosticAndFixAsync(@"
namespace N;
[||]using System;
public class C
{
}
", @"
namespace N;
using System;
public class C
{
}
", options: Options.AddConfigOption(ConfigOptionKeys.BlankLineAfterFileScopedNamespaceDeclaration, true));
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.BlankLineAfterFileScopedNamespaceDeclaration)]
public async Task Test_RemoveEmptyLine()
{
Expand Down

0 comments on commit 5b30f8d

Please sign in to comment.