File: Formatting\Engine\Trivia\TriviaDataFactory.Analyzer.vb
Web Access
Project: src\src\Workspaces\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Workspaces.vbproj (Microsoft.CodeAnalysis.VisualBasic.Workspaces)
' 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.
 
Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
    Partial Friend Class TriviaDataFactory
        Private Class Analyzer
            Public Shared Function Leading(token As SyntaxToken) As AnalysisResult
                Dim result As AnalysisResult
 
                Analyze(token.LeadingTrivia, result)
                Return result
            End Function
 
            Public Shared Function Trailing(token As SyntaxToken) As AnalysisResult
                Dim result As AnalysisResult
 
                Analyze(token.TrailingTrivia, result)
                Return result
            End Function
 
            Public Shared Function Between(token1 As SyntaxToken, token2 As SyntaxToken) As AnalysisResult
                If (Not token1.HasTrailingTrivia) AndAlso (Not token2.HasLeadingTrivia) Then
                    Return Nothing
                End If
 
                Dim result As AnalysisResult
 
                Analyze(token1.TrailingTrivia, result)
                Analyze(token2.LeadingTrivia, result)
                Return result
            End Function
 
            Private Shared Sub Analyze(list As SyntaxTriviaList, ByRef result As AnalysisResult)
                If list.Count = 0 Then
                    Return
                End If
                Dim previousTrivia As New SyntaxTrivia
                For Each trivia In list
                    If trivia.Kind = SyntaxKind.WhitespaceTrivia Then
                        AnalyzeWhitespacesInTrivia(trivia, result)
                    ElseIf trivia.Kind = SyntaxKind.EndOfLineTrivia Then
                        AnalyzeLineBreak(previousTrivia, trivia, result)
                    ElseIf trivia.Kind = SyntaxKind.CommentTrivia OrElse trivia.Kind = SyntaxKind.DocumentationCommentTrivia Then
                        result.HasComments = True
                    ElseIf trivia.Kind = SyntaxKind.DisabledTextTrivia OrElse trivia.Kind = SyntaxKind.SkippedTokensTrivia Then
                        result.HasSkippedOrDisabledText = True
                    ElseIf trivia.Kind = SyntaxKind.LineContinuationTrivia Then
                        AnalyzeLineContinuation(trivia, result)
                    ElseIf trivia.Kind = SyntaxKind.ColonTrivia Then
                        result.HasColonTrivia = True
                    ElseIf trivia.Kind = SyntaxKind.ConflictMarkerTrivia Then
                        result.HasConflictMarker = True
                    Else
                        Contract.ThrowIfFalse(SyntaxFacts.IsPreprocessorDirective(trivia.Kind))
 
                        result.HasPreprocessor = True
                    End If
                    previousTrivia = trivia
                Next
            End Sub
 
            Private Shared Sub AnalyzeLineContinuation(trivia As SyntaxTrivia, ByRef result As AnalysisResult)
                result.LineBreaks += 1
 
                result.HasTrailingSpace = trivia.ToFullString().Length <> 3
                result.HasLineContinuation = True
                result.HasOnlyOneSpaceBeforeLineContinuation = result.Space = 1 AndAlso result.Tab = 0
 
                result.HasTabAfterSpace = False
                result.Space = 0
                result.Tab = 0
            End Sub
 
            Private Shared Sub AnalyzeLineBreak(previousTrivia As SyntaxTrivia, trivia As SyntaxTrivia, ByRef result As AnalysisResult)
                ' if there was any space immediately before line break, then we have trailing spaces
                If previousTrivia.Kind = SyntaxKind.WhitespaceTrivia AndAlso previousTrivia.Width > 0 Then
                    result.HasTrailingSpace = True
                    result.HasTabAfterSpace = False
                    result.Space = 0
                    result.Tab = 0
                    result.TreatAsElastic = result.TreatAsElastic Or trivia.IsElastic()
                End If
 
                ' reset space and tab information
                result.LineBreaks += 1
 
            End Sub
 
            Private Shared Sub AnalyzeWhitespacesInTrivia(trivia As SyntaxTrivia, ByRef result As AnalysisResult)
                ' trivia already has text. getting text should be noop
                Debug.Assert(trivia.Kind = SyntaxKind.WhitespaceTrivia)
                Debug.Assert(trivia.Width = trivia.FullWidth)
 
                Dim space As Integer = 0
                Dim tab As Integer = 0
                Dim unknownWhitespace As Integer = 0
 
                Dim text = trivia.ToString()
                For i As Integer = 0 To trivia.Width - 1
                    If text(i) = " "c Then
                        space += 1
                    ElseIf text(i) = vbTab Then
                        If result.Space > 0 Then
                            result.HasTabAfterSpace = True
                        End If
 
                        tab += 1
                    Else
                        unknownWhitespace += 1
                    End If
                Next i
 
                ' set result
                result.Space += space
                result.Tab += tab
                result.HasUnknownWhitespace = result.HasUnknownWhitespace Or unknownWhitespace > 0
                result.TreatAsElastic = result.TreatAsElastic Or trivia.IsElastic()
            End Sub
 
            Friend Structure AnalysisResult
                Friend Property LineBreaks() As Integer
                Friend Property Space() As Integer
                Friend Property Tab() As Integer
 
                Friend Property HasTabAfterSpace() As Boolean
                Friend Property HasUnknownWhitespace() As Boolean
                Friend Property HasTrailingSpace() As Boolean
                Friend Property HasSkippedOrDisabledText() As Boolean
 
                Friend Property HasComments() As Boolean
                Friend Property HasPreprocessor() As Boolean
                Friend Property HasConflictMarker() As Boolean
 
                Friend Property HasOnlyOneSpaceBeforeLineContinuation() As Boolean
                Friend Property HasLineContinuation() As Boolean
                Friend Property HasColonTrivia() As Boolean
                Friend Property TreatAsElastic() As Boolean
            End Structure
        End Class
    End Class
End Namespace