dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.92k stars 4.02k forks source link

VisualBasicCompilation.GetTypeInfo returns `null` for `ObjectCreationExpressionSyntax.Type` #75147

Open TymurGubayev opened 2 days ago

TymurGubayev commented 2 days ago

Version Used: 4.12.0-1.final

Steps to Reproduce:

Get a VB.NET compilation of following code:

Class C
    Sub S()
        Dim o As C = New C()
    End Sub
End Class

Then use GetTypeInfo to get the ITypeSymbol of the ObjectCreationExpressionSyntax.

Here is an example of how to do this:

Create new Standalone Roslyn Analyzer project, add following usings:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.VisualBasic;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;

Replace the Main method with following code:

static async Task Main(string[] args)
{
    var refApis = AppDomain.CurrentDomain.GetAssemblies()
    .Where(a => !a.IsDynamic)
    .Select(a => MetadataReference.CreateFromFile(a.Location));

    var tree = SyntaxFactory.ParseSyntaxTree("""
Class C
    Sub S()
        Dim o As C = New C()
    End Sub
End Class
""");
    var compilation = VisualBasicCompilation.Create("something", [tree], refApis);
    var semantic = compilation.GetSemanticModel(tree);

    var root = (CompilationUnitSyntax)await tree.GetRootAsync();
    var C = (ClassBlockSyntax)root.Members.First();
    var S = (MethodBlockSyntax)C.Members.First();
    var decla = (LocalDeclarationStatementSyntax)S.Statements[0];
    var decl = decla.Declarators[0];
    var asClause = decl.AsClause;
    var objectCreation = (ObjectCreationExpressionSyntax)decl.Initializer.Value;

    var t1 = semantic.GetTypeInfo(asClause.Type()).Type;
    var t2 = semantic.GetTypeInfo(objectCreation.Type).Type;
    var t3 = semantic.GetSpeculativeTypeInfo(objectCreation.Type.SpanStart, objectCreation.Type, SpeculativeBindingOption.BindAsTypeOrNamespace).Type;

    Debug.Assert(t2 is not null); // fails
    Debug.Assert(t1 == t2); // fails
    Debug.Assert(t1 == t3);
}

Expected Behavior: All three methods type symbols are not null and identical.

Actual Behavior: GetTypeInfo returns null for objectCreation.Type, while GetSpeculativeTypeInfo returns correct type symbol for the same.

TymurGubayev commented 2 days ago

this might be somehow related to https://github.com/dotnet/roslyn/issues/74499