diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs index 408ed84dd0f7d73aace847ba4949f6d14b6c09ff..c95aa55acc48d750cba9a9e6533acf3c9effbef3 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs @@ -172,7 +172,9 @@ public static MemberDeclarationSyntax LastOperator(SyntaxList, TDeclaration> before = null) where TDeclaration : SyntaxNode { - var index = GetInsertionIndex(declarationList, declaration, options, availableIndices, after, before); + var index = GetInsertionIndex( + declarationList, declaration, options, availableIndices, + CSharpDeclarationComparer.Instance, after, before); if (availableIndices != null) { availableIndices.Insert(index, true); @@ -191,114 +193,6 @@ public static MemberDeclarationSyntax LastOperator(SyntaxList t.IsKind(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken) && t.IsMissing).Any(); } - public static int GetInsertionIndex( - SyntaxList declarationList, - TDeclaration declaration, - CodeGenerationOptions options, - IList availableIndices, - Func, TDeclaration> after = null, - Func, TDeclaration> before = null) - where TDeclaration : SyntaxNode - { - Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); - - if (options != null) - { - // Try to strictly obey the after option by inserting immediately after the member containing the location - if (options.AfterThisLocation != null) - { - var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); - if (afterMember != null) - { - var index = declarationList.IndexOf(afterMember); - index = GetPreferredIndex(index + 1, availableIndices, forward: true); - if (index != -1) - { - return index; - } - } - } - - // Try to strictly obey the before option by inserting immediately before the member containing the location - if (options.BeforeThisLocation != null) - { - var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); - if (beforeMember != null) - { - var index = declarationList.IndexOf(beforeMember); - index = GetPreferredIndex(index, availableIndices, forward: false); - if (index != -1) - { - return index; - } - } - } - - if (options.AutoInsertionLocation) - { - if (declarationList.IsEmpty()) - { - return 0; - } - else if (declarationList.IsSorted(CSharpDeclarationComparer.Instance)) - { - var result = Array.BinarySearch(declarationList.ToArray(), declaration, CSharpDeclarationComparer.Instance); - var index = GetPreferredIndex(result < 0 ? ~result : result, availableIndices, forward: true); - if (index != -1) - { - return index; - } - } - - if (after != null) - { - var member = after(declarationList); - if (member != null) - { - var index = declarationList.IndexOf(member); - if (index >= 0) - { - index = GetPreferredIndex(index + 1, availableIndices, forward: true); - if (index != -1) - { - return index; - } - } - } - } - - if (before != null) - { - var member = before(declarationList); - if (member != null) - { - var index = declarationList.IndexOf(member); - - if (index >= 0) - { - index = GetPreferredIndex(index, availableIndices, forward: false); - if (index != -1) - { - return index; - } - } - } - } - } - } - - // Otherwise, add the declaration to the end. - { - var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); - if (index != -1) - { - return index; - } - } - - return declarationList.Count; - } - public static SyntaxNode GetContextNode( Location location, CancellationToken cancellationToken) { diff --git a/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationHelpers.cs b/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationHelpers.cs index b05de53adc12d3f935adab05ef468cc85eabc46f..a33b35b34f72c3cee553d0d61c02c71f6cc660d5 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationHelpers.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationHelpers.cs @@ -228,5 +228,114 @@ public static T GetReuseableSyntaxNodeForAttribute(AttributeData attribute, C attribute.ApplicationSyntaxReference.GetSyntax() as T : null; } + + public static int GetInsertionIndex( + SyntaxList declarationList, + TDeclaration declaration, + CodeGenerationOptions options, + IList availableIndices, + IComparer comparer, + Func, TDeclaration> after = null, + Func, TDeclaration> before = null) + where TDeclaration : SyntaxNode + { + Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); + + if (options != null) + { + // Try to strictly obey the after option by inserting immediately after the member containing the location + if (options.AfterThisLocation != null) + { + var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); + if (afterMember != null) + { + var index = declarationList.IndexOf(afterMember); + index = GetPreferredIndex(index + 1, availableIndices, forward: true); + if (index != -1) + { + return index; + } + } + } + + // Try to strictly obey the before option by inserting immediately before the member containing the location + if (options.BeforeThisLocation != null) + { + var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); + if (beforeMember != null) + { + var index = declarationList.IndexOf(beforeMember); + index = GetPreferredIndex(index, availableIndices, forward: false); + if (index != -1) + { + return index; + } + } + } + + if (options.AutoInsertionLocation) + { + if (declarationList.IsEmpty()) + { + return 0; + } + else if (declarationList.IsSorted(comparer)) + { + var result = Array.BinarySearch(declarationList.ToArray(), declaration, comparer); + var index = GetPreferredIndex(result < 0 ? ~result : result, availableIndices, forward: true); + if (index != -1) + { + return index; + } + } + + if (after != null) + { + var member = after(declarationList); + if (member != null) + { + var index = declarationList.IndexOf(member); + if (index >= 0) + { + index = GetPreferredIndex(index + 1, availableIndices, forward: true); + if (index != -1) + { + return index; + } + } + } + } + + if (before != null) + { + var member = before(declarationList); + if (member != null) + { + var index = declarationList.IndexOf(member); + + if (index >= 0) + { + index = GetPreferredIndex(index, availableIndices, forward: false); + if (index != -1) + { + return index; + } + } + } + } + } + } + + // Otherwise, add the declaration to the end. + { + var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); + if (index != -1) + { + return index; + } + } + + return declarationList.Count; + } } } diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb index be6b7a64b12f6c754b6fda7e8b2e4761ab142435..45d8172671fe77c24023e1a791441461dd4e6ddb 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb @@ -149,7 +149,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration before = BeforeDeclaration(declarationList, options, before) Dim index = GetInsertionIndex( - declarationList, declaration, options, availableIndices, after, before) + declarationList, declaration, options, availableIndices, + VisualBasicDeclarationComparer.Instance, after, before) If availableIndices IsNot Nothing Then availableIndices.Insert(index, True) @@ -158,84 +159,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Return declarationList.Insert(index, declaration) End Function - Private Function GetInsertionIndex(Of TDeclaration As SyntaxNode)( - declarationList As SyntaxList(Of TDeclaration), - declaration As TDeclaration, - options As CodeGenerationOptions, - availableIndices As IList(Of Boolean), - after As Func(Of SyntaxList(Of TDeclaration), TDeclaration), - before As Func(Of SyntaxList(Of TDeclaration), TDeclaration)) As Integer - - If options IsNot Nothing Then - ' Try to use AfterThisLocation - If options.AfterThisLocation IsNot Nothing Then - Dim afterMember = declarationList.LastOrDefault(Function(m) m.SpanStart <= options.AfterThisLocation.SourceSpan.Start) - If afterMember IsNot Nothing Then - Dim index = declarationList.IndexOf(afterMember) - index = GetPreferredIndex(index + 1, availableIndices, forward:=True) - If index <> -1 Then - Return index - End If - End If - End If - - ' Try to use BeforeThisLocation - If options.BeforeThisLocation IsNot Nothing Then - Dim beforeMember = declarationList.FirstOrDefault(Function(m) m.Span.End >= options.BeforeThisLocation.SourceSpan.End) - If beforeMember IsNot Nothing Then - Dim index = declarationList.IndexOf(beforeMember) - index = GetPreferredIndex(index, availableIndices, forward:=False) - If index <> -1 Then - Return index - End If - End If - End If - - If options.AutoInsertionLocation Then - Dim declarations = declarationList.ToArray() - If (declarations.Length = 0) Then - Return 0 - ElseIf declarations.IsSorted(VisualBasicDeclarationComparer.Instance) Then - Dim result = Array.BinarySearch(Of TDeclaration)(declarations, declaration, VisualBasicDeclarationComparer.Instance) - Dim index = GetPreferredIndex(If(result < 0, Not result, result), availableIndices, forward:=True) - If index <> -1 Then - Return index - End If - End If - - If after IsNot Nothing Then - Dim member = after(declarationList) - If member IsNot Nothing Then - Dim index = declarationList.IndexOf(member) - index = GetPreferredIndex(index + 1, availableIndices, forward:=True) - If index <> -1 Then - Return index - End If - End If - End If - - If before IsNot Nothing Then - Dim member = before(declarationList) - If member IsNot Nothing Then - Dim index = declarationList.IndexOf(member) - index = GetPreferredIndex(index, availableIndices, forward:=False) - If index <> -1 Then - Return index - End If - End If - End If - End If - End If - - ' Otherwise, add the method to the end. - Dim index1 = GetPreferredIndex(declarationList.Count, availableIndices, forward:=False) - If index1 <> -1 Then - Return index1 - End If - - Return declarationList.Count - End Function - Public Function GetDestination(destination As SyntaxNode) As CodeGenerationDestination If destination IsNot Nothing Then Select Case destination.Kind