使用 Roslyn 获取 VB 中推断变量的 TypeSymbol

Get the TypeSymbol for ain inferred variable in VB with Roslyn

在 VB 中使用 Roslyn,我试图访问 ITypeSymbol 以获取使用类型推断声明的变量,但正在努力 return 正确的节点。我希望 ITypeSymbol 能够识别变量是否是引用类型。相比之下,这在 C# 中相对容易。在这种情况下,我们可以简单地使用 node.Declaration.Type,但这在 VB 声明符中不可用。

在下面的示例中,我能够从 AsClause 访问 b 声明的 TypeSymbol,但对于 a 中使用的推断类型,它是 null变量:

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

你可以从上面的localSym得到本地的类型:

DirectCast(localSym, ILocalSymbol).Type

不幸的是 GetDeclaredSymbol() 的 return 类型的重载不能更强类型化,但不幸的是 ModifiedIdentifierSyntax 没有办法知道是否来自本地、外地等