| File: Syntax\VisualBasicSyntaxRewriter.vb | Web Access |
| Project: src\roslyn\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 Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic ''' <summary> ''' Represents a <see cref="VisualBasicSyntaxVisitor"/> which descends an entire <see cref="SyntaxNode"/> graph and ''' may replace or remove visited SyntaxNodes in depth-first order. ''' </summary> Partial Public Class VisualBasicSyntaxRewriter Inherits VisualBasicSyntaxVisitor(Of SyntaxNode) Private ReadOnly _visitIntoStructuredTrivia As Boolean Public Sub New(Optional visitIntoStructuredTrivia As Boolean = False) Me._visitIntoStructuredTrivia = visitIntoStructuredTrivia End Sub Public Overridable ReadOnly Property VisitIntoStructuredTrivia As Boolean Get Return Me._visitIntoStructuredTrivia End Get End Property Private _recursionDepth As Integer Public Overrides Function Visit(node As SyntaxNode) As SyntaxNode If node IsNot Nothing Then _recursionDepth += 1 StackGuard.EnsureSufficientExecutionStack(_recursionDepth) Dim result = DirectCast(node, VisualBasicSyntaxNode).Accept(Me) _recursionDepth -= 1 Return result Else Return node End If End Function Public Overridable Function VisitToken(token As SyntaxToken) As SyntaxToken Dim leading = Me.VisitList(token.LeadingTrivia) Dim trailing = Me.VisitList(token.TrailingTrivia) If leading <> token.LeadingTrivia OrElse trailing <> token.TrailingTrivia Then If leading <> token.LeadingTrivia Then token = token.WithLeadingTrivia(leading) End If If trailing <> token.TrailingTrivia Then token = token.WithTrailingTrivia(trailing) End If End If Return token End Function Public Overridable Function VisitTrivia(trivia As SyntaxTrivia) As SyntaxTrivia If Me.VisitIntoStructuredTrivia AndAlso trivia.HasStructure Then Dim [structure] = DirectCast(trivia.GetStructure(), VisualBasicSyntaxNode) Dim newStructure = DirectCast(Me.Visit([structure]), StructuredTriviaSyntax) If newStructure IsNot [structure] Then If newStructure IsNot Nothing Then Return SyntaxFactory.Trivia(newStructure) Else Return Nothing End If End If End If Return trivia End Function Public Overridable Function VisitList(Of TNode As SyntaxNode)(list As SyntaxList(Of TNode)) As SyntaxList(Of TNode) Dim alternate As SyntaxListBuilder = Nothing Dim i = 0, n = list.Count While i < n Dim item = list(i) Dim visited = Me.VisitListElement(item) If item IsNot visited AndAlso alternate Is Nothing Then alternate = New SyntaxListBuilder(n) alternate.AddRange(list, 0, i) End If If alternate IsNot Nothing AndAlso visited IsNot Nothing AndAlso visited.Kind <> SyntaxKind.None Then alternate.Add(visited) End If i = i + 1 End While If alternate IsNot Nothing Then Return alternate.ToList(Of TNode)() End If Return list End Function Public Overridable Function VisitListElement(Of TNode As SyntaxNode)(node As TNode) As TNode Return DirectCast(Me.Visit(node), TNode) End Function Public Overridable Function VisitList(list As SyntaxTokenList) As SyntaxTokenList Dim alternate As SyntaxTokenListBuilder = Nothing Dim i = -1, n = list.Count For Each item In list i = i + 1 Dim visited = Me.VisitListElement(item) If item <> visited AndAlso alternate Is Nothing Then alternate = New SyntaxTokenListBuilder(n) alternate.Add(list, 0, i) End If If alternate IsNot Nothing AndAlso visited.Kind <> SyntaxKind.None Then ' skip the null check since SyntaxToken is a value type alternate.Add(visited) End If Next If alternate IsNot Nothing Then Return alternate.ToList() End If Return list End Function Public Overridable Function VisitListElement(token As SyntaxToken) As SyntaxToken Return Me.VisitToken(token) End Function Public Overridable Function VisitList(Of TNode As SyntaxNode)(list As SeparatedSyntaxList(Of TNode)) As SeparatedSyntaxList(Of TNode) Dim count As Integer = list.Count Dim sepCount As Integer = list.SeparatorCount Dim alternate As SeparatedSyntaxListBuilder(Of TNode) = Nothing Dim i As Integer = 0 While i < sepCount Dim node As TNode = list(i) Dim visitedNode As TNode = Me.VisitListElement(Of TNode)(node) Dim separator As SyntaxToken = list.GetSeparator(i) Dim visitedSeparator As SyntaxToken = Me.VisitListSeparator(separator) If alternate.IsNull Then If node IsNot visitedNode OrElse separator <> visitedSeparator Then alternate = New SeparatedSyntaxListBuilder(Of TNode)(count) alternate.AddRange(list, i) End If End If If Not alternate.IsNull Then If visitedNode IsNot Nothing Then alternate.Add(visitedNode) If visitedSeparator.RawKind = 0 Then Throw New InvalidOperationException("separator is expected") End If alternate.AddSeparator(visitedSeparator) Else If visitedNode Is Nothing Then Throw New InvalidOperationException("element is expected") End If End If End If i += 1 End While If i < count Then Dim node As TNode = list(i) Dim visitedNode As TNode = Me.VisitListElement(Of TNode)(node) If alternate.IsNull Then If node IsNot visitedNode Then alternate = New SeparatedSyntaxListBuilder(Of TNode)(count) alternate.AddRange(list, i) End If End If If Not alternate.IsNull AndAlso visitedNode IsNot Nothing Then alternate.Add(visitedNode) End If End If If Not alternate.IsNull Then Return alternate.ToList() End If Return list End Function Public Overridable Function VisitListSeparator(token As SyntaxToken) As SyntaxToken Return Me.VisitToken(token) End Function Public Overridable Function VisitList(list As SyntaxTriviaList) As SyntaxTriviaList Dim count = list.Count If count <> 0 Then Dim alternate As SyntaxTriviaListBuilder = Nothing Dim index = -1 For Each item In list index += 1 Dim visited = Me.VisitListElement(item) 'skip the null check since SyntaxTrivia Is a value type If visited <> item AndAlso alternate Is Nothing Then alternate = New SyntaxTriviaListBuilder(count) alternate.Add(list, 0, index) End If If alternate IsNot Nothing AndAlso visited.Kind() <> SyntaxKind.None Then alternate.Add(visited) End If Next If alternate IsNot Nothing Then Return alternate.ToList() End If End If Return list End Function Public Overridable Function VisitListElement(element As SyntaxTrivia) As SyntaxTrivia Return Me.VisitTrivia(element) End Function End Class End Namespace