Jim Wooley
Jim Wooley

Reputation: 10418

Get the TypeSymbol for ain inferred variable in VB with Roslyn

Using Roslyn in VB, I'm trying to access the ITypeSymbol for a variable declared using type inference, but am struggling to return the right node. I want the ITypeSymbol to be able to identify if a variable is a reference type or not. In comparison, this is relatively easy in C#. In that case, we can simply take the node.Declaration.Type but that's not available off of the VB Declarator.

In the following example, I'm able to access the TypeSymbol from the AsClause for the b declaration, but that is null for an inferred type used in the a variable:

Imports System.IO

Module Module1

    Sub Main()
        Dim code = "
Class C
    Shared Sub Main()
        Dim a = """"
        Dim b As String = """"
    End Sub
End Class"

    Dim tree = SyntaxFactory.ParseSyntaxTree(code)
    Dim compilation = VisualBasicCompilation.Create("test", {tree}, {MetadataReference.CreateFromAssembly(GetType(Object).Assembly)})

    Dim result = compilation.Emit(New MemoryStream)

    Dim semanticModel = compilation.GetSemanticModel(tree)

    Dim localNodes = tree.GetRoot().DescendantNodes.OfType(Of LocalDeclarationStatementSyntax)
    For Each node In localNodes
        Dim localSym = semanticModel.GetDeclaredSymbol(node.Declarators.Single.Names.Single)
        Trace.WriteLine(localSym.ToDisplayString())

        ' TODO: Figure how to get the typeinfo from inferred type
        Dim symbol = semanticModel.GetTypeInfo(node) ' Is Nothing
        Dim variableType = node.Declarators.First.AsClause?.Type ' This is null for inferred types
        If variableType IsNot Nothing Then
            Dim typeSymbol = SemanticModel.GetTypeInfo(variableType).ConvertedType
            If typeSymbol.IsReferenceType AndAlso typeSymbol.SpecialType <> SpecialType.System_String Then
                ' Real processing goes here

            End If
        End If


    Next

    End Sub

End Module

Upvotes: 0

Views: 163

Answers (1)

Kevin Pilch
Kevin Pilch

Reputation: 11615

You can get the type of the local from localSym above:

DirectCast(localSym, ILocalSymbol).Type

It's unfortunate that that overload of GetDeclaredSymbol()'s return type can't be more strongly typed, but unfortunately with a ModifiedIdentifierSyntax there isn't a way to know if is from a local, field, etc.

Upvotes: 3

Related Questions