VisualBasicStructureHelpers.vb 5.7 KB
Newer Older
1 2
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

3 4
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.Structure
5 6
Imports Microsoft.CodeAnalysis.Text

7
Namespace Microsoft.CodeAnalysis.VisualBasic.Structure
8 9
    Friend Module VisualBasicOutliningHelpers
        Public Const Ellipsis = "..."
10
        Public Const SpaceEllipsis = " " & Ellipsis
11 12
        Public Const MaxXmlDocCommentBannerLength = 120

13 14 15 16
        Private Function GetNodeBannerText(node As SyntaxNode) As String
            Return node.ConvertToSingleLine().ToString() & SpaceEllipsis
        End Function

17
        Private Function GetCommentBannerText(comment As SyntaxTrivia) As String
18
            Return "' " & comment.ToString().Substring(1).Trim() & SpaceEllipsis
19 20
        End Function

C
CyrusNajmabadi 已提交
21 22
        Private Function CreateCommentsRegion(startComment As SyntaxTrivia,
                                              endComment As SyntaxTrivia) As BlockSpan?
C
CyrusNajmabadi 已提交
23
            Return CreateBlockSpan(
24 25
                TextSpan.FromBounds(startComment.SpanStart, endComment.Span.End),
                GetCommentBannerText(startComment),
26
                autoCollapse:=True,
27
                type:=BlockTypes.Comment,
C
CyrusNajmabadi 已提交
28
                isCollapsible:=True, isDefaultCollapsed:=False)
29 30 31
        End Function

        ' For testing purposes
32
        Friend Function CreateCommentsRegions(triviaList As SyntaxTriviaList) As ImmutableArray(Of BlockSpan)
33
            Dim spans = ArrayBuilder(Of BlockSpan).GetInstance()
34
            CollectCommentsRegions(triviaList, spans)
35
            Return spans.ToImmutableAndFree()
36 37
        End Function

38 39
        Friend Sub CollectCommentsRegions(triviaList As SyntaxTriviaList,
                                          spans As ArrayBuilder(Of BlockSpan))
40 41 42 43 44 45 46 47 48 49 50 51 52 53
            If triviaList.Count > 0 Then
                Dim startComment As SyntaxTrivia? = Nothing
                Dim endComment As SyntaxTrivia? = Nothing

                ' Iterate through trivia and collect groups of contiguous single-line comments that are only separated by whitespace
                For Each trivia In triviaList
                    If trivia.Kind = SyntaxKind.CommentTrivia Then
                        startComment = If(startComment, trivia)
                        endComment = trivia
                    ElseIf trivia.Kind <> SyntaxKind.WhitespaceTrivia AndAlso
                        trivia.Kind <> SyntaxKind.EndOfLineTrivia AndAlso
                        trivia.Kind <> SyntaxKind.EndOfFileToken Then

                        If startComment IsNot Nothing Then
C
CyrusNajmabadi 已提交
54
                            spans.AddIfNotNull(CreateCommentsRegion(startComment.Value, endComment.Value))
55 56 57 58 59 60 61 62
                            startComment = Nothing
                            endComment = Nothing
                        End If
                    End If
                Next

                ' Add any final span
                If startComment IsNot Nothing Then
C
CyrusNajmabadi 已提交
63
                    spans.AddIfNotNull(CreateCommentsRegion(startComment.Value, endComment.Value))
64 65 66 67
                End If
            End If
        End Sub

68
        Friend Sub CollectCommentsRegions(node As SyntaxNode,
69
                                          spans As ArrayBuilder(Of BlockSpan))
70
            If node Is Nothing Then
71
                Throw New ArgumentNullException(NameOf(node))
72 73 74 75 76 77 78
            End If

            Dim triviaList = node.GetLeadingTrivia()

            CollectCommentsRegions(triviaList, spans)
        End Sub

C
CyrusNajmabadi 已提交
79
        Friend Function CreateBlockSpan(
80 81 82 83 84
                span As TextSpan,
                bannerText As String,
                autoCollapse As Boolean,
                type As String,
                isCollapsible As Boolean,
C
CyrusNajmabadi 已提交
85
                isDefaultCollapsed As Boolean) As BlockSpan?
86 87 88 89
            Return New BlockSpan(
                textSpan:=span,
                bannerText:=bannerText,
                autoCollapse:=autoCollapse,
90 91 92
                isDefaultCollapsed:=isDefaultCollapsed,
                type:=type,
                isCollapsible:=isCollapsible)
93 94
        End Function

C
CyrusNajmabadi 已提交
95
        Friend Function CreateBlockSpanFromBlock(
96 97 98 99
                blockNode As SyntaxNode,
                bannerText As String,
                autoCollapse As Boolean,
                type As String,
C
CyrusNajmabadi 已提交
100
                isCollapsible As Boolean) As BlockSpan?
C
CyrusNajmabadi 已提交
101
            Return CreateBlockSpan(blockNode.Span, bannerText, autoCollapse,
C
CyrusNajmabadi 已提交
102
                                type, isCollapsible, isDefaultCollapsed:=False)
103 104
        End Function

C
CyrusNajmabadi 已提交
105
        Friend Function CreateBlockSpanFromBlock(
106 107 108 109
                blockNode As SyntaxNode,
                bannerNode As SyntaxNode,
                autoCollapse As Boolean,
                type As String,
C
CyrusNajmabadi 已提交
110
                isCollapsible As Boolean) As BlockSpan?
C
CyrusNajmabadi 已提交
111
            Return CreateBlockSpan(
112
                blockNode.Span, GetNodeBannerText(bannerNode),
C
CyrusNajmabadi 已提交
113
                autoCollapse, type, isCollapsible, isDefaultCollapsed:=False)
114 115
        End Function

C
CyrusNajmabadi 已提交
116
        Friend Function CreateBlockSpan(syntaxList As IEnumerable(Of SyntaxNode),
117 118 119
                                     bannerText As String,
                                     autoCollapse As Boolean,
                                     type As String,
C
CyrusNajmabadi 已提交
120
                                     isCollapsible As Boolean) As BlockSpan?
121 122 123 124 125 126
            If syntaxList.IsEmpty() Then
                Return Nothing
            End If

            Dim startPos = syntaxList.First().SpanStart
            Dim endPos = syntaxList.Last().Span.End
C
CyrusNajmabadi 已提交
127
            Return CreateBlockSpan(
128
                TextSpan.FromBounds(startPos, endPos), bannerText,
C
CyrusNajmabadi 已提交
129
                autoCollapse, type, isCollapsible, isDefaultCollapsed:=False)
130 131
        End Function
    End Module
132
End Namespace