File: Syntax\InternalSyntax\VisualBasicSyntaxRewriter.vb
Web Access
Project: src\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic)
' 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.Syntax.InternalSyntax
 
Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
    Partial Friend MustInherit Class VisualBasicSyntaxVisitor
        Public Overridable Function VisitSyntaxToken(token As SyntaxToken) As SyntaxToken
            Debug.Assert(token IsNot Nothing)
            Return token
        End Function
 
        Public Overridable Function VisitSyntaxTrivia(trivia As SyntaxTrivia) As SyntaxTrivia
            Debug.Assert(trivia IsNot Nothing)
            Return trivia
        End Function
    End Class
 
    Partial Friend Class VisualBasicSyntaxRewriter
        Inherits VisualBasicSyntaxVisitor
 
        Public Function VisitList(Of TNode As VisualBasicSyntaxNode)(list As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of TNode)) As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of TNode)
            Dim alternate As SyntaxListBuilder(Of TNode) = Nothing
            Dim i As Integer = 0
            Dim n As Integer = list.Count
            Do While (i < n)
                Dim item As TNode = list.Item(i)
                Dim visited As TNode = DirectCast(Me.Visit(item), TNode)
                If item IsNot visited AndAlso alternate.IsNull Then
                    alternate = New SyntaxListBuilder(Of TNode)(n)
                    alternate.AddRange(list, 0, i)
                End If
 
                If Not alternate.IsNull Then
                    If visited IsNot Nothing AndAlso visited.Kind <> SyntaxKind.None Then
                        alternate.Add(visited)
                    End If
                End If
                i += 1
            Loop
            If Not alternate.IsNull Then
                Return alternate.ToList()
            End If
            Return list
        End Function
 
        Public Function VisitList(Of TNode As VisualBasicSyntaxNode)(list As CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(Of TNode)) As CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(Of TNode)
            Dim alternate As SeparatedSyntaxListBuilder(Of TNode) = Nothing
            Dim i As Integer = 0
            Dim itemCount As Integer = list.Count
            Dim separatorCount As Integer = list.SeparatorCount
 
            While i < itemCount
                Dim item = list(i)
                Dim visitedItem = Me.Visit(item)
 
                Dim separator As GreenNode = Nothing
                Dim visitedSeparator As GreenNode = Nothing
 
                If (i < separatorCount) Then
                    separator = list.GetSeparator(i)
                    ' LastTokenReplacer depends on us calling Visit rather than VisitToken for separators.
                    ' It is not clear whether this is desirable/acceptable.
                    Dim visitedSeparatorNode = Me.Visit(DirectCast(separator, VisualBasicSyntaxNode))
                    Debug.Assert(TypeOf visitedSeparatorNode Is SyntaxToken, "Cannot replace a separator with a non-separator")
 
                    visitedSeparator = DirectCast(visitedSeparatorNode, SyntaxToken)
 
                    Debug.Assert((separator Is Nothing AndAlso separator.RawKind = SyntaxKind.None) OrElse
                        (visitedSeparator IsNot Nothing AndAlso visitedSeparator.RawKind <> SyntaxKind.None),
                    "Cannot delete a separator from a separated list. Removing an element will remove the corresponding separator.")
                End If
 
                If (item IsNot visitedItem OrElse separator IsNot visitedSeparator) AndAlso alternate.IsNull Then
                    alternate = New SeparatedSyntaxListBuilder(Of TNode)(itemCount)
                    alternate.AddRange(list, i)
                End If
 
                If Not alternate.IsNull Then
                    If visitedItem IsNot Nothing AndAlso visitedItem.Kind <> SyntaxKind.None Then
                        alternate.Add(DirectCast(visitedItem, TNode))
                        If visitedSeparator IsNot Nothing Then
                            alternate.AddSeparator(visitedSeparator)
                        End If
                    ElseIf i >= separatorCount AndAlso alternate.Count > 0 Then ' last element deleted
                        alternate.RemoveLast() ' delete *preceding* separator
                    End If
                End If
 
                i += 1
            End While
 
            If Not alternate.IsNull Then
                Return alternate.ToList()
            End If
 
            Return list
        End Function
    End Class
End Namespace