From cca960a659af7af5d603220da5e7fc53d94076e8 Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Sun, 22 May 2022 19:26:24 +0200 Subject: [PATCH 1/7] Add support for file scoped namespace to SA1516. --- .../LayoutRules/SA1516CSharp10UnitTests.cs | 128 ++++++++++++++++++ ...A1516ElementsMustBeSeparatedByBlankLine.cs | 17 +++ 2 files changed, 145 insertions(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs index baa1ba110..10b5333cf 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -3,9 +3,137 @@ namespace StyleCop.Analyzers.Test.CSharp10.LayoutRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.LayoutRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.LayoutRules.SA1516ElementsMustBeSeparatedByBlankLine, + StyleCop.Analyzers.LayoutRules.SA1516CodeFixProvider>; public class SA1516CSharp10UnitTests : SA1516CSharp9UnitTests { + private const string CorrectCode = @"extern alias corlib; + +using System; +using System.Linq; +using a = System.Collections.Generic; + +namespace Foo; + +public class Bar +{ + public string Test1; + public string Test2; + public string Test3; + + public string TestProperty1 { get; set; } + + public string TestProperty2 { get; set; } + /// + /// A summary. + /// + public string TestProperty3 { get; set; } + + public string TestProperty4 + { + get + { + return Test1; + } + + set + { + Test1 = value; + } + } + + public string FooValue, BarValue; + + [Obsolete] + public enum TestEnum + { + Value1, + Value2 + } +} + +public enum Foobar +{ + +} +"; + + /// + /// Verifies that SA1516 is not reported for code with correct blank lines. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestFileScopedNamespaceCorrectSpacingAsync() + { + await VerifyCSharpDiagnosticAsync(CorrectCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Verifies that SA1516 is reported for code with missing correct blank lines. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestFileScopedNamespaceWrongSpacingAsync() + { + var testCode = @"extern alias corlib; +{|#0:using|} System; +using System.Linq; +using a = System.Collections.Generic; +{|#1:namespace|} Foo; +{|#2:public|} class Bar +{ +} +{|#3:public|} enum Foobar +{ +} +"; + + var fixedCode = @"extern alias corlib; + +using System; +using System.Linq; +using a = System.Collections.Generic; + +namespace Foo; + +public class Bar +{ +} + +public enum Foobar +{ +} +"; + + var test = new CSharpTest(LanguageVersion.CSharp10) + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + TestState = + { + OutputKind = OutputKind.DynamicallyLinkedLibrary, + Sources = { testCode }, + }, + FixedCode = fixedCode, + }; + var expectedDiagnostic = new[] { + Diagnostic().WithLocation(0), + Diagnostic().WithLocation(1), + Diagnostic().WithLocation(2), + Diagnostic().WithLocation(3), + }; + test.TestState.ExpectedDiagnostics.AddRange(expectedDiagnostic); + await test.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs index a3a8ecc4e..728dd8bd3 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs @@ -15,6 +15,7 @@ namespace StyleCop.Analyzers.LayoutRules using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -87,6 +88,7 @@ internal class SA1516ElementsMustBeSeparatedByBlankLine : DiagnosticAnalyzer private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; private static readonly Action CompilationUnitAction = HandleCompilationUnit; private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action FileScopedNamespaceDeclarationAction = HandleFileScopedNamespaceDeclaration; private static readonly Action BasePropertyDeclarationAction = HandleBasePropertyDeclaration; private static readonly ImmutableDictionary DiagnosticProperties = ImmutableDictionary.Empty.Add(CodeFixActionKey, InsertBlankLineValue); @@ -127,6 +129,7 @@ public override void Initialize(AnalysisContext context) context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(FileScopedNamespaceDeclarationAction, SyntaxKindEx.FileScopedNamespaceDeclaration); context.RegisterSyntaxNodeAction(BasePropertyDeclarationAction, SyntaxKinds.BasePropertyDeclaration); } @@ -209,6 +212,20 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty } } + private static void HandleFileScopedNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + { + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; + + var members = namespaceDeclaration.Members; + + HandleMemberList(context, members); + + if (members.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, members[0]); + } + } + private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; From edfbcf1fdb286aaa50ae2a9cd1e3e471a5ca91ea Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Mon, 23 May 2022 17:23:47 +0200 Subject: [PATCH 2/7] fix style --- .../LayoutRules/SA1516CSharp10UnitTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs index 10b5333cf..1712d9ae2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -126,7 +126,8 @@ public enum Foobar }, FixedCode = fixedCode, }; - var expectedDiagnostic = new[] { + var expectedDiagnostic = new[] + { Diagnostic().WithLocation(0), Diagnostic().WithLocation(1), Diagnostic().WithLocation(2), From 1bcb856942b88c118b3267024f2aa309e8cd13b9 Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Tue, 24 May 2022 12:48:51 +0200 Subject: [PATCH 3/7] add more tests and fix extern alias --- .../LayoutRules/SA1516CodeFixProvider.cs | 5 + .../LayoutRules/SA1516CSharp10UnitTests.cs | 210 +++++++++++++----- ...A1516ElementsMustBeSeparatedByBlankLine.cs | 22 ++ 3 files changed, 184 insertions(+), 53 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1516CodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1516CodeFixProvider.cs index 73c5bcfb7..b8d7940fa 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1516CodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1516CodeFixProvider.cs @@ -152,6 +152,11 @@ private static SyntaxNode GetRelevantNode(SyntaxNode innerNode) return currentNode; } + if (currentNode is ExternAliasDirectiveSyntax) + { + return currentNode; + } + currentNode = currentNode.Parent; } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs index 1712d9ae2..570812bb7 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -16,96 +16,202 @@ namespace StyleCop.Analyzers.Test.CSharp10.LayoutRules public class SA1516CSharp10UnitTests : SA1516CSharp9UnitTests { - private const string CorrectCode = @"extern alias corlib; + /// + /// Verifies that SA1516 is reported for usings and extern alias outside a file scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestThatDiagnosticIIsReportedOnUsingsAndExternAliasOutsideFileScopedNamespaceAsync() + { + var testCode = @"extern alias corlib; +[|using|] System; +using System.Linq; +using a = System.Collections; +[|namespace|] Foo; +"; + + var fixedCode = @"extern alias corlib; using System; using System.Linq; -using a = System.Collections.Generic; +using a = System.Collections; namespace Foo; +"; -public class Bar -{ - public string Test1; - public string Test2; - public string Test3; + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + } - public string TestProperty1 { get; set; } + /// + /// Verifies that SA1516 is reported for usings inside a file scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestThatDiagnosticIIsReportedOnSpacingWithUsingsInsideFileScopedNamespaceAsync() + { + var testCode = @"namespace Foo; +[|using|] System; +using System.Linq; +using a = System.Collections; +"; - public string TestProperty2 { get; set; } - /// - /// A summary. - /// - public string TestProperty3 { get; set; } + var fixedCode = @"namespace Foo; - public string TestProperty4 - { - get - { - return Test1; +using System; +using System.Linq; +using a = System.Collections; +"; + + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); } - set + /// + /// Verifies that SA1516 is reported for member declarations inside a file scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestThatDiagnosticIIsReportedOnMemberDeclarationsInsideFileScopedNamespaceAsync() { - Test1 = value; - } - } + var testCode = @"namespace Foo; +[|public|] class Bar +{ +} +[|public|] enum Foobar +{ +} +"; - public string FooValue, BarValue; + var fixedCode = @"namespace Foo; - [Obsolete] - public enum TestEnum - { - Value1, - Value2 - } +public class Bar +{ } public enum Foobar { +} +"; + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + } + + /// + /// Verifies that SA1516 is reported for usings and member declarations inside a file scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestThatDiagnosticIIsReportedOnUsingsAndMemberDeclarationsInsideFileScopedNamespaceAsync() + { + var testCode = @"namespace Foo; +[|using|] System; +using System.Linq; +using a = System.Collections; +[|public|] class Bar +{ +} +[|public|] enum Foobar +{ } "; + var fixedCode = @"namespace Foo; + +using System; +using System.Linq; +using a = System.Collections; + +public class Bar +{ +} + +public enum Foobar +{ +} +"; + + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + } + /// - /// Verifies that SA1516 is not reported for code with correct blank lines. + /// Verifies that SA1516 is reported extern alias inside a file scoped namespace. /// /// A representing the asynchronous unit test. [Fact] [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] - public async Task TestFileScopedNamespaceCorrectSpacingAsync() + public async Task TestThatDiagnosticIIsReportedOnExternAliasInsideFileScopedNamespaceAsync() { - await VerifyCSharpDiagnosticAsync(CorrectCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + var testCode = @"namespace Foo; +[|extern|] alias corlib; +"; + + var fixedCode = @"namespace Foo; + +extern alias corlib; +"; + + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); } /// - /// Verifies that SA1516 is reported for code with missing correct blank lines. + /// Verifies that SA1516 is reported extern alias and usings inside a file scoped namespace. /// /// A representing the asynchronous unit test. [Fact] [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] - public async Task TestFileScopedNamespaceWrongSpacingAsync() + public async Task TestThatDiagnosticIIsReportedOnExternAliasAndUsingsInsideFileScopedNamespaceAsync() { - var testCode = @"extern alias corlib; -{|#0:using|} System; + var testCode = @"namespace Foo; +[|extern|] alias corlib; +[|using|] System; using System.Linq; -using a = System.Collections.Generic; -{|#1:namespace|} Foo; -{|#2:public|} class Bar +using a = System.Collections; +"; + + var fixedCode = @"namespace Foo; + +extern alias corlib; + +using System; +using System.Linq; +using a = System.Collections; +"; + + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + } + + /// + /// Verifies that SA1516 is reported extern alias, usings and member declarations + /// inside a file scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3512, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3512")] + public async Task TestThatDiagnosticIIsReportedOnExternAliasUsingsAndMemberDeclarationsInsideFileScopedNamespaceAsync() + { + var testCode = @"namespace Foo; +[|extern|] alias corlib; +[|using|] System; +using System.Linq; +using a = System.Collections; +[|public|] class Bar { } -{|#3:public|} enum Foobar +[|public|] enum Foobar { } "; - var fixedCode = @"extern alias corlib; + var fixedCode = @"namespace Foo; + +extern alias corlib; using System; using System.Linq; -using a = System.Collections.Generic; - -namespace Foo; +using a = System.Collections; public class Bar { @@ -116,6 +222,11 @@ public enum Foobar } "; + await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + } + + private static Task VerifyCSharpFixAsync(string testCode, string fixedCode) + { var test = new CSharpTest(LanguageVersion.CSharp10) { ReferenceAssemblies = ReferenceAssemblies.Net.Net50, @@ -126,15 +237,8 @@ public enum Foobar }, FixedCode = fixedCode, }; - var expectedDiagnostic = new[] - { - Diagnostic().WithLocation(0), - Diagnostic().WithLocation(1), - Diagnostic().WithLocation(2), - Diagnostic().WithLocation(3), - }; - test.TestState.ExpectedDiagnostics.AddRange(expectedDiagnostic); - await test.RunAsync(CancellationToken.None).ConfigureAwait(false); + + return test.RunAsync(CancellationToken.None); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs index 728dd8bd3..fb8199b7c 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs @@ -216,13 +216,35 @@ private static void HandleFileScopedNamespaceDeclaration(SyntaxNodeAnalysisConte { var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; + var usings = namespaceDeclaration.Usings; var members = namespaceDeclaration.Members; + HandleUsings(context, usings, settings); HandleMemberList(context, members); + if (namespaceDeclaration.Externs.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, namespaceDeclaration.Externs[0]); + } + + if (namespaceDeclaration.Usings.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, namespaceDeclaration.Usings[0]); + + if (namespaceDeclaration.Externs.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Externs[namespaceDeclaration.Externs.Count - 1], namespaceDeclaration.Usings[0]); + } + } + if (members.Count > 0) { ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, members[0]); + + if (namespaceDeclaration.Usings.Count > 0) + { + ReportIfThereIsNoBlankLine(context, usings[usings.Count - 1], members[0]); + } } } From c2d0129a7d78fc2931f4ba4b46a677d6837004e2 Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Sun, 18 Jun 2023 10:13:18 +0200 Subject: [PATCH 4/7] restore changes lost in merge --- .../SA1516ElementsMustBeSeparatedByBlankLine.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs index bd1ea17ea..fd8125ad9 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs @@ -15,6 +15,7 @@ namespace StyleCop.Analyzers.LayoutRules using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -87,6 +88,7 @@ internal class SA1516ElementsMustBeSeparatedByBlankLine : DiagnosticAnalyzer private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; private static readonly Action CompilationUnitAction = HandleCompilationUnit; private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action FileScopedNamespaceDeclarationAction = HandleFileScopedNamespaceDeclaration; private static readonly Action BasePropertyDeclarationAction = HandleBasePropertyDeclaration; private static readonly ImmutableDictionary DiagnosticProperties = ImmutableDictionary.Empty.Add(CodeFixActionKey, InsertBlankLineValue); @@ -129,6 +131,7 @@ public override void Initialize(AnalysisContext context) context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(FileScopedNamespaceDeclarationAction, SyntaxKindEx.FileScopedNamespaceDeclaration); context.RegisterSyntaxNodeAction(BasePropertyDeclarationAction, SyntaxKinds.BasePropertyDeclaration); }); } @@ -212,6 +215,20 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty } } + private static void HandleFileScopedNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + { + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; + + var members = namespaceDeclaration.Members; + + HandleMemberList(context, members); + + if (members.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, members[0]); + } + } + private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; From a6efbfdfcef4e2e7034a4286258f8c477087259e Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Sun, 18 Jun 2023 10:16:36 +0200 Subject: [PATCH 5/7] restore more changes lost in merge --- ...A1516ElementsMustBeSeparatedByBlankLine.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs index fd8125ad9..2ac731989 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs @@ -219,13 +219,35 @@ private static void HandleFileScopedNamespaceDeclaration(SyntaxNodeAnalysisConte { var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; + var usings = namespaceDeclaration.Usings; var members = namespaceDeclaration.Members; + HandleUsings(context, usings, settings); HandleMemberList(context, members); + if (namespaceDeclaration.Externs.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, namespaceDeclaration.Externs[0]); + } + + if (namespaceDeclaration.Usings.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, namespaceDeclaration.Usings[0]); + + if (namespaceDeclaration.Externs.Count > 0) + { + ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Externs[namespaceDeclaration.Externs.Count - 1], namespaceDeclaration.Usings[0]); + } + } + if (members.Count > 0) { ReportIfThereIsNoBlankLine(context, namespaceDeclaration.Name, members[0]); + + if (namespaceDeclaration.Usings.Count > 0) + { + ReportIfThereIsNoBlankLine(context, usings[usings.Count - 1], members[0]); + } } } From 7a1ffddd3b4ff29376c9af6b8c6b90e193e385ad Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Sun, 18 Jun 2023 10:20:36 +0200 Subject: [PATCH 6/7] review fixes 1. part --- .../LayoutRules/SA1516CSharp10UnitTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs index 570812bb7..a659053ef 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -227,12 +227,11 @@ public enum Foobar private static Task VerifyCSharpFixAsync(string testCode, string fixedCode) { - var test = new CSharpTest(LanguageVersion.CSharp10) + var test = new CSharpTest() { - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, TestState = { - OutputKind = OutputKind.DynamicallyLinkedLibrary, Sources = { testCode }, }, FixedCode = fixedCode, From 67bd1ba0d0e55f2ed2ea8a2a48343d633d2e2801 Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Sun, 18 Jun 2023 10:22:16 +0200 Subject: [PATCH 7/7] remove parentheses from constructor call --- .../LayoutRules/SA1516CSharp10UnitTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs index a659053ef..f6020b139 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -227,7 +227,7 @@ public enum Foobar private static Task VerifyCSharpFixAsync(string testCode, string fixedCode) { - var test = new CSharpTest() + var test = new CSharpTest { ReferenceAssemblies = ReferenceAssemblies.Net.Net60, TestState =