File: SymbolsTests\WithStatementSymbolsTests.vb
Web Access
Project: src\src\Compilers\VisualBasic\Test\Symbol\Microsoft.CodeAnalysis.VisualBasic.Symbol.UnitTests.vbproj (Microsoft.CodeAnalysis.VisualBasic.Symbol.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 System.Runtime.CompilerServices
Imports System.Xml.Linq
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
 
Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols
Imports Roslyn.Test.Utilities
 
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.ExtensionMethods
 
    Public Class WithStatementSymbolsTests
        Inherits BasicTestBase
 
        <Fact()>
        Public Sub LocalInEmptyWithStatementExpression()
            Dim compilationDef =
    <compilation name="LocalInEmptyWithStatementExpression">
        <file name="a.vb">
Module WithTestScoping
    Sub Main()
        Dim o1 As New Object()
        With [#0 o1 0#]
        End With
    End Sub
End Module
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes)
            Assert.Equal(1, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("o1 As System.Object", info0.Symbol.ToTestDisplayString())
        End Sub
 
        <Fact()>
        Public Sub NestedWithWithLambdasAndObjectInitializers()
            Dim compilationDef =
    <compilation name="LocalInEmptyWithStatementExpression">
        <file name="a.vb">
Imports System
 
Structure SS1
    Public A As String
    Public B As String
End Structure
 
Structure SS2
    Public X As SS1
    Public Y As SS1
End Structure
 
Structure Clazz
    Shared Sub Main(args() As String)
        Dim t As New Clazz(1)
    End Sub
    Sub New(i As Integer)
        Dim outer As New SS2
        With outer
            Dim a As New [#0 SS2 0#]() With {.X = Function() As SS1
                                                 With .Y
                                                     a.Y.B = a.Y.A
                                                     a.Y.A = "1"
                                                 End With
                                                 Return .Y
                                             End Function.Invoke()}
        End With
    End Sub
End Structure
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes)
            Assert.Equal(1, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("SS2", info0.Symbol.ToTestDisplayString())
        End Sub
 
        <Fact()>
        Public Sub LocalInEmptyWithStatementExpression_Struct()
            Dim compilationDef =
    <compilation name="LocalInEmptyWithStatementExpression_Struct">
        <file name="a.vb">
Structure STR
    Public F As String
End Structure
 
Module WithTestScoping
    Sub Main()
        Dim o1 As New STR()
        With [#0 o1 0#]
        End With
    End Sub
End Module
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes)
            Assert.Equal(1, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("o1 As STR", info0.Symbol.ToTestDisplayString())
        End Sub
 
        <Fact()>
        Public Sub LocalInWithStatementExpression()
            Dim compilationDef =
    <compilation name="LocalInWithStatementExpression">
        <file name="a.vb">
Module WithTestScoping
    Sub Main()
        Dim o1 As New Object()
        With [#0 o1 0#]
            Dim o1 = Nothing
            With [#1 o1 1#]
                Dim o2 = Nothing
            End With
            With [#2 New Object() 2#]
                Dim o1 As New Object()
                Dim o2 = Nothing
            End With
        End With
    End Sub
End Module
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes,
<errors>
BC30616: Variable 'o1' hides a variable in an enclosing block.
            Dim o1 = Nothing
                ~~
BC30616: Variable 'o1' hides a variable in an enclosing block.
                Dim o1 As New Object()
                    ~~
</errors>)
            Assert.Equal(3, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("o1 As System.Object", info0.Symbol.ToTestDisplayString())
 
            Dim info1 = model.GetSemanticInfoSummary(DirectCast(nodes(1), ExpressionSyntax))
            Assert.NotNull(info1.Symbol)
            Assert.Equal("o1 As System.Object", info1.Symbol.ToTestDisplayString())
            Assert.NotSame(info0.Symbol, info1.Symbol)
 
            Dim info2 = model.GetSemanticInfoSummary(DirectCast(nodes(2), ExpressionSyntax))
            Assert.NotNull(info2.Symbol)
            Assert.Equal("Sub System.Object..ctor()", info2.Symbol.ToTestDisplayString())
        End Sub
 
        <Fact()>
        Public Sub NestedWithStatements()
            Dim compilationDef =
    <compilation name="NestedWithStatements">
        <file name="a.vb">
Structure Clazz
    Structure SS
        Public FLD As String
    End Structure
 
    Public FLD As SS
 
    Sub TEST()
        With Me
            With [#0 .FLD 0#]
                Dim v As String = .GetType() .ToString()
            End With
        End With
    End Sub
End Structure
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes)
            Assert.Equal(1, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("Clazz.FLD As Clazz.SS", info0.Symbol.ToTestDisplayString())
 
            Dim systemObject = compilation.GetTypeByMetadataName("System.Object")
            Dim conv = model.ClassifyConversion(DirectCast(nodes(0), ExpressionSyntax), systemObject)
            Assert.True(conv.IsWidening)
 
        End Sub
 
        <Fact()>
        Public Sub LocalInWithStatementExpression3()
            Dim compilationDef =
    <compilation name="LocalInWithStatementExpression3">
        <file name="a.vb">
Structure Clazz
    Structure SSS
        Public FLD As String
    End Structure
 
    Structure SS
        Public FS As SSS
    End Structure
 
    Public FLD As SS
 
    Sub TEST()
        With Me
            With .FLD
                With .FS 
                    Dim v = [#0 .FLD 0#]
                End With
            End With
        End With
    End Sub
End Structure
        </file>
    </compilation>
 
            Dim tree As SyntaxTree = Nothing
            Dim nodes As New List(Of SyntaxNode)
            Dim compilation = Compile(compilationDef, tree, nodes)
            Assert.Equal(1, nodes.Count)
 
            Dim model = compilation.GetSemanticModel(tree)
 
            Dim info0 = model.GetSemanticInfoSummary(DirectCast(nodes(0), ExpressionSyntax))
            Assert.NotNull(info0.Symbol)
            Assert.Equal("Clazz.SSS.FLD As System.String", info0.Symbol.ToTestDisplayString())
 
            Dim systemObject = compilation.GetTypeByMetadataName("System.Object")
            Dim conv = model.ClassifyConversion(DirectCast(nodes(0), ExpressionSyntax), systemObject)
            Assert.True(conv.IsWidening)
 
        End Sub
 
#Region "Utils"
 
        Private Function Compile(text As XElement, ByRef tree As SyntaxTree, nodes As List(Of SyntaxNode), Optional errors As XElement = Nothing) As VisualBasicCompilation
            Dim spans As New List(Of TextSpan)
            ExtractTextIntervals(text, spans)
 
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndReferences(text, {SystemRef, SystemCoreRef, MsvbRef})
            If errors Is Nothing Then
                CompilationUtils.AssertNoErrors(compilation)
            Else
                CompilationUtils.AssertTheseDiagnostics(compilation, errors)
            End If
 
            tree = compilation.SyntaxTrees(0)
            For Each span In spans
 
                Dim stack As New Stack(Of SyntaxNode)
                stack.Push(tree.GetRoot())
 
                While stack.Count > 0
                    Dim node = stack.Pop()
 
                    If span.Contains(node.Span) Then
                        nodes.Add(node)
                        Exit While
                    End If
 
                    For Each child In node.ChildNodes
                        stack.Push(child)
                    Next
                End While
            Next
 
            Return compilation
        End Function
 
        Private Shared Sub ExtractTextIntervals(text As XElement, nodes As List(Of TextSpan))
            text.<file>.Value = text.<file>.Value.Trim().Replace(vbLf, vbCrLf)
 
            Dim index As Integer = 0
            Do
                Dim startMarker = "[#" & index
                Dim endMarker = index & "#]"
 
                ' opening '[#{0-9}'
                Dim start = text.<file>.Value.IndexOf(startMarker, StringComparison.Ordinal)
                If start < 0 Then
                    Exit Do
                End If
 
                ' closing '{0-9}#]'
                Dim [end] = text.<file>.Value.IndexOf(endMarker, StringComparison.Ordinal)
                Assert.InRange([end], 0, Int32.MaxValue)
 
                nodes.Add(New TextSpan(start, [end] - start + 3))
 
                text.<file>.Value = text.<file>.Value.Replace(startMarker, "   ").Replace(endMarker, "   ")
 
                index += 1
                Assert.InRange(index, 0, 9)
            Loop
        End Sub
 
        Private Shared Function GetNamedTypeSymbol(c As VisualBasicCompilation, namedTypeName As String, Optional fromCorLib As Boolean = False) As NamedTypeSymbol
            Dim nameParts = namedTypeName.Split("."c)
 
            Dim srcAssembly = DirectCast(c.Assembly, SourceAssemblySymbol)
            Dim nsSymbol As NamespaceSymbol = (If(fromCorLib, srcAssembly.CorLibrary, srcAssembly)).GlobalNamespace
            For Each ns In nameParts.Take(nameParts.Length - 1)
                nsSymbol = DirectCast(nsSymbol.GetMember(ns), NamespaceSymbol)
            Next
            Return DirectCast(nsSymbol.GetTypeMember(nameParts(nameParts.Length - 1)), NamedTypeSymbol)
        End Function
 
#End Region
 
    End Class
 
End Namespace