| File: Organizing\Organizers\MemberDeclarationsOrganizer.Comparer.vb | Web Access |
| Project: src\roslyn\src\Features\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Features.vbproj (Microsoft.CodeAnalysis.VisualBasic.Features) |
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.CodeAnalysis.VisualBasic.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.Organizing.Organizers Partial Friend Class MemberDeclarationsOrganizer Public Class Comparer Implements IComparer(Of StatementSyntax) ' TODO(cyrusn): Allow users to specify the ordering they want Public Enum OuterOrdering Fields EventFields Constructors Destructors Properties Events Indexers Operators ConversionOperators Methods Types Remaining End Enum Public Enum InnerOrdering StaticInstance Accessibility Name End Enum Public Enum Accessibility [Public] [Protected] [Friend] [Private] End Enum Public Function Compare(x As StatementSyntax, y As StatementSyntax) As Integer Implements IComparer(Of StatementSyntax).Compare If x Is y Then Return 0 End If Dim xOuterOrdering = GetOuterOrdering(x) Dim yOuterOrdering = GetOuterOrdering(y) Dim value = xOuterOrdering - yOuterOrdering If value <> 0 Then Return value End If If xOuterOrdering = OuterOrdering.Remaining Then Return 1 ElseIf yOuterOrdering = OuterOrdering.Remaining Then Return -1 End If If xOuterOrdering = OuterOrdering.Fields OrElse yOuterOrdering = OuterOrdering.Fields Then ' Fields with initializers can't be reordered relative to ' themselves due to ordering issues. Dim xHasInitializer = DirectCast(x, FieldDeclarationSyntax).Declarators.Any(Function(v) v.Initializer IsNot Nothing) Dim yHasInitializer = DirectCast(y, FieldDeclarationSyntax).Declarators.Any(Function(v) v.Initializer IsNot Nothing) If xHasInitializer AndAlso yHasInitializer Then Return 0 End If End If Dim xIsShared = x.GetModifiers().Any(Function(t) t.Kind = SyntaxKind.SharedKeyword) Dim yIsShared = y.GetModifiers().Any(Function(t) t.Kind = SyntaxKind.SharedKeyword) value = Comparer(Of Boolean).Default.Inverse().Compare(xIsShared, yIsShared) If value <> 0 Then Return value End If Dim xAccessibility = GetAccessibility(x) Dim yAccessibility = GetAccessibility(y) value = xAccessibility - yAccessibility If value <> 0 Then Return value End If Dim xName = If(ShouldCompareByName(x), TryCast(x, DeclarationStatementSyntax).GetNameToken(), Nothing) Dim yName = If(ShouldCompareByName(x), TryCast(y, DeclarationStatementSyntax).GetNameToken(), Nothing) value = TokenComparer.NormalInstance.Compare(xName, yName) If value <> 0 Then Return value End If ' Their names were the same. Order them by arity at this point. Return x.GetArity() - y.GetArity() End Function Private Shared Function GetAccessibility(x As StatementSyntax) As Accessibility Dim xModifiers = x.GetModifiers() If xModifiers.Any(Function(t) t.Kind = SyntaxKind.PublicKeyword) Then Return Accessibility.Public ElseIf xModifiers.Any(Function(t) t.Kind = SyntaxKind.FriendKeyword) Then Return Accessibility.Friend ElseIf xModifiers.Any(Function(t) t.Kind = SyntaxKind.ProtectedKeyword) Then Return Accessibility.Protected Else ' Only fields are private in VB. All other members are public If x.Kind = SyntaxKind.FieldDeclaration Then Return Accessibility.Private Else Return Accessibility.Public End If End If End Function Private Shared Function GetOuterOrdering(x As StatementSyntax) As OuterOrdering Select Case x.Kind Case SyntaxKind.FieldDeclaration Return OuterOrdering.Fields Case SyntaxKind.ConstructorBlock Return OuterOrdering.Constructors Case SyntaxKind.PropertyBlock Return OuterOrdering.Properties Case SyntaxKind.EventBlock Return OuterOrdering.Events Case SyntaxKind.OperatorBlock Return OuterOrdering.Operators Case SyntaxKind.SubBlock, SyntaxKind.FunctionBlock Return OuterOrdering.Methods Case SyntaxKind.ClassBlock, SyntaxKind.InterfaceBlock, SyntaxKind.StructureBlock, SyntaxKind.EnumBlock, SyntaxKind.DelegateSubStatement, SyntaxKind.DelegateFunctionStatement Return OuterOrdering.Types Case Else Return OuterOrdering.Remaining End Select End Function Private Shared Function ShouldCompareByName(x As StatementSyntax) As Boolean ' Constructors and operators should not be sorted by name. Select Case x.Kind Case SyntaxKind.ConstructorBlock, SyntaxKind.OperatorBlock Return False Case Else Return True End Select End Function End Class End Class End Namespace