Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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