From 46848f03a8e6df0f3e8bc21fb504adad39cd77bc Mon Sep 17 00:00:00 2001 From: Jakub Linhart Date: Tue, 24 May 2022 12:48:51 +0200 Subject: [PATCH] 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 cafeb1d15..af03ff6e1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/LayoutRules/SA1516CSharp10UnitTests.cs @@ -18,96 +18,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 { @@ -118,6 +224,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, @@ -128,15 +239,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]); + } } }