From a9ec12fcb7560a6bd0b709e80e8d3b2f17d9e201 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 20:45:49 -0800 Subject: [PATCH 01/16] Simplify BaseNamespaceDeclarationSyntax callbacks --- .../StyleCop.Analyzers/Helpers/SyntaxKinds.cs | 13 +++++++++++ ...sMustBePlacedBeforeOtherUsingDirectives.cs | 22 ++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxKinds.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxKinds.cs index 0451f4056..503df056c 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxKinds.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxKinds.cs @@ -10,6 +10,19 @@ namespace StyleCop.Analyzers.Helpers internal static class SyntaxKinds { + /// + /// Gets a collection of values which appear in the syntax tree as a + /// . + /// + /// + /// A collection of values which appear in the syntax tree as a + /// . + /// + public static ImmutableArray BaseNamespaceDeclaration { get; } = + ImmutableArray.Create( + SyntaxKind.NamespaceDeclaration, + SyntaxKindEx.FileScopedNamespaceDeclaration); + /// /// Gets a collection of values which appear in the syntax tree as a /// . diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives.cs index 3fbad78c0..7a6f7f8ce 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives.cs @@ -40,8 +40,7 @@ internal class SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; - private static readonly Action FileScopedNamespaceDeclarationAction = HandleFileScopedNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -54,8 +53,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); - context.RegisterSyntaxNodeAction(FileScopedNamespaceDeclarationAction, SyntaxKindEx.FileScopedNamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings) @@ -72,26 +70,14 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty ProcessUsingsAndReportDiagnostic(usings, context); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { if (!settings.OrderingRules.SystemUsingDirectivesFirst) { return; } - var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; - var usings = namespaceDeclaration.Usings; - ProcessUsingsAndReportDiagnostic(usings, context); - } - - private static void HandleFileScopedNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) - { - if (!settings.OrderingRules.SystemUsingDirectivesFirst) - { - return; - } - - var namespaceDeclaration = (FileScopedNamespaceDeclarationSyntaxWrapper)context.Node; + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; var usings = namespaceDeclaration.Usings; ProcessUsingsAndReportDiagnostic(usings, context); } From d208f0af4d00d8d70db0aa0284566111941d26c6 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 20:46:08 -0800 Subject: [PATCH 02/16] Update SA1209 to support file-scoped namespaces Fixes #3439 --- .../OrderingRules/SA1209CSharp10UnitTests.cs | 37 +++++++++++++++++++ ...esMustBePlacedAfterOtherUsingDirectives.cs | 9 +++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs index 6bbf667ca..712fabe87 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs @@ -3,9 +3,46 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1209CSharp10UnitTests : SA1209CSharp9UnitTests { + [Fact] + [WorkItem(3439, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3439")] + public async Task TestWhenUsingAliasDirectivesAreNotPlacedCorrectlyInFileScopedNamespaceAsync() + { + var testCodeNamespace = @"namespace Test; + +using System.Net; +using System.Threading; +[|using L = System.Linq;|] +using System.IO; +using P = System.Threading.Tasks; + +class A +{ +} +"; + var fixedTestCodeNamespace = @"namespace Test; +using System.IO; +using System.Net; +using System.Threading; +using L = System.Linq; +using P = System.Threading.Tasks; + +class A +{ +} +"; + + await VerifyCSharpFixAsync(testCodeNamespace, DiagnosticResult.EmptyDiagnosticResults, fixedTestCodeNamespace, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives.cs index d041509d7..7843d25e2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives.cs @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; /// /// A using-alias directive is positioned before a regular using directive. @@ -37,7 +38,7 @@ internal class SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives : new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -50,7 +51,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) @@ -60,9 +61,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) ProcessUsingsAndReportDiagnostic(compilationUnit.Usings, context); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context) { - var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; ProcessUsingsAndReportDiagnostic(namespaceDeclaration.Usings, context); } From fc7a4335e5e2f30928dfb30cbf31b62bf5602e29 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:03:10 -0800 Subject: [PATCH 03/16] Clarify file-scoped namespace behavior in SA1402 code fix --- .../MaintainabilityRules/SA1402CodeFixProvider.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1402CodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1402CodeFixProvider.cs index 6735f7179..12069da7c 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1402CodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1402CodeFixProvider.cs @@ -3,6 +3,7 @@ namespace StyleCop.Analyzers.MaintainabilityRules { + using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; @@ -14,6 +15,7 @@ namespace StyleCop.Analyzers.MaintainabilityRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; /// /// Implements a code fix for . @@ -89,6 +91,10 @@ private static async Task GetTransformedSolutionAsync(Document documen nodesToRemoveFromExtracted.Add(child); break; + case SyntaxKindEx.FileScopedNamespaceDeclaration: + // Only one file-scoped namespace is allowed per syntax tree + throw new InvalidOperationException("This location is not reachable"); + default: break; } From c93a4bcceffee243517298736400642c5834a07e Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:14:41 -0800 Subject: [PATCH 04/16] Update SA1137 for file-scoped namespaces --- .../SA1137CSharp10UnitTests.cs | 157 ++++++++++++++++++ ...137ElementsShouldHaveTheSameIndentation.cs | 8 +- 2 files changed, 161 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1137CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1137CSharp10UnitTests.cs index 73ed44a30..f99ee8c75 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1137CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1137CSharp10UnitTests.cs @@ -3,9 +3,166 @@ namespace StyleCop.Analyzers.Test.CSharp10.ReadabilityRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.ReadabilityRules; + using StyleCop.Analyzers.Test.Helpers; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.ReadabilityRules.SA1137ElementsShouldHaveTheSameIndentation, + StyleCop.Analyzers.ReadabilityRules.IndentationCodeFixProvider>; public class SA1137CSharp10UnitTests : SA1137CSharp9UnitTests { + [Theory] + [MemberData(nameof(CommonMemberData.BaseTypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestFileScopedNamespaceDeclarationAsync(string baseTypeKind) + { + await new CSharpTest + { + TestSources = + { + $@" +using System; + +namespace Namespace0; + + [My] [My] {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace1; + + [My] +[| |][My] {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace2; + + [My] +[| |][My] + {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace3; + +[| |][My] +[| |][My] + {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace4; + + {baseTypeKind} TypeName1 {{ }} + +[| |][My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +namespace Namespace5; + + {baseTypeKind} TypeName1 {{ }} + + [My] +[| |][My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +namespace Namespace6; + + {baseTypeKind} TypeName1 {{ }} + +[| |][My] + [My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] +class MyAttribute : Attribute {{ }} +", + }, + FixedSources = + { + $@" +using System; + +namespace Namespace0; + + [My] [My] {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace1; + + [My] + [My] {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace2; + + [My] + [My] + {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace3; + + [My] + [My] + {baseTypeKind} TypeName {{ }} +", + $@" +using System; + +namespace Namespace4; + + {baseTypeKind} TypeName1 {{ }} + + [My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +namespace Namespace5; + + {baseTypeKind} TypeName1 {{ }} + + [My] + [My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +namespace Namespace6; + + {baseTypeKind} TypeName1 {{ }} + + [My] + [My] {baseTypeKind} TypeName2 {{ }} +", + $@" +using System; + +[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] +class MyAttribute : Attribute {{ }} +", + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1137ElementsShouldHaveTheSameIndentation.cs b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1137ElementsShouldHaveTheSameIndentation.cs index ea4317290..f023b5f5e 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1137ElementsShouldHaveTheSameIndentation.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1137ElementsShouldHaveTheSameIndentation.cs @@ -32,7 +32,7 @@ internal class SA1137ElementsShouldHaveTheSameIndentation : DiagnosticAnalyzer new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.ReadabilityRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; private static readonly Action EnumDeclarationAction = HandleEnumDeclaration; private static readonly Action MethodDeclarationAction = HandleMethodDeclaration; @@ -61,7 +61,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration); context.RegisterSyntaxNodeAction(EnumDeclarationAction, SyntaxKind.EnumDeclaration); context.RegisterSyntaxNodeAction(MethodDeclarationAction, SyntaxKind.MethodDeclaration); @@ -94,9 +94,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) CheckElements(context, elements.ToImmutable()); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context) { - var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; var elements = ImmutableList.CreateBuilder(); From cd18a2d36095b8431583a1d0cca8a619f8968925 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:16:21 -0800 Subject: [PATCH 05/16] Update SA1101 for file-scoped namespaces --- .../ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs index 84d1067e5..b14da7c68 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs @@ -249,6 +249,7 @@ private static bool HasThis(SyntaxNode node) case SyntaxKind.DelegateDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.NamespaceDeclaration: + case SyntaxKindEx.FileScopedNamespaceDeclaration: return false; case SyntaxKind.FieldDeclaration: From e16de1d1f4b1ff03c652953ac0fa9c1b19eebbea Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:18:29 -0800 Subject: [PATCH 06/16] Update SA1403 for file-scoped namespaces --- .../SA1403FileMayOnlyContainASingleNamespace.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1403FileMayOnlyContainASingleNamespace.cs b/StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1403FileMayOnlyContainASingleNamespace.cs index 5b907d513..d5aa73378 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1403FileMayOnlyContainASingleNamespace.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1403FileMayOnlyContainASingleNamespace.cs @@ -51,7 +51,8 @@ private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context) { var syntaxRoot = context.Tree.GetRoot(context.CancellationToken); - var descentNodes = syntaxRoot.DescendantNodes(descendIntoChildren: node => node != null && !node.IsKind(SyntaxKind.ClassDeclaration)); + // No need to check file-scoped namespaces because the compiler only allows one per file + var descentNodes = syntaxRoot.DescendantNodes(descendIntoChildren: node => node.IsKind(SyntaxKind.CompilationUnit) || node.IsKind(SyntaxKind.NamespaceDeclaration)); bool foundNode = false; From cc2cce60fd4e3c4ae4d319bb0ecc17626b62ff64 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:24:51 -0800 Subject: [PATCH 07/16] Update SA1300 for file-scoped namespaces --- .../RenameToUpperCaseCodeFixProvider.cs | 3 +- .../NamingRules/SA1300CSharp10UnitTests.cs | 86 +++++++++++++++++++ ...1300ElementMustBeginWithUpperCaseLetter.cs | 8 +- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs index 152e03235..f7cdc519f 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs @@ -14,6 +14,7 @@ namespace StyleCop.Analyzers.NamingRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; /// /// Implements a code fix for all analyzers that require a symbol to be upper case. @@ -60,7 +61,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var newName = baseName; var memberSyntax = RenameHelper.GetParentDeclaration(token); - if (memberSyntax is NamespaceDeclarationSyntax) + if (BaseNamespaceDeclarationSyntaxWrapper.IsInstance(memberSyntax)) { // namespaces are not symbols. So we are just renaming the namespace Task RenameNamespace(CancellationToken cancellationToken) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs index 4dcc2ed78..39b15b133 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs @@ -3,9 +3,95 @@ namespace StyleCop.Analyzers.Test.CSharp10.NamingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.NamingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.NamingRules.SA1300ElementMustBeginWithUpperCaseLetter, + StyleCop.Analyzers.NamingRules.RenameToUpperCaseCodeFixProvider>; public class SA1300CSharp10UnitTests : SA1300CSharp9UnitTests { + [Fact] + public async Task TestUpperCaseFileScopedNamespaceAsync() + { + var testCode = @"namespace Test;"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestLowerCaseFileScopedNamespaceAsync() + { + var testCode = @"namespace {|#0:test|};"; + + var fixedCode = @"namespace Test;"; + + DiagnosticResult expected = Diagnostic().WithArguments("test").WithLocation(0); + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestAllowedLowerCaseFileScopedNamespaceIsNotReportedAsync() + { + var customTestSettings = @" +{ + ""settings"": { + ""namingRules"": { + ""allowedNamespaceComponents"": [ ""eBay"" ] + } + } +} +"; + + var testCode = @"namespace eBay;"; + + await new CSharpTest + { + TestCode = testCode, + Settings = customTestSettings, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestLowerCaseComlicatedFileScopedNamespaceAsync() + { + var testCode = @"namespace {|#0:test|}.{|#1:foo|}.{|#2:bar|};"; + + var fixedCode = @"namespace Test.Foo.Bar;"; + + DiagnosticResult[] expected = new[] + { + Diagnostic().WithArguments("test").WithLocation(0), + Diagnostic().WithArguments("foo").WithLocation(1), + Diagnostic().WithArguments("bar").WithLocation(2), + }; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestAllowedLowerCaseComplicatedFileScopedNamespaceIsNotReportedAsync() + { + var customTestSettings = @" +{ + ""settings"": { + ""namingRules"": { + ""allowedNamespaceComponents"": [ ""iPod"" ] + } + } +} +"; + + var testCode = @"namespace Apple.iPod.Library;"; + + await new CSharpTest + { + TestCode = testCode, + Settings = customTestSettings, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1300ElementMustBeginWithUpperCaseLetter.cs b/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1300ElementMustBeginWithUpperCaseLetter.cs index e88f0d569..f757d7e50 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1300ElementMustBeginWithUpperCaseLetter.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1300ElementMustBeginWithUpperCaseLetter.cs @@ -49,7 +49,7 @@ internal class SA1300ElementMustBeginWithUpperCaseLetter : DiagnosticAnalyzer private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.NamingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; private static readonly Action ClassDeclarationAction = HandleClassDeclaration; private static readonly Action RecordDeclarationAction = HandleRecordDeclaration; private static readonly Action EnumDeclarationAction = HandleEnumDeclaration; @@ -75,7 +75,7 @@ public override void Initialize(AnalysisContext context) // Note: Interfaces are handled by SA1302 // Note: Fields are handled by SA1303 through SA1311 - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); context.RegisterSyntaxNodeAction(ClassDeclarationAction, SyntaxKind.ClassDeclaration); context.RegisterSyntaxNodeAction(RecordDeclarationAction, SyntaxKindEx.RecordDeclaration); context.RegisterSyntaxNodeAction(RecordDeclarationAction, SyntaxKindEx.RecordStructDeclaration); @@ -91,9 +91,9 @@ public override void Initialize(AnalysisContext context) context.RegisterSyntaxNodeAction(ParameterAction, SyntaxKind.Parameter); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { - NameSyntax nameSyntax = ((NamespaceDeclarationSyntax)context.Node).Name; + NameSyntax nameSyntax = ((BaseNamespaceDeclarationSyntaxWrapper)context.Node).Name; CheckNamespaceNameSyntax(context, nameSyntax, settings); } From e202aeb23d4830aa876120a513faee413bee6f61 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:39:42 -0800 Subject: [PATCH 08/16] Update SA1200 for file-scoped namespaces --- .../OrderingRules/UsingCodeFixProvider.cs | 7 +++- ...SA1200CSharp10OutsideNamespaceUnitTests.cs | 27 ++++++++++++++++ .../SA1200CSharp10PreserveUnitTests.cs | 32 +++++++++++++++++++ .../OrderingRules/SA1200CSharp10UnitTests.cs | 30 +++++++++++++++++ .../SA1200OutsideNamespaceUnitTests.cs | 6 ++-- .../OrderingRules/SA1200PreserveUnitTests.cs | 2 +- ...200UsingDirectivesMustBePlacedCorrectly.cs | 11 ++++--- 7 files changed, 106 insertions(+), 9 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs index e89f5962c..2320f5dd6 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs @@ -137,7 +137,12 @@ private static string DetermineIndentation(CompilationUnitSyntax compilationUnit { var rootNamespace = compilationUnit.Members.First(member => BaseNamespaceDeclarationSyntaxWrapper.IsInstance(member)); var indentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, rootNamespace); - usingsIndentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationLevel + 1); + if (!rootNamespace.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration)) + { + indentationLevel++; + } + + usingsIndentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationLevel); } else { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10OutsideNamespaceUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10OutsideNamespaceUnitTests.cs index ef20fe410..99925dfa5 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10OutsideNamespaceUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10OutsideNamespaceUnitTests.cs @@ -3,9 +3,36 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; + using StyleCop.Analyzers.OrderingRules; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; public class SA1200CSharp10OutsideNamespaceUnitTests : SA1200CSharp9OutsideNamespaceUnitTests { + [Fact] + public async Task TestInvalidUsingStatementsInFileScopedNamespaceAsync() + { + var testCode = @"namespace TestNamespace; + +{|#0:using System;|} +{|#1:using System.Threading;|} +"; + var fixedTestCode = @"using System; +using System.Threading; + +namespace TestNamespace; +"; + + DiagnosticResult[] expectedResults = + { + Diagnostic(SA1200UsingDirectivesMustBePlacedCorrectly.DescriptorOutside).WithLocation(0), + Diagnostic(SA1200UsingDirectivesMustBePlacedCorrectly.DescriptorOutside).WithLocation(1), + }; + + await VerifyCSharpFixAsync(testCode, expectedResults, fixedTestCode, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10PreserveUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10PreserveUnitTests.cs index 63c84bbe5..4cf283b45 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10PreserveUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10PreserveUnitTests.cs @@ -3,9 +3,41 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; public class SA1200CSharp10PreserveUnitTests : SA1200CSharp9PreserveUnitTests { + [Fact] + public async Task TestValidUsingStatementsInFileScopedNamespaceAsync() + { + var testCode = @"namespace TestNamespace; + +using System; +using System.Threading; +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Verifies that having using statements in the compilation unit will not diagnostics, even if they could be + /// moved inside a file-scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestIgnoredUsingStatementsInCompilationUnitWithFileScopedNamespaceAsync() + { + var testCode = @"using System; +using System.Threading; + +namespace TestNamespace; +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs index 4d9d87538..8ad951adc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs @@ -3,9 +3,39 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; + using StyleCop.Analyzers.OrderingRules; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1200UsingDirectivesMustBePlacedCorrectly, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1200CSharp10UnitTests : SA1200CSharp9UnitTests { + [Fact] + public async Task TestInvalidUsingStatementsInCompilationUnitWithFileScopedNamespaceAsync() + { + var testCode = @"{|#0:using System;|} +{|#1:using System.Threading;|} + +namespace TestNamespace; +"; + + var fixedTestCode = @"namespace TestNamespace; +using System; +using System.Threading; +"; + + DiagnosticResult[] expectedResults = + { + Diagnostic(SA1200UsingDirectivesMustBePlacedCorrectly.DescriptorInside).WithLocation(0), + Diagnostic(SA1200UsingDirectivesMustBePlacedCorrectly.DescriptorInside).WithLocation(1), + }; + + await VerifyCSharpFixAsync(testCode, expectedResults, fixedTestCode, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200OutsideNamespaceUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200OutsideNamespaceUnitTests.cs index 0e825baf7..8229674a1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200OutsideNamespaceUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200OutsideNamespaceUnitTests.cs @@ -347,10 +347,10 @@ private void Test() await VerifyCSharpFixAsync(testCode, expectedResults, fixedTestCode, CancellationToken.None).ConfigureAwait(false); } - private static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) + protected static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) => StyleCopCodeFixVerifier.Diagnostic(descriptor); - private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken) + protected static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken) { var test = new StyleCopCodeFixVerifier.CSharpTest { @@ -362,7 +362,7 @@ private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[ return test.RunAsync(cancellationToken); } - private static Task VerifyCSharpFixAsync(string source, DiagnosticResult[] expected, string fixedSource, CancellationToken cancellationToken) + protected static Task VerifyCSharpFixAsync(string source, DiagnosticResult[] expected, string fixedSource, CancellationToken cancellationToken) { var test = new StyleCopCodeFixVerifier.CSharpTest { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200PreserveUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200PreserveUnitTests.cs index 9e6d5e77d..e83aba509 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200PreserveUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1200PreserveUnitTests.cs @@ -124,7 +124,7 @@ namespace TestNamespace await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } - private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken) + protected static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken) { var test = new StyleCopCodeFixVerifier.CSharpTest { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1200UsingDirectivesMustBePlacedCorrectly.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1200UsingDirectivesMustBePlacedCorrectly.cs index 7c01cdb8d..a35c35e47 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1200UsingDirectivesMustBePlacedCorrectly.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1200UsingDirectivesMustBePlacedCorrectly.cs @@ -10,6 +10,8 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; + using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -176,7 +178,7 @@ internal class SA1200UsingDirectivesMustBePlacedCorrectly : DiagnosticAnalyzer #pragma warning restore SA1202 // Elements should be ordered by access private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -189,7 +191,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } /// @@ -235,6 +237,7 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty case SyntaxKind.ExternAliasDirective: case SyntaxKind.NamespaceDeclaration: + case SyntaxKindEx.FileScopedNamespaceDeclaration: default: continue; } @@ -254,14 +257,14 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty /// /// The analysis context. /// The effective StyleCop analysis settings. - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { if (settings.OrderingRules.UsingDirectivesPlacement != UsingDirectivesPlacement.OutsideNamespace) { return; } - NamespaceDeclarationSyntax syntax = (NamespaceDeclarationSyntax)context.Node; + BaseNamespaceDeclarationSyntaxWrapper syntax = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; foreach (UsingDirectiveSyntax directive in syntax.Usings) { // Using directive should appear outside a namespace declaration From ea800e25e3a7cf2600b1349e7579573ac231ed48 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:45:21 -0800 Subject: [PATCH 09/16] Update SA1201 for file-scoped namespaces --- .../OrderingRules/SA1201CSharp10UnitTests.cs | 42 +++++++++++++++++++ ...1201ElementsMustAppearInTheCorrectOrder.cs | 12 +++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs index a28bf3533..6879aca92 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs @@ -3,9 +3,51 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1201ElementsMustAppearInTheCorrectOrder, + StyleCop.Analyzers.OrderingRules.ElementOrderCodeFixProvider>; public class SA1201CSharp10UnitTests : SA1201CSharp9UnitTests { + [Fact] + public async Task TestOuterOrderCorrectOrderWithFileScopedNamespaceAsync() + { + string testCode = @"namespace Foo; + +public delegate void bar(); +public enum TestEnum { } +public interface IFoo { } +public struct FooStruct { } +public class FooClass { } +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestOuterOrderWrongOrderWithFileScopedNamespaceAsync() + { + string testCode = @" +namespace Foo; + +public enum TestEnum { } +public delegate void {|#0:bar|}(); +public interface IFoo { } +public class FooClass { } +public struct {|#1:FooStruct|} { } +"; + var expected = new[] + { + Diagnostic().WithLocation(0).WithArguments("delegate", "enum"), + Diagnostic().WithLocation(1).WithArguments("struct", "class"), + }; + + await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1201ElementsMustAppearInTheCorrectOrder.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1201ElementsMustAppearInTheCorrectOrder.cs index f37532b96..ecb5b746f 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1201ElementsMustAppearInTheCorrectOrder.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1201ElementsMustAppearInTheCorrectOrder.cs @@ -123,6 +123,7 @@ internal class SA1201ElementsMustAppearInTheCorrectOrder : DiagnosticAnalyzer // extern alias and usings are missing here because the compiler itself is enforcing the right order. private static readonly ImmutableArray OuterOrder = ImmutableArray.Create( + SyntaxKindEx.FileScopedNamespaceDeclaration, SyntaxKind.NamespaceDeclaration, SyntaxKind.DelegateDeclaration, SyntaxKind.EnumDeclaration, @@ -149,6 +150,7 @@ internal class SA1201ElementsMustAppearInTheCorrectOrder : DiagnosticAnalyzer private static readonly Dictionary MemberNames = new Dictionary { [SyntaxKind.NamespaceDeclaration] = "namespace", + [SyntaxKindEx.FileScopedNamespaceDeclaration] = "namespace", [SyntaxKind.DelegateDeclaration] = "delegate", [SyntaxKind.EnumDeclaration] = "enum", [SyntaxKind.InterfaceDeclaration] = "interface", @@ -172,7 +174,7 @@ internal class SA1201ElementsMustAppearInTheCorrectOrder : DiagnosticAnalyzer }; private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; /// @@ -186,7 +188,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration); } @@ -218,7 +220,7 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty HandleMemberList(context, elementOrder, kindIndex, compilationUnit.Members, OuterOrder); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var elementOrder = settings.OrderingRules.ElementOrder; int kindIndex = elementOrder.IndexOf(OrderingTrait.Kind); @@ -227,9 +229,9 @@ private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context return; } - var compilationUnit = (NamespaceDeclarationSyntax)context.Node; + var baseNamespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; - HandleMemberList(context, elementOrder, kindIndex, compilationUnit.Members, OuterOrder); + HandleMemberList(context, elementOrder, kindIndex, baseNamespaceDeclaration.Members, OuterOrder); } private static void HandleMemberList(SyntaxNodeAnalysisContext context, ImmutableArray elementOrder, int kindIndex, SyntaxList members, ImmutableArray order) From b7bfa00d9cde20029cf0d3c30d1f9bafc3432918 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:50:32 -0800 Subject: [PATCH 10/16] Update SA1202 for file-scoped namespaces --- .../ElementOrderCodeFixProvider.cs | 7 +-- .../OrderingRules/SA1202CSharp10UnitTests.cs | 53 +++++++++++++++++++ .../OrderingRules/SA1202UnitTests.cs | 30 +++++++++++ .../Helpers/MemberOrderHelper.cs | 3 +- .../SA1202ElementsMustBeOrderedByAccess.cs | 11 ++-- 5 files changed, 95 insertions(+), 9 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/ElementOrderCodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/ElementOrderCodeFixProvider.cs index 5f6c18e6f..3faa4f72f 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/ElementOrderCodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/ElementOrderCodeFixProvider.cs @@ -15,6 +15,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -82,9 +83,9 @@ private static SyntaxNode UpdateSyntaxRoot(MemberDeclarationSyntax memberDeclara return HandleTypeDeclaration(memberToMove, (TypeDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationSettings); } - if (parentDeclaration is NamespaceDeclarationSyntax) + if (BaseNamespaceDeclarationSyntaxWrapper.IsInstance(parentDeclaration)) { - return HandleNamespaceDeclaration(memberToMove, (NamespaceDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationSettings); + return HandleBaseNamespaceDeclaration(memberToMove, (BaseNamespaceDeclarationSyntaxWrapper)parentDeclaration, elementOrder, syntaxRoot, indentationSettings); } if (parentDeclaration is CompilationUnitSyntax) @@ -105,7 +106,7 @@ private static SyntaxNode HandleCompilationUnitDeclaration(MemberOrderHelper mem return OrderMember(memberOrder, compilationUnitDeclaration.Members, elementOrder, syntaxRoot, indentationSettings); } - private static SyntaxNode HandleNamespaceDeclaration(MemberOrderHelper memberOrder, NamespaceDeclarationSyntax namespaceDeclaration, ImmutableArray elementOrder, SyntaxNode syntaxRoot, IndentationSettings indentationSettings) + private static SyntaxNode HandleBaseNamespaceDeclaration(MemberOrderHelper memberOrder, BaseNamespaceDeclarationSyntaxWrapper namespaceDeclaration, ImmutableArray elementOrder, SyntaxNode syntaxRoot, IndentationSettings indentationSettings) { return OrderMember(memberOrder, namespaceDeclaration.Members, elementOrder, syntaxRoot, indentationSettings); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1202CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1202CSharp10UnitTests.cs index 694b7e988..cb7df3647 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1202CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1202CSharp10UnitTests.cs @@ -3,9 +3,62 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1202ElementsMustBeOrderedByAccess, + StyleCop.Analyzers.OrderingRules.ElementOrderCodeFixProvider>; public class SA1202CSharp10UnitTests : SA1202CSharp9UnitTests { + /// + /// Verifies that the analyzer will properly handle ordering within a file-scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestFileScopedNamespaceClassesAsync() + { + var testCode = @"namespace TestNamespace; + +enum TestEnum1 { } +public enum {|#0:TestEnum2|} { } +class TestClass1 { } +public class {|#1:TestClass2|} { } +"; + + DiagnosticResult[] expected = + { + Diagnostic().WithLocation(0).WithArguments("public", "internal"), + Diagnostic().WithLocation(1).WithArguments("public", "internal"), + }; + + var fixedCode = @"namespace TestNamespace; +public enum TestEnum2 { } + +enum TestEnum1 { } +public class TestClass2 { } +class TestClass1 { } +"; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestDefaultAccessModifierOrderWithFileScopedNamespaceAsync() + { + string testCode = @"namespace Foo; + +public class Class1 { } +internal class Class2 { } +class Class3 { } +internal class Class4 { } +class Class5 { } +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs index cd27e4f8a..fdc46e640 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs @@ -642,6 +642,36 @@ class TestClass1 { } await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } + [Fact] + public async Task TestDefaultAccessModifierOrderInCompilationUnitAsync() + { + string testCode = @" +public class Class1 { } +internal class Class2 { } +class Class3 { } +internal class Class4 { } +class Class5 { } +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestDefaultAccessModifierOrderInNamespaceAsync() + { + string testCode = @"namespace Foo +{ + public class Class1 { } + internal class Class2 { } + class Class3 { } + internal class Class4 { } + class Class5 { } +} +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + /// /// Verifies that the analyzer will properly handle static constructors. /// diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs index 98343aa08..d6d49a5c5 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs @@ -8,6 +8,7 @@ namespace StyleCop.Analyzers.Helpers using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -151,7 +152,7 @@ internal static AccessLevel GetAccessLevelForOrdering(SyntaxNode member, SyntaxT accessibility = AccessLevelHelper.GetAccessLevel(modifiers); if (accessibility == AccessLevel.NotSpecified) { - if (member.Parent.IsKind(SyntaxKind.CompilationUnit) || member.Parent.IsKind(SyntaxKind.NamespaceDeclaration)) + if (member.Parent.IsKind(SyntaxKind.CompilationUnit) || member.Parent.IsKind(SyntaxKind.NamespaceDeclaration) || member.Parent.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration)) { accessibility = AccessLevel.Internal; } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs index 5d8b407cd..af63cd98e 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -69,7 +70,7 @@ internal class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer SyntaxKind.OperatorDeclaration); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; /// @@ -83,7 +84,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); context.RegisterSyntaxNodeAction(TypeDeclarationAction, TypeDeclarationKinds); } @@ -101,7 +102,7 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty HandleMemberList(context, elementOrder, accessibilityIndex, compilationUnit.Members); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var elementOrder = settings.OrderingRules.ElementOrder; int accessibilityIndex = elementOrder.IndexOf(OrderingTrait.Accessibility); @@ -110,9 +111,9 @@ private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context return; } - var compilationUnit = (NamespaceDeclarationSyntax)context.Node; + var baseNamespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; - HandleMemberList(context, elementOrder, accessibilityIndex, compilationUnit.Members); + HandleMemberList(context, elementOrder, accessibilityIndex, baseNamespaceDeclaration.Members); } private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) From a0463b303efff2492d7a919330e85cdad934b0aa Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:52:52 -0800 Subject: [PATCH 11/16] Update SA1204 for file-scoped namespaces --- .../OrderingRules/SA1204CSharp10UnitTests.cs | 29 +++++++++++++++++++ ...lementsMustAppearBeforeInstanceElements.cs | 11 +++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1204CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1204CSharp10UnitTests.cs index 172fc0549..ad0fd1668 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1204CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1204CSharp10UnitTests.cs @@ -3,9 +3,38 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1204StaticElementsMustAppearBeforeInstanceElements, + StyleCop.Analyzers.OrderingRules.ElementOrderCodeFixProvider>; public class SA1204CSharp10UnitTests : SA1204CSharp9UnitTests { + /// + /// Verifies that the analyzer will properly handle ordering within a file-scoped namespace. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestFileScopedNamespaceClassesAsync() + { + var testCode = @"namespace TestNamespace; + +class TestClass1 { } +static class {|#0:TestClass2|} { } +"; + + var expected = Diagnostic().WithLocation(0); + + var fixedCode = @"namespace TestNamespace; +static class TestClass2 { } + +class TestClass1 { } +"; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs index 2aaca3405..ca5851610 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs @@ -11,6 +11,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -41,7 +42,7 @@ internal class SA1204StaticElementsMustAppearBeforeInstanceElements : Diagnostic ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; private static readonly Action TypeDeclarationAction = HandleTypeDeclaration; /// @@ -55,7 +56,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); context.RegisterSyntaxNodeAction(TypeDeclarationAction, TypeDeclarationKinds); } @@ -73,7 +74,7 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty HandleMemberList(context, elementOrder, staticIndex, compilationUnit.Members); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var elementOrder = settings.OrderingRules.ElementOrder; int staticIndex = elementOrder.IndexOf(OrderingTrait.Static); @@ -82,9 +83,9 @@ private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context return; } - var compilationUnit = (NamespaceDeclarationSyntax)context.Node; + var baseNamespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; - HandleMemberList(context, elementOrder, staticIndex, compilationUnit.Members); + HandleMemberList(context, elementOrder, staticIndex, baseNamespaceDeclaration.Members); } private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) From cf5eea9a9437515d39ecfd13eb6b6cb29a263146 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 21:58:17 -0800 Subject: [PATCH 12/16] Update SA1210 for file-scoped namespaces --- ...harp10CombinedSystemDirectivesUnitTests.cs | 42 +++++++++++++++++++ .../OrderingRules/SA1210CSharp10UnitTests.cs | 42 +++++++++++++++++++ ...SA1210CombinedSystemDirectivesUnitTests.cs | 20 ++++----- ...sMustBeOrderedAlphabeticallyByNamespace.cs | 9 ++-- 4 files changed, 99 insertions(+), 14 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs index 58eab7583..bb3e6509c 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs @@ -3,9 +3,51 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1210CSharp10CombinedSystemDirectivesUnitTests : SA1210CSharp9CombinedSystemDirectivesUnitTests { + [Fact] + public async Task TestUsingDirectivesInFileScopedNamespaceDeclarationAsync() + { + await new CSharpTest + { + TestSources = + { + @"namespace Food; + +[|using System.Threading;|] +using System; +", + @"namespace Bar; + +[|using Food;|] +using Bar; +[|using System.Threading;|] +using System; +", + }, + FixedSources = + { + @"namespace Food; +using System; +using System.Threading; +", + @"namespace Bar; +using Bar; +using Food; +using System; +using System.Threading; +", + }, + Settings = CombinedUsingDirectivesTestSettings, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs index 84afe12e0..c9db20a85 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs @@ -3,9 +3,51 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1210CSharp10UnitTests : SA1210CSharp9UnitTests { + [Fact] + public async Task TestUsingDirectivesInFileScopedNamespaceDeclarationAsync() + { + await new CSharpTest + { + TestSources = + { + @"namespace Foo; + +[|using System.Threading;|] +using System; +", + @"namespace Bar; + +[|using Foo;|] +using Bar; +[|using System.Threading;|] +using System; +", + }, + FixedSources = + { + @"namespace Foo; +using System; +using System.Threading; +", + @"namespace Bar; +using System; +using System.Threading; +using Bar; +using Foo; +", + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1210CombinedSystemDirectivesUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1210CombinedSystemDirectivesUnitTests.cs index 29acbefdc..0f9d82008 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1210CombinedSystemDirectivesUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1210CombinedSystemDirectivesUnitTests.cs @@ -18,6 +18,16 @@ namespace StyleCop.Analyzers.Test.OrderingRules /// public class SA1210CombinedSystemDirectivesUnitTests { + protected const string CombinedUsingDirectivesTestSettings = @" +{ + ""settings"": { + ""orderingRules"": { + ""systemUsingDirectivesFirst"": false + } + } +} +"; + [Fact] public async Task TestProperOrderedUsingDirectivesInNamespaceDeclarationAsync() { @@ -212,16 +222,6 @@ private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[ private static Task VerifyCSharpFixAsync(string source, DiagnosticResult[] expected, string fixedSource, CancellationToken cancellationToken) { - const string CombinedUsingDirectivesTestSettings = @" -{ - ""settings"": { - ""orderingRules"": { - ""systemUsingDirectivesFirst"": false - } - } -} -"; - var test = new StyleCopCodeFixVerifier.CSharpTest { TestCode = source, diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace.cs index 99424ebc2..1fad7c2f5 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace.cs @@ -11,6 +11,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -40,7 +41,7 @@ internal class SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace : Dia new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -53,7 +54,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings) @@ -63,9 +64,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty ProcessUsings(context, settings.OrderingRules, compilationUnit.Usings); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { - var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; ProcessUsings(context, settings.OrderingRules, namespaceDeclaration.Usings); } From 672299031d35352a3e04c34b9f859bfc4e5b45f8 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 22:18:31 -0800 Subject: [PATCH 13/16] Update SA1121 for file-scoped namespaces --- .../SA1121CSharp10UnitTests.cs | 33 +++++++++++++++++++ .../Helpers/SyntaxTreeHelpers.cs | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1121CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1121CSharp10UnitTests.cs index 9db3e4c11..9007af20d 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1121CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1121CSharp10UnitTests.cs @@ -3,9 +3,42 @@ namespace StyleCop.Analyzers.Test.CSharp10.ReadabilityRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.ReadabilityRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.ReadabilityRules.SA1121UseBuiltInTypeAlias, + StyleCop.Analyzers.ReadabilityRules.SA1121CodeFixProvider>; public class SA1121CSharp10UnitTests : SA1121CSharp9UnitTests { + [Fact] + public async Task TestUsingNameChangeInFileScopedNamespaceAsync() + { + string oldSource = @"namespace Foo; + +using MyInt = System.UInt32; +class Bar +{ +{|#0:MyInt|} value = 3; +} +"; + string newSource = @"namespace Foo; + +using MyInt = System.UInt32; +class Bar +{ +uint value = 3; +} +"; + + await new CSharpTest + { + TestCode = oldSource, + ExpectedDiagnostics = { Diagnostic().WithLocation(0) }, + FixedCode = newSource, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxTreeHelpers.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxTreeHelpers.cs index 94c2f9038..5e34e9838 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxTreeHelpers.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SyntaxTreeHelpers.cs @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.Helpers using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; + using StyleCop.Analyzers.Lightup; internal static class SyntaxTreeHelpers { @@ -89,7 +90,7 @@ internal static bool ContainsUsingAlias(this SyntaxTree tree, ConcurrentDictiona private static bool ContainsUsingAliasNoCache(SyntaxTree tree) { - var nodes = tree.GetRoot().DescendantNodes(node => node.IsKind(SyntaxKind.CompilationUnit) || node.IsKind(SyntaxKind.NamespaceDeclaration)); + var nodes = tree.GetRoot().DescendantNodes(node => node.IsKind(SyntaxKind.CompilationUnit) || node.IsKind(SyntaxKind.NamespaceDeclaration) || node.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration)); return nodes.OfType().Any(x => x.Alias != null); } From 947b470a4af5786fe273da721d22a7a8815ec09b Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 22:24:51 -0800 Subject: [PATCH 14/16] Update SA1211 for file-scoped namespaces --- .../OrderingRules/SA1211CSharp10UnitTests.cs | 62 +++++++++++++++++++ ...sMustBeOrderedAlphabeticallyByAliasName.cs | 9 +-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs index 3983b81fe..043f3ebf2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs @@ -3,9 +3,71 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1211CSharp10UnitTests : SA1211CSharp9UnitTests { + [Fact] + public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() + { + await new CSharpTest + { + TestSources = + { + @"namespace Foo; + +using System; +using \u0069nt = System.Int32; +{|#0:using character = System.Char;|} +", + @"namespace Bar; + +using System; +using Stream = System.IO.Stream; +using StringBuilder = System.Text.StringBuilder; +using StringWriter = System.IO.StringWriter; +{|#1:using MemoryStream = System.IO.MemoryStream;|} +", + @"namespace Spam; + +using System; +using @int = System.Int32; +{|#2:using Character = System.Char;|} +", + }, + ExpectedDiagnostics = + { + Diagnostic().WithLocation(0).WithArguments("character", "int"), + Diagnostic().WithLocation(1).WithArguments("MemoryStream", "Stream"), + Diagnostic().WithLocation(2).WithArguments("Character", "int"), + }, + FixedSources = + { + @"namespace Foo; +using System; +using character = System.Char; +using \u0069nt = System.Int32; +", + @"namespace Bar; +using System; +using MemoryStream = System.IO.MemoryStream; +using Stream = System.IO.Stream; +using StringBuilder = System.Text.StringBuilder; +using StringWriter = System.IO.StringWriter; +", + @"namespace Spam; +using System; +using Character = System.Char; +using @int = System.Int32; +", + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName.cs index baf8dc380..0a422db6f 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName.cs @@ -11,6 +11,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; /// /// The using-alias directives within a C# code file are not sorted alphabetically by alias name. @@ -37,7 +38,7 @@ internal class SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -50,7 +51,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) @@ -59,9 +60,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) HandleUsingDirectives(context, compilationUnit.Usings); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context) { - var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; + var namespaceDeclaration = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; HandleUsingDirectives(context, namespaceDeclaration.Usings); } From dac0dd87752b9dfd73266752f83f90aac0f52f0a Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 22:30:56 -0800 Subject: [PATCH 15/16] Update SA1216 for file-scoped namespaces --- .../OrderingRules/SA1216CSharp10UnitTests.cs | 48 +++++++++++++++++++ ...ectivesMustBePlacedAtTheCorrectLocation.cs | 9 ++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs index 2f904717d..b5884e18a 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs @@ -3,9 +3,57 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1216CSharp10UnitTests : SA1216CSharp9UnitTests { + [Fact] + public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() + { + await new CSharpTest + { + TestSources = + { + @"namespace Foo; + +{|#0:using static System.Math;|} +using Execute = System.Action; +using System; +", + @"namespace Bar; + +using Execute = System.Action; +{|#1:using static System.Array;|} +using static System.Math; +using System; +", + }, + ExpectedDiagnostics = + { + Diagnostic().WithLocation(0), + Diagnostic().WithLocation(1), + }, + FixedSources = + { + @"namespace Foo; +using System; +using static System.Math; +using Execute = System.Action; +", + @"namespace Bar; +using System; +using static System.Array; +using static System.Math; +using Execute = System.Action; +", + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation.cs index 02741d412..74ce83f89 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation.cs @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; /// /// A static using directive is positioned at the wrong location. @@ -37,7 +38,7 @@ internal class SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation : Dia new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -50,7 +51,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) @@ -59,9 +60,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context) CheckUsingDeclarations(context, compilationUnit.Usings); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context) { - var namespaceDirective = (NamespaceDeclarationSyntax)context.Node; + var namespaceDirective = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; CheckUsingDeclarations(context, namespaceDirective.Usings); } From 32bfb494388a191214e4fd29033cb64860900e2d Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Jan 2022 22:35:45 -0800 Subject: [PATCH 16/16] Update SA1217 for file-scoped namespaces --- .../OrderingRules/SA1217CSharp10UnitTests.cs | 50 +++++++++++++++++++ ...icDirectivesMustBeOrderedAlphabetically.cs | 9 ++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs index 4fba94788..2595d8fa1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs @@ -3,9 +3,59 @@ namespace StyleCop.Analyzers.Test.CSharp10.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp9.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1217UsingStaticDirectivesMustBeOrderedAlphabetically, + StyleCop.Analyzers.OrderingRules.UsingCodeFixProvider>; public class SA1217CSharp10UnitTests : SA1217CSharp9UnitTests { + [Fact] + public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() + { + await new CSharpTest + { + TestSources = + { + @"namespace Foo; + +using System; +using Execute = System.Action; +{|#0:using static System.Math;|} +using static System.Array; +", + @"namespace Bar; + +{|#1:using static System.Math;|} +using Execute = System.Action; +using static System.Array; +using System; +", + }, + ExpectedDiagnostics = + { + Diagnostic().WithLocation(0).WithArguments("System.Math", "System.Array"), + Diagnostic().WithLocation(1).WithArguments("System.Math", "System.Array"), + }, + FixedSources = + { + @"namespace Foo; +using System; +using static System.Array; +using static System.Math; +using Execute = System.Action; +", + @"namespace Bar; +using System; +using static System.Array; +using static System.Math; +using Execute = System.Action; +", + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1217UsingStaticDirectivesMustBeOrderedAlphabetically.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1217UsingStaticDirectivesMustBeOrderedAlphabetically.cs index ccfe7a5d3..0a6030848 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1217UsingStaticDirectivesMustBeOrderedAlphabetically.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1217UsingStaticDirectivesMustBeOrderedAlphabetically.cs @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Settings.ObjectModel; /// @@ -38,7 +39,7 @@ internal class SA1217UsingStaticDirectivesMustBeOrderedAlphabetically : Diagnost new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); private static readonly Action CompilationUnitAction = HandleCompilationUnit; - private static readonly Action NamespaceDeclarationAction = HandleNamespaceDeclaration; + private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -51,7 +52,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); - context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration); + context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); } private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings) @@ -60,9 +61,9 @@ private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, Sty CheckUsingDeclarations(context, settings.OrderingRules, compilationUnit.Usings); } - private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) + private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { - var namespaceDirective = (NamespaceDeclarationSyntax)context.Node; + var namespaceDirective = (BaseNamespaceDeclarationSyntaxWrapper)context.Node; CheckUsingDeclarations(context, settings.OrderingRules, namespaceDirective.Usings); }