File: Semantics\WithBlockSemanticModelTests.vb
Web Access
Project: src\src\Compilers\VisualBasic\Test\Semantic\Microsoft.CodeAnalysis.VisualBasic.Semantic.UnitTests.vbproj (Microsoft.CodeAnalysis.VisualBasic.Semantic.UnitTests)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
 
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Imports Basic.Reference.Assemblies
 
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
 
    Public Class WithBlockSemanticModelTests
        Inherits FlowTestBase
 
#Region "Symbol / Type Info"
 
        <Fact>
        Public Sub WithAliasedStaticField()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
    <file name="a.vb">
Imports Alias1 = ClassWithField
Class ClassWithField
    Public Shared field1 As String = "a"
End Class
Module WithAliasedStaticField
    Sub Main()
        With Alias1.field1 'BIND:"Alias1.field1"
            Dim newString = .Replace("a", "b")
        End With
    End Sub
End Module
    </file>
</compilation>)
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim withExpression = DirectCast(tree.GetCompilationUnitRoot().DescendantNodes().Where(Function(n) n.Kind = SyntaxKind.SimpleMemberAccessExpression).First(), MemberAccessExpressionSyntax)
 
            Assert.Equal("Alias1", model.GetAliasInfo(DirectCast(withExpression.Expression, IdentifierNameSyntax)).ToDisplayString())
            Assert.False(model.GetConstantValue(withExpression).HasValue)
            Dim typeInfo = model.GetTypeInfo(withExpression)
            Assert.Equal("String", typeInfo.Type.ToDisplayString())
            Assert.Equal("String", typeInfo.ConvertedType.ToDisplayString())
            Dim conv = model.GetConversion(withExpression)
            Assert.Equal(ConversionKind.Identity, conv.Kind)
            Dim symbolInfo = model.GetSymbolInfo(withExpression)
            Assert.Equal("Public Shared field1 As String", symbolInfo.Symbol.ToDisplayString())
            Assert.Equal(SymbolKind.Field, symbolInfo.Symbol.Kind)
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length)
            Assert.Equal(0, model.GetMemberGroup(withExpression).Length)
        End Sub
 
        <Fact>
        Public Sub WithDeclaresAnonymousLocalSymbolAndTypeInfo()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
    <file name="a.vb">
Module WithDeclaresAnonymousLocalSymbolAndTypeInfo
    Sub Main()
        With New With {.A = 1, .B = "2"} 'BIND:"New With {.A = 1, .B = "2"}"
            .A = .B
        End With
    End Sub
End Module
    </file>
</compilation>)
            Dim semanticInfo = CompilationUtils.GetSemanticInfoSummary(Of AnonymousObjectCreationExpressionSyntax)(compilation, "a.vb")
 
            Assert.Null(semanticInfo.Alias)
            Assert.False(semanticInfo.ConstantValue.HasValue)
            Assert.Equal("<anonymous type: A As Integer, B As String>", semanticInfo.Type.ToDisplayString())
            Assert.Equal("<anonymous type: A As Integer, B As String>", semanticInfo.ConvertedType.ToDisplayString())
            Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind)
            Assert.Equal("Public Sub New(A As Integer, B As String)", semanticInfo.Symbol.ToDisplayString()) ' should get constructor for anonymous type
            Assert.Equal(SymbolKind.Method, semanticInfo.Symbol.Kind)
            Assert.Equal(0, semanticInfo.CandidateSymbols.Length)
            Assert.Equal(0, semanticInfo.MemberGroup.Length)
        End Sub
 
        <Fact(), WorkItem(544083, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544083")>
        Public Sub WithSpeculativeSymbolInfo()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
    <file name="a.vb">
Class C1
    Property Property1 As Integer
    Property Property2 As String
End Class
Module Module1
    Sub Main()
        Dim x As New C1()
        With x
            Dim f = Function() .Property1 'BINDHERE
        End With
    End Sub    
End Module
    </file>
</compilation>)
            Dim semanticModel = GetSemanticModel(compilation, "a.vb")
            Dim position = compilation.SyntaxTrees.Single().ToString().IndexOf("'BINDHERE", StringComparison.Ordinal)
 
            Dim expr = SyntaxFactory.ParseExpression(".property2")
            Dim speculativeTypeInfo = semanticModel.GetSpeculativeTypeInfo(position, expr, SpeculativeBindingOption.BindAsExpression)
            Assert.Equal("String", speculativeTypeInfo.ConvertedType.ToDisplayString())
            Dim conv = semanticModel.GetSpeculativeConversion(position, expr, SpeculativeBindingOption.BindAsExpression)
            Assert.Equal(ConversionKind.Identity, conv.Kind)
            Assert.Equal("String", speculativeTypeInfo.Type.ToDisplayString())
 
            Dim speculativeSymbolInfo = semanticModel.GetSpeculativeSymbolInfo(position, SyntaxFactory.ParseExpression(".property2"), SpeculativeBindingOption.BindAsExpression)
            Assert.Equal("Public Property Property2 As String", speculativeSymbolInfo.Symbol.ToDisplayString())
            Assert.Equal(SymbolKind.Property, speculativeSymbolInfo.Symbol.Kind)
        End Sub
 
#End Region
 
#Region "FlowAnalysis"
 
        <Fact>
        Public Sub UseWithVariableInNestedLambda()
            Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation>
    <file name="a.vb">
Class C1
    Property Property1 As Integer
End Class
Module Module1
    Sub Main()
        Dim x As New C1()
        With x
            Dim f = Function()
                        [|Return .Property1|]
                    End Function
        End With
    End Sub    
End Module
    </file>
</compilation>)
            Dim controlFlowResults = analysis.Item1
            Dim dataFlowResults = analysis.Item2
 
            Assert.Empty(dataFlowResults.VariablesDeclared)
            Assert.Empty(dataFlowResults.AlwaysAssigned)
            Assert.Empty(dataFlowResults.DataFlowsIn)
            Assert.Empty(dataFlowResults.DataFlowsOut)
            Assert.Empty(dataFlowResults.ReadInside)
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowResults.ReadOutside))
            Assert.Empty(dataFlowResults.WrittenInside)
            Assert.Equal("x, f", GetSymbolNamesJoined(dataFlowResults.WrittenOutside))
 
            Assert.Empty(controlFlowResults.EntryPoints)
            Assert.False(controlFlowResults.EndPointIsReachable)
            Assert.True(controlFlowResults.StartPointIsReachable)
            Assert.Equal(1, controlFlowResults.ExitPoints.Count)
        End Sub
 
        <Fact>
        Public Sub WithDeclaresAnonymousLocalDataFlow()
            Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation>
    <file name="a.vb">
Module WithDeclaresAnonymousLocal
    Sub Main()
        With New With {.A = 1, .B = "2"}
            [|.A = .B|]
        End With
    End Sub
End Module
    </file>
</compilation>)
            Dim controlFlowResults = analysis.Item1
            Dim dataFlowResults = analysis.Item2
 
            Assert.Empty(dataFlowResults.VariablesDeclared)
            Assert.Empty(dataFlowResults.AlwaysAssigned)
            Assert.Empty(dataFlowResults.DataFlowsIn) ' assume anonymous locals don't show
            Assert.Empty(dataFlowResults.DataFlowsOut)
            Assert.Empty(dataFlowResults.ReadInside) ' assume anonymous locals don't show
            Assert.Empty(dataFlowResults.ReadOutside)
            Assert.Empty(dataFlowResults.WrittenInside)
            Assert.Empty(dataFlowResults.WrittenOutside) ' assume anonymous locals don't show
 
            Assert.Empty(controlFlowResults.ExitPoints)
            Assert.Empty(controlFlowResults.EntryPoints)
            Assert.True(controlFlowResults.EndPointIsReachable)
            Assert.True(controlFlowResults.StartPointIsReachable)
        End Sub
 
        <Fact>
        Public Sub EmptyWith()
            Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation>
    <file name="a.vb">
Module Module1
    Sub Main()
        Dim x As Object()
        [|With x
        End With|]
    End Sub    
End Module
    </file>
</compilation>)
            Dim controlFlowResults = analysis.Item1
            Dim dataFlowResults = analysis.Item2
 
            Assert.Empty(dataFlowResults.VariablesDeclared)
            Assert.Empty(dataFlowResults.AlwaysAssigned)
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowResults.DataFlowsIn))
            Assert.Empty(dataFlowResults.DataFlowsOut)
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowResults.ReadInside))
            Assert.Empty(dataFlowResults.ReadOutside)
            Assert.Empty(dataFlowResults.WrittenInside)
            Assert.Empty(dataFlowResults.WrittenOutside)
 
            Assert.Empty(controlFlowResults.ExitPoints)
            Assert.Empty(controlFlowResults.EntryPoints)
            Assert.True(controlFlowResults.EndPointIsReachable)
            Assert.True(controlFlowResults.StartPointIsReachable)
        End Sub
 
#End Region
 
        <Fact, WorkItem(2662, "https://github.com/dotnet/roslyn/issues/2662")>
        Public Sub Issue2662()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntimeAndReferences(
<compilation>
    <file name="a.vb"><![CDATA[
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.CompilerServices

Module Program
    Sub Main(args As String())

    End Sub
    Private Sub AddCustomer()
        Dim theCustomer As New Customer

        With theCustomer
            .Name = "Abc"
            .URL = "http://www.microsoft.com/"
            .City = "Redmond"
            .Print(.Name)
        End With
    End Sub

    <Extension()>
    Public Sub Print(ByVal cust As Customer, str As String)
        Console.WriteLine(str)
    End Sub

    Public Class Customer
        Public Property Name As String
        Public Property City As String
        Public Property URL As String

        Public Property Comments As New List(Of String)
    End Class
End Module
    ]]></file>
</compilation>, {Net40.References.SystemCore})
 
            compilation.AssertNoDiagnostics()
 
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim withBlock = tree.GetCompilationUnitRoot().DescendantNodes().OfType(Of WithBlockSyntax)().Single()
 
            Dim name = withBlock.Statements(3).DescendantNodes().OfType(Of IdentifierNameSyntax).Where(Function(i) i.Identifier.ValueText = "Name").Single()
            model.GetAliasInfo(name)
 
            Dim result2 = model.AnalyzeDataFlow(withBlock, withBlock)
            Assert.True(result2.Succeeded)
 
            model = compilation.GetSemanticModel(tree)
            model.GetAliasInfo(name)
 
            Assert.Equal("theCustomer As Program.Customer", model.GetSymbolInfo(withBlock.WithStatement.Expression).Symbol.ToTestDisplayString())
        End Sub
 
        <Fact>
        <WorkItem(187910, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=187910&_a=edit")>
        Public Sub Bug187910()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
    <file name="a.vb">
Class ClassWithField
    Public field1 As String = "a"
End Class
Class WithAliasedStaticField
    Sub Test(parameter as ClassWithField)
        With parameter
            System.Console.WriteLine(.field1)
        End With
    End Sub
End Class
    </file>
</compilation>)
 
            Dim compilationB = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
    <file name="b.vb">
Class WithAliasedStaticField1
    Sub Test(parameter as ClassWithField)
        With parameter
            System.Console.WriteLine(.field1)
        End With
    End Sub
End Class
    </file>
</compilation>)
 
            compilation.AssertTheseDiagnostics()
 
            Dim treeA = compilation.SyntaxTrees.Single()
            Dim modelA = compilation.GetSemanticModel(treeA)
            Dim parameter = treeA.GetCompilationUnitRoot().DescendantNodes().OfType(Of IdentifierNameSyntax)().Where(Function(n) n.Identifier.ValueText = "parameter").First()
 
            Assert.Equal("Sub WithAliasedStaticField.Test(parameter As ClassWithField)", modelA.GetEnclosingSymbol(parameter.SpanStart).ToTestDisplayString())
 
            Dim treeB = compilationB.SyntaxTrees.Single()
            Dim withBlockB = treeB.GetCompilationUnitRoot().DescendantNodes().OfType(Of WithBlockSyntax)().Single()
 
            Dim modelAB As SemanticModel = Nothing
            Assert.True(modelA.TryGetSpeculativeSemanticModel(parameter.Parent.Parent.SpanStart, withBlockB, modelAB))
 
            Assert.Equal("Sub WithAliasedStaticField.Test(parameter As ClassWithField)", modelAB.GetEnclosingSymbol(withBlockB.WithStatement.Expression.SpanStart).ToTestDisplayString())
        End Sub
 
        <Fact>
        <WorkItem(10929, "https://github.com/dotnet/roslyn/issues/10929")>
        Public Sub WithTargetAsArgument_01()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
    <file name="a.vb">
Class Base
End Class
 
Class Derived
    Inherits Base
 
    Public Function Contains(node As Base) As Boolean
        Return True
    End Function
End Class
 
Module Ext
    Sub M(vbNode As Derived)
        With vbNode
            If .Contains(vbNode) Then
            End If
        End With
    End Sub
End Module
    </file>
</compilation>)
 
            compilation.AssertTheseDiagnostics()
 
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes().OfType(Of IdentifierNameSyntax)().Where(Function(n) n.Identifier.ValueText = "vbNode").ToArray()
 
            Dim symbolInfo1 = model.GetSymbolInfo(nodes(0))
            Assert.Equal("vbNode As Derived", symbolInfo1.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo1.Symbol.Kind)
 
            Dim symbolInfo2 = model.GetSymbolInfo(nodes(1))
            Assert.Equal("vbNode As Derived", symbolInfo2.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo2.Symbol.Kind)
 
            Assert.Same(symbolInfo1.Symbol, symbolInfo2.Symbol)
        End Sub
 
        <Fact>
        <WorkItem(10929, "https://github.com/dotnet/roslyn/issues/10929")>
        Public Sub WithTargetAsArgument_02()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
    <file name="a.vb"><![CDATA[
Class Base
End Class

Class Derived
    Inherits Base
End Class

Module Ext
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetCurrent(Of TNode As Base)(root As Base, node As TNode) As TNode
        Return Nothing
    End Function

    Sub M(vbNode As Derived)
        With vbNode
            If .GetCurrent(vbNode) Is Nothing Then
            End If
        End With
    End Sub
End Module
    ]]></file>
</compilation>, additionalRefs:={Net40.References.SystemCore})
 
            compilation.AssertTheseDiagnostics()
 
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes().OfType(Of IdentifierNameSyntax)().Where(Function(n) n.Identifier.ValueText = "vbNode").ToArray()
 
            Dim symbolInfo1 = model.GetSymbolInfo(nodes(0))
            Assert.Equal("vbNode As Derived", symbolInfo1.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo1.Symbol.Kind)
 
            Dim symbolInfo2 = model.GetSymbolInfo(nodes(1))
            Assert.Equal("vbNode As Derived", symbolInfo2.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo2.Symbol.Kind)
 
            Assert.Same(symbolInfo1.Symbol, symbolInfo2.Symbol)
        End Sub
 
        <Fact>
        <WorkItem(10929, "https://github.com/dotnet/roslyn/issues/10929")>
        Public Sub WithTargetAsArgument_03()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
    <file name="a.vb"><![CDATA[
Class Base
End Class

Class Derived
    Inherits Base

    Public Function Contains(node As Base) As Boolean
        Return True
    End Function
End Class

Module Ext
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetCurrent(Of TNode As Base)(root As Base, node As TNode) As TNode
        Return Nothing
    End Function

    Sub M(vbNode As Derived)
        With vbNode
            If .GetCurrent(vbNode) Is Nothing Then
            End If
            If .Contains(vbNode) Then
            End If
        End With
    End Sub
End Module
    ]]></file>
</compilation>, additionalRefs:={Net40.References.SystemCore})
 
            compilation.AssertTheseDiagnostics()
 
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes().OfType(Of IdentifierNameSyntax)().Where(Function(n) n.Identifier.ValueText = "vbNode").ToArray()
 
            Dim symbolInfo1 = model.GetSymbolInfo(nodes(0))
            Assert.Equal("vbNode As Derived", symbolInfo1.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo1.Symbol.Kind)
 
            Dim symbolInfo2 = model.GetSymbolInfo(nodes(1))
            Assert.Equal("vbNode As Derived", symbolInfo2.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo2.Symbol.Kind)
 
            Dim symbolInfo3 = model.GetSymbolInfo(nodes(2))
            Assert.Equal("vbNode As Derived", symbolInfo3.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Parameter, symbolInfo3.Symbol.Kind)
 
            Assert.Same(symbolInfo1.Symbol, symbolInfo2.Symbol)
            Assert.Same(symbolInfo1.Symbol, symbolInfo3.Symbol)
        End Sub
 
        <Fact>
        <WorkItem(10929, "https://github.com/dotnet/roslyn/issues/10929")>
        Public Sub WithTargetAsArgument_04()
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
    <file name="a.vb"><![CDATA[
Class Base
End Class

Class Derived
    Inherits Base
End Class

Module Ext
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetCurrent(Of TNode As Base)(root As Base, node As TNode) As TNode
        Return Nothing
    End Function

    readonly property vbNode As Derived
        Get
            return nothing
        End Get
    End Property

    Sub M()
        With vbNode
            If .GetCurrent(vbNode) Is Nothing Then
            End If
        End With
    End Sub
End Module
    ]]></file>
</compilation>, additionalRefs:={Net40.References.SystemCore})
 
            compilation.AssertTheseDiagnostics()
 
            Dim tree = compilation.SyntaxTrees.Single()
            Dim model = compilation.GetSemanticModel(tree)
            Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes().OfType(Of IdentifierNameSyntax)().Where(Function(n) n.Identifier.ValueText = "vbNode").ToArray()
 
            Dim symbolInfo1 = model.GetSymbolInfo(nodes(0))
            Assert.Equal("ReadOnly Property Ext.vbNode As Derived", symbolInfo1.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Property, symbolInfo1.Symbol.Kind)
 
            Dim symbolInfo2 = model.GetSymbolInfo(nodes(1))
            Assert.Equal("ReadOnly Property Ext.vbNode As Derived", symbolInfo2.Symbol.ToTestDisplayString())
            Assert.Equal(SymbolKind.Property, symbolInfo2.Symbol.Kind)
 
            Assert.Same(symbolInfo1.Symbol, symbolInfo2.Symbol)
        End Sub
 
    End Class
 
End Namespace