TypeSyntaxGeneratorVisitor.vb 9.3 KB
Newer Older
1
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax

Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions

    Friend Class TypeSyntaxGeneratorVisitor
        Inherits SymbolVisitor(Of TypeSyntax)

B
beep boop 已提交
18
        Private ReadOnly _addGlobal As Boolean
P
Pilchie 已提交
19 20

        Public Sub New(addGlobal As Boolean)
B
beep boop 已提交
21
            Me._addGlobal = addGlobal
P
Pilchie 已提交
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
        End Sub

        Public Overrides Function DefaultVisit(node As ISymbol) As TypeSyntax
            Throw New NotImplementedException()
        End Function

        Private Function AddInformationTo(Of TTypeSyntax As TypeSyntax)(type As TTypeSyntax, symbol As ISymbol) As TTypeSyntax
            type = type.WithPrependedLeadingTrivia(SyntaxFactory.ElasticMarker).WithAppendedTrailingTrivia(SyntaxFactory.ElasticMarker)
            type = type.WithAdditionalAnnotations(SymbolAnnotation.Create(symbol))
            Return type
        End Function

        Public Overrides Function VisitAlias(symbol As IAliasSymbol) As TypeSyntax
            Return AddInformationTo(symbol.Name.ToIdentifierName, symbol)
        End Function

        Public Overrides Function VisitArrayType(symbol As IArrayTypeSymbol) As TypeSyntax
            Dim underlyingNonArrayType = symbol.ElementType
            While underlyingNonArrayType.Kind = SymbolKind.ArrayType
                underlyingNonArrayType = (DirectCast(underlyingNonArrayType, IArrayTypeSymbol)).ElementType
            End While

            Dim elementTypeSyntax = underlyingNonArrayType.Accept(Me)
            Dim ranks = New List(Of ArrayRankSpecifierSyntax)()
            Dim arrayType = symbol
            While arrayType IsNot Nothing
                Dim commaCount = Math.Max(0, arrayType.Rank - 1)
                Dim commas = SyntaxFactory.TokenList(Enumerable.Repeat(SyntaxFactory.Token(SyntaxKind.CommaToken), commaCount))
                ranks.Add(SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.Token(SyntaxKind.OpenParenToken), commas, SyntaxFactory.Token(SyntaxKind.CloseParenToken)))
                arrayType = TryCast(arrayType.ElementType, IArrayTypeSymbol)
            End While

            Dim arrayTypeSyntax = SyntaxFactory.ArrayType(elementTypeSyntax, SyntaxFactory.List(ranks))
            Return AddInformationTo(arrayTypeSyntax, symbol)
        End Function

        Public Overrides Function VisitDynamicType(symbol As IDynamicTypeSymbol) As TypeSyntax
            Return AddInformationTo(SyntaxFactory.IdentifierName("dynamic"), symbol)
        End Function

        Public Function CreateSimpleTypeSyntax(symbol As INamedTypeSymbol) As TypeSyntax
            Select Case symbol.SpecialType
                Case SpecialType.System_Object
B
Basoundr_ms 已提交
65
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object"))
P
Pilchie 已提交
66
                Case SpecialType.System_Boolean
B
Basoundr_ms 已提交
67
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Boolean"))
P
Pilchie 已提交
68
                Case SpecialType.System_Char
B
Basoundr_ms 已提交
69
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Char"))
P
Pilchie 已提交
70
                Case SpecialType.System_SByte
B
Basoundr_ms 已提交
71
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("SByte"))
P
Pilchie 已提交
72
                Case SpecialType.System_Byte
B
Basoundr_ms 已提交
73
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Byte"))
P
Pilchie 已提交
74
                Case SpecialType.System_Int16
B
Basoundr_ms 已提交
75
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int16"))
P
Pilchie 已提交
76
                Case SpecialType.System_UInt16
B
Basoundr_ms 已提交
77
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt16"))
P
Pilchie 已提交
78
                Case SpecialType.System_Int32
B
Basoundr_ms 已提交
79
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int32"))
P
Pilchie 已提交
80
                Case SpecialType.System_Int64
B
Basoundr_ms 已提交
81
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int64"))
P
Pilchie 已提交
82
                Case SpecialType.System_UInt32
B
Basoundr_ms 已提交
83
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt32"))
P
Pilchie 已提交
84
                Case SpecialType.System_UInt64
B
Basoundr_ms 已提交
85
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt64"))
P
Pilchie 已提交
86
                Case SpecialType.System_Decimal
B
Basoundr_ms 已提交
87
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Decimal"))
P
Pilchie 已提交
88
                Case SpecialType.System_Single
B
Basoundr_ms 已提交
89
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Single"))
P
Pilchie 已提交
90
                Case SpecialType.System_Double
B
Basoundr_ms 已提交
91
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Double"))
P
Pilchie 已提交
92
                Case SpecialType.System_String
B
Basoundr_ms 已提交
93
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("String"))
P
Pilchie 已提交
94
                Case SpecialType.System_DateTime
B
Basoundr_ms 已提交
95
                    Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("DateTime"))
P
Pilchie 已提交
96 97 98
            End Select

            If symbol.Name = String.Empty OrElse symbol.IsAnonymousType Then
B
Basoundr_ms 已提交
99
                Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object"))
P
Pilchie 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
            End If

            If symbol.OriginalDefinition.SpecialType = SpecialType.System_Nullable_T Then
                Return AddInformationTo(SyntaxFactory.NullableType(symbol.TypeArguments.First().Accept(Me)), symbol)
            End If

            If symbol.TypeParameters.Length = 0 Then
                Return symbol.Name.ToIdentifierName
            End If

            Return SyntaxFactory.GenericName(
                symbol.Name.ToIdentifierToken,
                SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(symbol.TypeArguments.[Select](Function(t) t.Accept(Me)))))
        End Function

        Public Overrides Function VisitNamedType(symbol As INamedTypeSymbol) As TypeSyntax
            Dim typeSyntax = CreateSimpleTypeSyntax(symbol)
            If Not (TypeOf typeSyntax Is SimpleNameSyntax) Then
                Return typeSyntax
            End If

            Dim simpleNameSyntax = DirectCast(typeSyntax, SimpleNameSyntax)
            If symbol.ContainingType IsNot Nothing Then
                If symbol.ContainingType.TypeKind = TypeKind.Submission Then
                    Return typeSyntax
                Else
                    Return AddInformationTo(SyntaxFactory.QualifiedName(DirectCast(symbol.ContainingType.Accept(Me), NameSyntax), simpleNameSyntax), symbol)
                End If
            ElseIf symbol.ContainingNamespace IsNot Nothing Then
                If symbol.ContainingNamespace.IsGlobalNamespace Then
B
beep boop 已提交
130
                    If _addGlobal AndAlso symbol.TypeKind <> TypeKind.[Error] Then
P
Pilchie 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
                        Return AddInformationTo(SyntaxFactory.QualifiedName(SyntaxFactory.GlobalName(), simpleNameSyntax), symbol)
                    End If
                Else
                    Dim container = symbol.ContainingNamespace.Accept(Me)
                    Return AddInformationTo(SyntaxFactory.QualifiedName(DirectCast(container, NameSyntax), simpleNameSyntax), symbol)
                End If
            End If

            Return simpleNameSyntax
        End Function

        Public Overrides Function VisitNamespace(symbol As INamespaceSymbol) As TypeSyntax
            Dim result = AddInformationTo(symbol.Name.ToIdentifierName, symbol)
            If symbol.ContainingNamespace Is Nothing Then
                Return result
            End If

            If symbol.ContainingNamespace.IsGlobalNamespace Then
B
beep boop 已提交
149
                If _addGlobal Then
P
Pilchie 已提交
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
                    Return AddInformationTo(SyntaxFactory.QualifiedName(SyntaxFactory.GlobalName(), result), symbol)
                Else
                    Return result
                End If
            Else
                Dim container = symbol.ContainingNamespace.Accept(Me)
                Return AddInformationTo(SyntaxFactory.QualifiedName(DirectCast(container, NameSyntax), result), symbol)
            End If
        End Function

        Public Overrides Function VisitPointerType(symbol As IPointerTypeSymbol) As TypeSyntax
            ' TODO(cyrusn): What to do here?  Maybe object would be better instead?
            Return symbol.PointedAtType.Accept(Me)
        End Function

        Public Overrides Function VisitTypeParameter(symbol As ITypeParameterSymbol) As TypeSyntax
            Return AddInformationTo(symbol.Name.ToIdentifierName, symbol)
        End Function
    End Class
169
End Namespace