diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.UsingsSorter.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.UsingsSorter.cs index 38e3ee6c5..51abf7391 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.UsingsSorter.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.UsingsSorter.cs @@ -90,7 +90,7 @@ public List GetContainedUsings(TreeTextSpan directiveSpan) return result; } - public SyntaxList GenerateGroupedUsings(TreeTextSpan directiveSpan, string indentation, bool withTrailingBlankLine, bool qualifyNames) + public SyntaxList GenerateGroupedUsings(TreeTextSpan directiveSpan, string indentation, bool withLeadingBlankLine, bool withTrailingBlankLine, bool qualifyNames) { var usingList = new List(); List triviaToMove = new List(); @@ -107,6 +107,12 @@ public SyntaxList GenerateGroupedUsings(TreeTextSpan direc usingList[0] = usingList[0].WithLeadingTrivia(newLeadingTrivia); } + if (withLeadingBlankLine && usingList.Count > 0) + { + var firstUsing = usingList[0]; + usingList[0] = firstUsing.WithLeadingTrivia(firstUsing.GetLeadingTrivia().Insert(0, SyntaxFactory.CarriageReturnLineFeed)); + } + if (withTrailingBlankLine && (usingList.Count > 0)) { var lastUsing = usingList[usingList.Count - 1]; @@ -116,7 +122,7 @@ public SyntaxList GenerateGroupedUsings(TreeTextSpan direc return SyntaxFactory.List(usingList); } - public SyntaxList GenerateGroupedUsings(List usingsList, string indentation, bool withTrailingBlankLine, bool qualifyNames) + public SyntaxList GenerateGroupedUsings(List usingsList, string indentation, bool withLeadingBlankLine, bool withTrailingBlankLine, bool qualifyNames) { var usingList = new List(); List triviaToMove = new List(); @@ -133,6 +139,12 @@ public SyntaxList GenerateGroupedUsings(List 0) + { + var firstUsing = usingList[0]; + usingList[0] = firstUsing.WithLeadingTrivia(firstUsing.GetLeadingTrivia().Insert(0, SyntaxFactory.CarriageReturnLineFeed)); + } + if (withTrailingBlankLine && (usingList.Count > 0)) { var lastUsing = usingList[usingList.Count - 1]; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs index 2320f5dd6..44a244dfc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/UsingCodeFixProvider.cs @@ -225,8 +225,9 @@ private static void BuildReplaceMapForNamespaces(UsingsSorter usingsHelper, Dict } var indentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationSteps); + var withLeadingBlankLine = usingList[0].Parent.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration); - var modifiedUsings = usingsHelper.GenerateGroupedUsings(usingList, indentation, false, qualifyNames); + var modifiedUsings = usingsHelper.GenerateGroupedUsings(usingList, indentation, withLeadingBlankLine, withTrailingBlankLine: false, qualifyNames); for (var i = 0; i < usingList.Count; i++) { @@ -254,7 +255,7 @@ private static void BuildReplaceMapForConditionalDirectives(UsingsSorter usingsH var indentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationSteps); - var modifiedUsings = usingsHelper.GenerateGroupedUsings(childSpan, indentation, false, qualifyNames: false); + var modifiedUsings = usingsHelper.GenerateGroupedUsings(childSpan, indentation, false, false, qualifyNames: false); for (var i = 0; i < originalUsings.Count; i++) { @@ -274,9 +275,10 @@ private static int CompareSpanStart(UsingDirectiveSyntax left, UsingDirectiveSyn private static SyntaxNode AddUsingsToNamespace(SyntaxNode newSyntaxRoot, UsingsSorter usingsHelper, string usingsIndentation, bool hasConditionalDirectives) { var rootNamespace = (BaseNamespaceDeclarationSyntaxWrapper)((CompilationUnitSyntax)newSyntaxRoot).Members.First(member => BaseNamespaceDeclarationSyntaxWrapper.IsInstance(member)); + var withLeadingBlankLine = rootNamespace.SyntaxNode.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration); var withTrailingBlankLine = hasConditionalDirectives || rootNamespace.Members.Any() || rootNamespace.Externs.Any(); - var groupedUsings = usingsHelper.GenerateGroupedUsings(TreeTextSpan.Empty, usingsIndentation, withTrailingBlankLine, qualifyNames: false); + var groupedUsings = usingsHelper.GenerateGroupedUsings(TreeTextSpan.Empty, usingsIndentation, withLeadingBlankLine, withTrailingBlankLine, qualifyNames: false); groupedUsings = groupedUsings.AddRange(rootNamespace.Usings); var newRootNamespace = rootNamespace.WithUsings(groupedUsings); @@ -290,7 +292,7 @@ private static SyntaxNode AddUsingsToCompilationRoot(SyntaxNode newSyntaxRoot, U var newCompilationUnit = (CompilationUnitSyntax)newSyntaxRoot; var withTrailingBlankLine = hasConditionalDirectives || newCompilationUnit.AttributeLists.Any() || newCompilationUnit.Members.Any() || newCompilationUnit.Externs.Any(); - var groupedUsings = usingsHelper.GenerateGroupedUsings(TreeTextSpan.Empty, usingsIndentation, withTrailingBlankLine, qualifyNames: true); + var groupedUsings = usingsHelper.GenerateGroupedUsings(TreeTextSpan.Empty, usingsIndentation, withLeadingBlankLine: false, withTrailingBlankLine, qualifyNames: true); groupedUsings = groupedUsings.AddRange(newCompilationUnit.Usings); newSyntaxRoot = newCompilationUnit.WithUsings(groupedUsings); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs index 8ad951adc..99873bb60 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1200CSharp10UnitTests.cs @@ -25,6 +25,7 @@ namespace TestNamespace; "; var fixedTestCode = @"namespace TestNamespace; + using System; using System.Threading; "; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1208CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1208CSharp10UnitTests.cs index a15f4b365..586ff9d03 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1208CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1208CSharp10UnitTests.cs @@ -21,8 +21,8 @@ public async Task TestWhenSystemUsingDirectivesAreNotOnTopInFileScopedNamespaceA { TestSources = { - "namespace Xyz {}", - "namespace AnotherNamespace {}", + "namespace Xyz;", + "namespace AnotherNamespace;", @" namespace Test; @@ -38,10 +38,11 @@ class A }, FixedSources = { - "namespace Xyz {}", - "namespace AnotherNamespace {}", + "namespace Xyz;", + "namespace AnotherNamespace;", @" namespace Test; + using System; using System.IO; using System.Threading.Tasks; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs index 712fabe87..63154cb18 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1209CSharp10UnitTests.cs @@ -31,6 +31,7 @@ class A } "; var fixedTestCodeNamespace = @"namespace Test; + using System.IO; using System.Net; using System.Threading; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs index bb3e6509c..f7fdd5eee 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10CombinedSystemDirectivesUnitTests.cs @@ -36,10 +36,12 @@ public async Task TestUsingDirectivesInFileScopedNamespaceDeclarationAsync() FixedSources = { @"namespace Food; + using System; using System.Threading; ", @"namespace Bar; + using Bar; using Food; using System; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs index c9db20a85..dc01cb5c4 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1210CSharp10UnitTests.cs @@ -37,10 +37,12 @@ public async Task TestUsingDirectivesInFileScopedNamespaceDeclarationAsync() FixedSources = { @"namespace Foo; + using System; using System.Threading; ", @"namespace Bar; + using System; using System.Threading; using Bar; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs index 043f3ebf2..c75c77705 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1211CSharp10UnitTests.cs @@ -50,11 +50,13 @@ public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() 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; @@ -62,6 +64,7 @@ public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() using StringWriter = System.IO.StringWriter; ", @"namespace Spam; + using System; using Character = System.Char; using @int = System.Int32; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs index b5884e18a..edf5def1f 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1216CSharp10UnitTests.cs @@ -42,11 +42,13 @@ public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() 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; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs index 2595d8fa1..184a6e063 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1217CSharp10UnitTests.cs @@ -43,12 +43,14 @@ public async Task TestUsingDirectivesOrderingInFileScopedNamespaceAsync() 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;