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
24 changes: 19 additions & 5 deletions src/Atc.Analyzer/Rules/Style/BlankLineBetweenCodeBlocksAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ private static int CountBlankLinesBetween(
StatementSyntax second)
{
// Get the end line of the first statement
var firstEndLine = first.GetLocation().GetLineSpan().EndLinePosition.Line;
var firstEndLine = first
.GetLocation()
.GetLineSpan()
.EndLinePosition
.Line;

// Get the start line of the second statement (or its first non-whitespace leading trivia)
var secondStartLine = GetEffectiveStartLine(second);
Expand All @@ -117,17 +121,23 @@ private static int CountBlankLinesBetween(

private static int GetEffectiveStartLine(StatementSyntax statement)
{
// Check leading trivia for comments - if there's a comment, use its line position
// Check leading trivia for comments or preprocessor directives - if found, use its line position
var leadingTrivia = statement.GetLeadingTrivia();

foreach (var trivia in leadingTrivia)
{
if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.MultiLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) ||
trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia))
trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia) ||
trivia.IsKind(SyntaxKind.IfDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.ElseDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.ElifDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.EndIfDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.RegionDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.EndRegionDirectiveTrivia))
{
// Return the line where the comment starts
// Return the line where the trivia starts
return trivia
.GetLocation()?
.GetLineSpan()
Expand All @@ -140,6 +150,10 @@ private static int GetEffectiveStartLine(StatementSyntax statement)
}
}

return statement.GetLocation().GetLineSpan().StartLinePosition.Line;
return statement
.GetLocation()
.GetLineSpan()
.StartLinePosition
.Line;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
context.Diagnostics);
}

[SuppressMessage("Design", "MA0051:Method is too long", Justification = "OK.")]
private static async Task<Document> FixBlankLinesAsync(
Document document,
StatementSyntax secondStatement,
CancellationToken cancellationToken)
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var root = await document
.GetSyntaxRootAsync(cancellationToken)
.ConfigureAwait(false);

if (root is null)
{
return document;
Expand All @@ -85,22 +89,28 @@ private static async Task<Document> FixBlankLinesAsync(
// Get the leading trivia of the second statement
var leadingTrivia = secondStatement.GetLeadingTrivia();

// Separate comments from whitespace
var comments = new List<SyntaxTrivia>();
var hasFoundComment = false;
// Separate comments and preprocessor directives from whitespace
var preservedTrivia = new List<SyntaxTrivia>();
var hasFoundPreservedTrivia = false;

foreach (var trivia in leadingTrivia)
{
if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.MultiLineCommentTrivia))
trivia.IsKind(SyntaxKind.MultiLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.IfDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.ElseDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.ElifDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.EndIfDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.RegionDirectiveTrivia) ||
trivia.IsKind(SyntaxKind.EndRegionDirectiveTrivia))
{
hasFoundComment = true;
comments.Add(trivia);
hasFoundPreservedTrivia = true;
preservedTrivia.Add(trivia);
}
else if (hasFoundComment && trivia.IsKind(SyntaxKind.EndOfLineTrivia))
else if (hasFoundPreservedTrivia && trivia.IsKind(SyntaxKind.EndOfLineTrivia))
{
// Keep the newline after the comment
comments.Add(trivia);
// Keep the newline after the preserved trivia
preservedTrivia.Add(trivia);
}
}

Expand All @@ -113,11 +123,11 @@ private static async Task<Document> FixBlankLinesAsync(
endOfLine, // This is the blank line
};

// Add back any comments with their proper trivia
if (comments.Count > 0)
// Add back any preserved trivia (comments, preprocessor directives) with their proper trivia
if (preservedTrivia.Count > 0)
{
newTriviaList.Add(SyntaxFactory.Whitespace(indentation));
newTriviaList.AddRange(comments);
newTriviaList.AddRange(preservedTrivia);
}

// Add the indentation for the statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,4 +432,32 @@ public void Method()

await AnalyzerVerifier.VerifyAnalyzerAsync(code);
}

[Fact]
public async Task NoDiagnostic_BlockStatementWithPreprocessorDirectiveBetween()
{
const string code = """
public class Sample
{
public void Method(string value)
{
if (string.IsNullOrEmpty(value))
{
return;
}

#if NETSTANDARD2_0
return;
#else
if (value.Length == 1)
{
return;
}
#endif
}
}
""";

await AnalyzerVerifier.VerifyAnalyzerAsync(code);
}
}