diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/LayoutRules/SA1516CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/LayoutRules/SA1516CSharp9UnitTests.cs
index 2fb3c591d..1cd926c5a 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/LayoutRules/SA1516CSharp9UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/LayoutRules/SA1516CSharp9UnitTests.cs
@@ -24,7 +24,7 @@ public class SA1516CSharp9UnitTests : SA1516CSharp8UnitTests
/// A representing the asynchronous unit test.
[Fact]
[WorkItem(3242, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3242")]
- public async Task TestStatementSpacingInTopLevelProgramAsync()
+ public async Task TestUsingAndGlobalStatementSpacingInTopLevelProgramAsync()
{
var testCode = @"using System;
using System.Threading;
@@ -55,5 +55,64 @@ public async Task TestStatementSpacingInTopLevelProgramAsync()
FixedCode = fixedCode,
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
}
+
+ ///
+ /// Verifies that SA1516 is not reported between global statement in top-level programs.
+ ///
+ /// A representing the asynchronous unit test.
+ [Fact]
+ [WorkItem(3351, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3351")]
+ public async Task TestGlobalStatementSpacingInTopLevelProgramAsync()
+ {
+ var testCode = @"int i = 0;
+return i;
+";
+
+ await new CSharpTest(LanguageVersion.CSharp9)
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net50,
+ TestState =
+ {
+ OutputKind = OutputKind.ConsoleApplication,
+ Sources = { testCode },
+ },
+ }.RunAsync(CancellationToken.None).ConfigureAwait(false);
+ }
+
+ ///
+ /// Verifies that SA1516 is reported between global statement and record declaration in top-level programs.
+ ///
+ /// A representing the asynchronous unit test.
+ [Fact]
+ public async Task TestGlobalStatementAndRecordSpacingInTopLevelProgramAsync()
+ {
+ var testCode = @"return 0;
+{|#0:record|} A();
+";
+
+ var fixedCode = @"return 0;
+
+record A();
+";
+
+ await new CSharpTest(LanguageVersion.CSharp9)
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net50,
+ TestState =
+ {
+ OutputKind = OutputKind.ConsoleApplication,
+ Sources = { testCode },
+ ExpectedDiagnostics =
+ {
+ // /0/Test0.cs(2,1): warning SA1516: Elements should be separated by blank line
+ Diagnostic().WithLocation(0),
+
+ // /0/Test0.cs(2,1): warning SA1516: Elements should be separated by blank line
+ Diagnostic().WithLocation(0),
+ },
+ },
+ FixedCode = fixedCode,
+ }.RunAsync(CancellationToken.None).ConfigureAwait(false);
+ }
}
}
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs
index ef1e496ab..a3a8ecc4e 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs
@@ -295,6 +295,12 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi
{
for (int i = 1; i < members.Count; i++)
{
+ // Don't report between global statements
+ if (members[i - 1].IsKind(SyntaxKind.GlobalStatement) && members[i].IsKind(SyntaxKind.GlobalStatement))
+ {
+ continue;
+ }
+
if (!members[i - 1].ContainsDiagnostics && !members[i].ContainsDiagnostics)
{
// Report if