Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Added option "AlphabeticalSortUsing" #502

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ public override IEnumerable<CodeAction> 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());
}
}, usingNode);
}

static AstNode FindUsingNodeAtCursor(RefactoringContext context)
private static AstNode FindUsingNodeAtCursor(RefactoringContext context)
{
// If cursor is inside using declaration
var locationAsIs = context.Location;
Expand All @@ -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<IEnumerable<AstNode>> EnumerateUsingBlocks(AstNode root)
private static IEnumerable<IEnumerable<AstNode>> EnumerateUsingBlocks(AstNode root)
{
var alreadyAddedNodes = new HashSet<AstNode>();

Expand All @@ -89,7 +89,7 @@ static IEnumerable<IEnumerable<AstNode>> EnumerateUsingBlocks(AstNode root)
}
}

static IEnumerable<AstNode> EnumerateUsingBlockNodes(AstNode firstNode)
private static IEnumerable<AstNode> EnumerateUsingBlockNodes(AstNode firstNode)
{
for (var node = firstNode; IsUsingDeclaration(node); node = node.GetNextSibling (n => n.Role != Roles.NewLine))
yield return node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,11 @@ public UsingPlacement UsingPlacement {
get;
set;
}

public bool AlphabeticalSortUsing {
get;
set;
}
#endregion

internal CSharpFormattingOptions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ public static CSharpFormattingOptions CreateMono()
MinimumBlankLinesBeforeUsings = 0,
MinimumBlankLinesAfterUsings = 1,
UsingPlacement = UsingPlacement.TopOfFile,
AlphabeticalSortUsing = false,

MinimumBlankLinesBeforeFirstDeclaration = 0,
MinimumBlankLinesBetweenTypes = 1,
Expand Down
48 changes: 34 additions & 14 deletions ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static void InsertUsingAndRemoveRedundantNamespaceUsage(RefactoringContex
/// </summary>
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<NamespaceDeclaration>() ?? context.RootNode;
// Find nearest enclosing parent that has usings:
AstNode usingParent = enclosingNamespace;
Expand All @@ -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
Expand Down Expand Up @@ -122,9 +122,9 @@ static bool CanAppearBeforeUsings(AstNode node)
/// <summary>
/// Sorts the specified usings.
/// </summary>
public static IEnumerable<AstNode> SortUsingBlock(IEnumerable<AstNode> nodes, BaseRefactoringContext context)
public static IEnumerable<AstNode> SortUsingBlock(IEnumerable<AstNode> 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);

Expand All @@ -142,8 +142,9 @@ private sealed class UsingInfo : IComparable<UsingInfo>
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);

Expand All @@ -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);
Expand Down Expand Up @@ -186,16 +189,33 @@ private static Tuple<AstType, string> 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;
}
}
}
}