From 4b1894dfcf22e4852e1d5e82f40f4acc2e1a79e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9F=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D1=85=D0=B8=D0=BD?= Date: Thu, 10 Sep 2015 19:47:13 +0300 Subject: [PATCH] added option alphabeticalsortusing --- .../CodeActions/SortUsingsAction.cs | 10 ++-- .../Formatter/CSharpFormattingOptions.cs | 5 ++ .../Formatter/FormattingOptionsFactory.cs | 1 + .../Refactoring/UsingHelper.cs | 48 +++++++++++++------ 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp.Refactoring/CodeActions/SortUsingsAction.cs b/ICSharpCode.NRefactory.CSharp.Refactoring/CodeActions/SortUsingsAction.cs index 04b8e4d48..fe95fa4f3 100644 --- a/ICSharpCode.NRefactory.CSharp.Refactoring/CodeActions/SortUsingsAction.cs +++ b/ICSharpCode.NRefactory.CSharp.Refactoring/CodeActions/SortUsingsAction.cs @@ -49,7 +49,7 @@ public override IEnumerable GetActions(RefactoringContext context) foreach (var block in blocks) { var originalNodes = block.ToArray(); - var sortedNodes = UsingHelper.SortUsingBlock(originalNodes, context).ToArray(); + var sortedNodes = UsingHelper.SortUsingBlock(originalNodes, context, script).ToArray(); for (var i = 0; i < originalNodes.Length; ++i) script.Replace(originalNodes[i], sortedNodes[i].Clone()); @@ -57,7 +57,7 @@ public override IEnumerable GetActions(RefactoringContext context) }, usingNode); } - static AstNode FindUsingNodeAtCursor(RefactoringContext context) + private static AstNode FindUsingNodeAtCursor(RefactoringContext context) { // If cursor is inside using declaration var locationAsIs = context.Location; @@ -71,12 +71,12 @@ static AstNode FindUsingNodeAtCursor(RefactoringContext context) return usingNode; } - static bool IsUsingDeclaration(AstNode node) + private static bool IsUsingDeclaration(AstNode node) { return node is UsingDeclaration || node is UsingAliasDeclaration; } - static IEnumerable> EnumerateUsingBlocks(AstNode root) + private static IEnumerable> EnumerateUsingBlocks(AstNode root) { var alreadyAddedNodes = new HashSet(); @@ -89,7 +89,7 @@ static IEnumerable> EnumerateUsingBlocks(AstNode root) } } - static IEnumerable EnumerateUsingBlockNodes(AstNode firstNode) + private static IEnumerable EnumerateUsingBlockNodes(AstNode firstNode) { for (var node = firstNode; IsUsingDeclaration(node); node = node.GetNextSibling (n => n.Role != Roles.NewLine)) yield return node; diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs b/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs index 0a97a1c0b..702b3a3cb 100644 --- a/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs +++ b/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs @@ -951,6 +951,11 @@ public UsingPlacement UsingPlacement { get; set; } + + public bool AlphabeticalSortUsing { + get; + set; + } #endregion internal CSharpFormattingOptions() diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs index ff32c1f8c..9672ea2a7 100644 --- a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs +++ b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs @@ -174,6 +174,7 @@ public static CSharpFormattingOptions CreateMono() MinimumBlankLinesBeforeUsings = 0, MinimumBlankLinesAfterUsings = 1, UsingPlacement = UsingPlacement.TopOfFile, + AlphabeticalSortUsing = false, MinimumBlankLinesBeforeFirstDeclaration = 0, MinimumBlankLinesBetweenTypes = 1, diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs index dfc87d21b..01ac91577 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs @@ -47,7 +47,7 @@ public static void InsertUsingAndRemoveRedundantNamespaceUsage(RefactoringContex /// public static void InsertUsing(RefactoringContext context, Script script, AstNode newUsing) { - UsingInfo newUsingInfo = new UsingInfo(newUsing, context); + UsingInfo newUsingInfo = new UsingInfo(newUsing, context, script); AstNode enclosingNamespace = context.GetNode() ?? context.RootNode; // Find nearest enclosing parent that has usings: AstNode usingParent = enclosingNamespace; @@ -71,7 +71,7 @@ public static void InsertUsing(RefactoringContext context, Script script, AstNod insertionPoint = usingParent.GetChildrenByRole(SyntaxTree.MemberRole).SkipWhile(CanAppearBeforeUsings).FirstOrDefault(); } else { insertionPoint = blockStart; - while (IsUsingFollowing (ref insertionPoint) && newUsingInfo.CompareTo(new UsingInfo(insertionPoint, context)) > 0) + while (IsUsingFollowing (ref insertionPoint) && newUsingInfo.CompareTo(new UsingInfo(insertionPoint, context, script)) > 0) insertionPoint = insertionPoint.NextSibling; if (!IsUsingDeclaration(insertionPoint)) { // Insert after last using instead of before next node @@ -122,9 +122,9 @@ static bool CanAppearBeforeUsings(AstNode node) /// /// Sorts the specified usings. /// - public static IEnumerable SortUsingBlock(IEnumerable nodes, BaseRefactoringContext context) + public static IEnumerable SortUsingBlock(IEnumerable nodes, BaseRefactoringContext context, Script script) { - var infos = nodes.Select(_ => new UsingInfo(_, context)); + var infos = nodes.Select(_ => new UsingInfo(_, context, script)); var orderedInfos = infos.OrderBy(_ => _); var orderedNodes = orderedInfos.Select(_ => _.Node); @@ -142,8 +142,9 @@ private sealed class UsingInfo : IComparable public bool IsAlias; public bool HasTypesFromOtherAssemblies; public bool IsSystem; + public bool IsSimpleAlphabeticalCompare; - public UsingInfo(AstNode node, BaseRefactoringContext context) + public UsingInfo(AstNode node, BaseRefactoringContext context, Script script) { var importAndAlias = GetImportAndAlias(node); @@ -154,6 +155,8 @@ public UsingInfo(AstNode node, BaseRefactoringContext context) IsAlias = Alias != null; + IsSimpleAlphabeticalCompare = script.FormattingOptions.AlphabeticalSortUsing; + ResolveResult rr; if (node.Ancestors.Contains(context.RootNode)) { rr = context.Resolve(importAndAlias.Item1); @@ -186,16 +189,33 @@ private static Tuple GetImportAndAlias(AstNode node) public int CompareTo(UsingInfo y) { UsingInfo x = this; - if (x.IsAlias != y.IsAlias) - return x.IsAlias ? 1 : -1; - if (x.IsAlias) - return StringComparer.OrdinalIgnoreCase.Compare(x.Alias, y.Alias); -// if (x.HasTypesFromOtherAssemblies != y.HasTypesFromOtherAssemblies) -// return x.HasTypesFromOtherAssemblies ? -1 : 1; - if (x.IsSystem != y.IsSystem) - return x.IsSystem ? -1 : 1; - return StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name); + if (IsSimpleAlphabeticalCompare) + { + return AlphabeticalCompare(y); + } + else + { + if (x.IsAlias != y.IsAlias) + return x.IsAlias ? 1 : -1; + else if (x.HasTypesFromOtherAssemblies != y.HasTypesFromOtherAssemblies) + return x.HasTypesFromOtherAssemblies ? -1 : 1; + else if (x.IsSystem != y.IsSystem) + return x.IsSystem ? -1 : 1; + else + return AlphabeticalCompare(y); + } } + + private int AlphabeticalCompare(UsingInfo y) + { + UsingInfo x = this; + if (x.Alias != y.Alias) + return StringComparer.Ordinal.Compare(x.Alias, y.Alias); + else if (x.Name != y.Name) + return StringComparer.Ordinal.Compare(x.Name, y.Name); + else + return 0; + } } } }