| File: Organizing\Organizers\MemberDeclarationsOrganizer.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 System.Threading Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Organizing.Organizers Partial Friend Class MemberDeclarationsOrganizer Private Sub New() End Sub Public Shared Function Organize(members As SyntaxList(Of StatementSyntax), cancellationToken As CancellationToken) As SyntaxList(Of StatementSyntax) ' Break the list of members up into groups based on the PP ' directives between them. Dim groups = members.SplitNodesOnPreprocessorBoundaries(cancellationToken) ' Go into each group and organize them. We'll then have a list of ' lists. Flatten that list and return that. Dim sortedGroups = groups.Select(AddressOf OrganizeMemberGroup).Flatten().ToList() If sortedGroups.SequenceEqual(members) Then Return members End If Return SyntaxFactory.List(sortedGroups) End Function Private Shared Sub TransferTrivia(Of TSyntaxNode As SyntaxNode)( originalList As IList(Of TSyntaxNode), finalList As IList(Of TSyntaxNode)) Debug.Assert(originalList.Count = finalList.Count) If originalList.Count >= 2 Then ' Ok, we wanted to reorder the list. But we're definitely not done right now. While ' most of the list will look fine, we will have issues with the first node. First, ' we don't want to move any pp directives or banners that are on the first node. ' Second, it can often be the case that the node doesn't even have any trivia. We ' want to follow the user's style. So we find the node that was in the index that ' the first node moved to, and we attempt to keep an appropriate amount of ' whitespace based on that. ' ' If the first node didn't move, then we don't need to do any of this special fixup ' logic. If originalList(0) IsNot finalList(0) Then ' First. Strip any pp directives or banners on the first node. They have to ' move to the first node in the final list. CopyBanner(originalList, finalList) ' Now, we need to fix up the first node wherever it is in the final list. We ' need to strip it of its banner, and we need to add additional whitespace to ' match the user's style FixupOriginalFirstNode(Of TSyntaxNode)(originalList, finalList) End If End If End Sub Private Shared Sub FixupOriginalFirstNode(Of TSyntaxNode As SyntaxNode)( originalList As IList(Of TSyntaxNode), finalList As IList(Of TSyntaxNode)) ' Now, find the original node in the final list. Dim originalFirstNode = originalList(0) Dim indexInFinalList = finalList.IndexOf(originalFirstNode) ' Find the initial node we had at that same index. Dim originalNodeAtThatIndex = originalList(indexInFinalList) ' If that node had blank lines above it, then place that number of blank ' lines before the first node in the final list. Dim blankLines = originalNodeAtThatIndex.GetLeadingBlankLines() originalFirstNode = originalFirstNode.GetNodeWithoutLeadingBannerAndPreprocessorDirectives(). WithPrependedLeadingTrivia(blankLines) finalList(indexInFinalList) = originalFirstNode End Sub Private Shared Sub CopyBanner(Of TSyntaxNode As SyntaxNode)( originalList As IList(Of TSyntaxNode), finalList As IList(Of TSyntaxNode)) ' First. Strip any pp directives or banners on the first node. They ' have to stay at the top of the list. Dim banner = originalList(0).GetLeadingBannerAndPreprocessorDirectives() ' Now, we want to remove any blank lines from the new first node and then ' reattach the banner. Dim finalFirstNode = finalList(0) finalFirstNode = finalFirstNode.GetNodeWithoutLeadingBlankLines() finalFirstNode = finalFirstNode.WithLeadingTrivia(banner.Concat(finalFirstNode.GetLeadingTrivia())) ' Place the updated first node back in the result list finalList(0) = finalFirstNode End Sub Private Shared Function OrganizeMemberGroup(members As IList(Of StatementSyntax)) As IList(Of StatementSyntax) If members.Count > 1 Then Dim originalList = New List(Of StatementSyntax)(members) Dim finalList = originalList.OrderBy(New Comparer()).ToList() If Not finalList.SequenceEqual(originalList) Then TransferTrivia(originalList, finalList) Return finalList End If End If Return members End Function End Class End Namespace