File: SymbolsTests\AnonymousTypes\AnonymousTypesEmittedSymbolsTests.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.IO
Imports System.Runtime.CompilerServices
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 AnonymousTypesEmittedSymbolsTests : Inherits BasicTestBase
 
        <Fact>
        Public Sub EmitAnonymousTypeTemplate_NoNeededSymbols()
            Dim compilationDef =
    <compilation name="EmitAnonymousTypeTemplate_NoNeededSymbols">
        <file name="a.vb">
Class ModuleB
    Private v1 = New With { .aa = 1 }
End Class
        </file>
    </compilation>
 
            Dim compilation = CompilationUtils.CreateEmptyCompilationWithReferences(source:=compilationDef, references:={})
            CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC30002: Type 'System.Void' is not defined.
Class ModuleB
~~~~~~~~~~~~~~
BC31091: Import of type 'Object' from assembly or module 'EmitAnonymousTypeTemplate_NoNeededSymbols.dll' failed.
Class ModuleB
      ~~~~~~~
BC30002: Type 'System.Object' is not defined.
    Private v1 = New With { .aa = 1 }
            ~~
BC30002: Type 'System.Object' is not defined.
    Private v1 = New With { .aa = 1 }
                     ~~~~~~~~~~~~~~~~
BC30002: Type 'System.Int32' is not defined.
    Private v1 = New With { .aa = 1 }
                                  ~
</errors>)
        End Sub
 
        <Fact>
        Public Sub EmitAnonymousTypeTemplateGenericTest()
            Dim compilationDef =
    <compilation name="EmitGenericAnonymousTypeTemplate">
        <file name="a.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object"), type.BaseType)
                                                  Assert.True(type.IsGenericType)
                                                  Assert.Equal(3, type.TypeParameters.Length)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub EmitAnonymousTypeUnification01()
            Dim compilationDef =
    <compilation name="EmitAnonymousTypeUnification01">
        <file name="a.vb">
Module ModuleB
    Sub Test1(x As Integer)
        Dim at1 As Object = New With { .aa = 1, .b1 = "", .Int = x + x, .Object=Nothing }
        Dim at2 As Object = New With { .aA = "X"c, .B1 = 0.123# * x, .int = new Object(), .objecT = Nothing }
        at1 = at2
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim types = m.ContainingAssembly.GlobalNamespace.GetTypeMembers()
                                                  Dim list = types.Where(Function(t) t.Name.StartsWith("VB$AnonymousType_", StringComparison.Ordinal)).ToList()
                                                  Assert.Equal(1, list.Count())
                                                  Dim type = list.First()
                                                  Assert.Equal("VB$AnonymousType_0", type.Name)
                                                  Assert.Equal(4, type.Arity)
                                                  Dim mems = type.GetMembers()
                                                  ' 4 fields, 4 get, 4 set, 1 ctor, 1 ToString
                                                  Assert.Equal(14, mems.Length)
                                                  Dim mlist = mems.Where(Function(mt) mt.Name = "GetHashCode" OrElse mt.Name = "Equals").Select(Function(mt) mt)
                                                  Assert.Equal(0, mlist.Count)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub EmitAnonymousTypeUnification02()
            Dim compilationDef =
    <compilation name="EmitAnonymousTypeUnification02">
        <file name="b.vb">
Imports System
Imports System.Collections.Generic
 
Class A
    Sub Test(p As List(Of String))
        Dim local = New Char() {"a"c, "b"c}
        Dim at1 As Object = New With {.test = p, Key .key = local, Key .k2 = "QC" + p(0)}
    End Sub
End Class
        </file>
        <file name="a.vb">
Structure S
    Function Test(p As Char()) As Object
        Dim at2 As Object = New With {.TEST = New System.Collections.Generic.List(Of String)(), Key .Key = p, Key .K2 = ""}
        Return at2
    End Function
End Structure
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim types = m.ContainingAssembly.GlobalNamespace.GetTypeMembers()
                                                  Dim list = types.Where(Function(t) t.Name.StartsWith("VB$AnonymousType", StringComparison.Ordinal)).ToList()
                                                  Assert.Equal(1, list.Count())
                                                  Dim type = list.First()
                                                  Assert.Equal("VB$AnonymousType_0", type.Name)
                                                  Assert.Equal(3, type.Arity)
                                                  Dim mems = type.GetMembers()
                                                  ' 3 fields, 3 get, 1 set, 1 ctor, 1 ToString, 1 GetHashCode, 2 Equals
                                                  Assert.Equal(12, mems.Length)
                                                  Dim mlist = mems.Where(Function(mt) mt.Name = "GetHashCode" OrElse mt.Name = "Equals").Select(Function(mt) mt)
                                                  Assert.Equal(3, mlist.Count)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub EmitAnonymousTypeUnification03()
            Dim compilationDef =
    <compilation name="EmitAnonymousTypeUnification03">
        <file name="b.vb">
Imports System
Imports System.Collections.Generic
 
Class A
    Sub Test(p As List(Of String))
        Dim local = New Char() {"a"c, "b"c}
        Dim at1 As Object = New With {.test = p, Key .key = local, Key .k2 = "QC" + p(0)}
    End Sub
End Class
        </file>
        <file name="a.vb">
Imports System
Imports System.Collections.Generic
 
Class B
    Sub Test(p As List(Of String))
        Dim local = New Char() {"a"c, "b"c}
        Dim at1 As Object = New With {.test = p, Key .key = local, .k2 = "QC" + p(0)}
    End Sub
End Class
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim types = m.ContainingAssembly.GlobalNamespace.GetTypeMembers()
                                                  Dim list = types.Where(Function(t) t.Name.StartsWith("VB$AnonymousType", StringComparison.Ordinal)).ToList()
                                                  ' no unification - diff in key
                                                  Assert.Equal(2, list.Count())
                                                  Dim type = m.ContainingAssembly.GlobalNamespace.GetTypeMembers("VB$AnonymousType_1").Single()
 
                                                  Assert.Equal("VB$AnonymousType_1", type.Name)
                                                  Assert.Equal(3, type.Arity)
                                                  Dim mems = type.GetMembers()
                                                  ' Second: 3 fields, 3 get, 2 set, 1 ctor, 1 ToString, 1 GetHashCode, 2 Equals
                                                  Assert.Equal(13, mems.Length)
                                                  Dim mlist = mems.Where(Function(mt) mt.Name = "GetHashCode" OrElse mt.Name = "Equals").Select(Function(mt) mt)
                                                  Assert.Equal(3, mlist.Count)
                                                  '
                                                  type = m.ContainingAssembly.GlobalNamespace.GetTypeMembers("VB$AnonymousType_0").Single()
                                                  Assert.Equal("VB$AnonymousType_0", type.Name)
                                                  Assert.Equal(3, type.Arity)
                                                  mems = type.GetMembers()
                                                  ' First: 3 fields, 3 get, 1 set, 1 ctor, 1 ToString, 1 GetHashCode, 2 Equals
                                                  Assert.Equal(12, mems.Length)
                                                  mlist = mems.Where(Function(mt) mt.Name = "GetHashCode" OrElse mt.Name = "Equals").Select(Function(mt) mt)
                                                  Assert.Equal(3, mlist.Count)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub EmitAnonymousTypeCustomModifiers()
            Dim compilationDef =
    <compilation name="EmitAnonymousTypeCustomModifiers">
        <file name="b.vb">
Imports System
Imports System.Collections.Generic
 
Class A
    Sub Test(p As List(Of String))
        Dim intArrMod = Modifiers.F9()
        Dim at1 = New With { Key .f = intArrMod}
        Dim at2 = New With { Key .f = New Integer() {}}
        at1 = at2
        at2 = at1
    End Sub
End Class
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef, TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll})
        End Sub
 
        <Fact>
        Public Sub AnonymousTypes_MultiplyEmitOfTheSameAssembly()
            Dim compilationDef =
    <compilation name="AnonymousTypes_MultiplyEmitOfTheSameAssembly">
        <file name="b.vb">
Module ModuleB
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1 }
        Dim v2 As Object = New With { Key .AA = "a" }
    End Sub
End Module
        </file>
        <file name="a.vb">
Module ModuleA
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .Aa = 1 }
        Dim v2 As Object = New With { Key .aA = "A" }
    End Sub
End Module
        </file>
        <file name="c.vb">
Module ModuleC
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .AA = 1 }
        Dim v2 As Object = New With { Key .aa = "A" }
    End Sub
End Module
        </file>
    </compilation>
 
            Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef)
            Dim tree = compilation.SyntaxTrees(0)
            Dim model = compilation.GetSemanticModel(tree)
            Dim position = compilationDef.<file>.Value.IndexOf("Dim v2", StringComparison.Ordinal) - 1
 
            ' The sole purpose of this is to check if there will be any asserts 
            ' or exceptions related to adjusted names/locations of anonymous types 
            ' symbols when Emit is called several times for the same compilation
            For i = 0 To 10
                Using stream As New MemoryStream()
                    compilation.Emit(stream)
                End Using
 
                ' do some speculative semantic query
                Dim expr1 = SyntaxFactory.ParseExpression(<text>New With { .aa = 1, .BB<%= i %> = "" }</text>.Value)
                Dim info1 = model.GetSpeculativeTypeInfo(position, expr1, SpeculativeBindingOption.BindAsExpression)
                Assert.NotNull(info1.Type)
            Next
        End Sub
 
        <Fact>
        Public Sub EmitCompilerGeneratedAttributeTest()
            Dim compilationDef =
    <compilation name="EmitCompilerGeneratedAttributeTest">
        <file name="a.vb">
Module Module1
    Sub Test1(x As Integer)
        Dim v As Object = New With { .a = 1 }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`1")
                                                  Assert.NotNull(type)
 
                                                  Dim attr = type.GetAttribute(
                                                      GetNamedTypeSymbol(m, "System.Runtime.CompilerServices.CompilerGeneratedAttribute"))
                                                  Assert.NotNull(attr)
                                              End Sub)
        End Sub
 
        <Fact>
        <WorkItem(48417, "https://github.com/dotnet/roslyn/issues/48417")>
        Public Sub CheckPropertyFieldAndAccessorsNamesTest()
            Dim compilationDef =
    <compilation name="CheckPropertyFieldAndAccessorsNamesTest">
        <file name="b.vb">
Module ModuleB
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aab = 1 }.aab
        Dim v2 As Object = New With { Key .AAB = "a" }.aab
    End Sub
End Module
        </file>
        <file name="a.vb">
Module ModuleA
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .Aab = 1 }.aab
        Dim v2 As Object = New With { Key .aAB = "A" }.aab
    End Sub
End Module
        </file>
        <file name="c.vb">
Module ModuleC
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .AAb = 1 }.aab
        Dim v2 As Object = New With { Key .aaB = "A" }.aab
    End Sub
End Module
        </file>
    </compilation>
 
            ' Cycle to hopefully get different order of files
            For i = 0 To 50
                CompileAndVerify(compilationDef,
                                 references:={SystemCoreRef},
                                 options:=TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All),
                                 symbolValidator:=Sub(m As ModuleSymbol)
                                                      Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`1")
                                                      Assert.NotNull(type)
                                                      CheckPropertyAccessorsAndField(m, type, "aab", type.TypeParameters(0), False)
 
                                                      type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_1`1")
                                                      Assert.NotNull(type)
                                                      CheckPropertyAccessorsAndField(m, type, "AAB", type.TypeParameters(0), True)
                                                  End Sub)
            Next
        End Sub
 
        <Fact>
        Public Sub CheckEmittedSymbol_ctor()
            Dim compilationDef =
    <compilation name="CheckEmittedSymbol_ctor">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Assert.Equal(1, type.InstanceConstructors.Length)
                                                  Dim constr = type.InstanceConstructors(0)
 
                                                  CheckMethod(m, constr, ".ctor", Accessibility.Public, isSub:=True, paramCount:=3)
 
                                                  Assert.Equal(type.TypeParameters(0), constr.Parameters(0).Type)
                                                  Assert.Equal("aa", constr.Parameters(0).Name)
 
                                                  Assert.Equal(type.TypeParameters(1), constr.Parameters(1).Type)
                                                  Assert.Equal("BB", constr.Parameters(1).Name)
 
                                                  Assert.Equal(type.TypeParameters(2), constr.Parameters(2).Type)
                                                  Assert.Equal("CCC", constr.Parameters(2).Name)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub CheckEmittedSymbol_ToString()
            Dim compilationDef =
    <compilation name="CheckEmittedSymbol_ToString">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Dim toStr = type.GetMember(Of MethodSymbol)("ToString")
 
                                                  CheckMethod(m, toStr, "ToString", Accessibility.Public,
                                                              retType:=GetNamedTypeSymbol(m, "System.String"),
                                                              isOverrides:=True, isOverloads:=True)
 
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object").GetMember("ToString"), toStr.OverriddenMethod)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub CheckNoExtraMethodsAreEmittedIfThereIsNoKeyFields()
            Dim compilationDef =
    <compilation name="CheckNoExtraMethodsAreEmittedIfThereIsNoKeyFields">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Assert.Equal(0, type.Interfaces.Length)
                                                  Assert.Equal(0, type.GetMembers("GetHashCode").Length)
                                                  Assert.Equal(0, type.GetMembers("Equals").Length)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub CheckEmittedSymbol_SystemObject_Equals()
            Dim compilationDef =
    <compilation name="CheckEmittedSymbol_SystemObject_Equals">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { Key .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Dim method = DirectCast(type.GetMembers("Equals").
                                                                                    Where(Function(s)
                                                                                              Return DirectCast(s, MethodSymbol).ExplicitInterfaceImplementations.Length = 0
                                                                                          End Function).Single(),
                                                                          MethodSymbol)
 
                                                  CheckMethod(m, method, "Equals", Accessibility.Public,
                                                              retType:=GetNamedTypeSymbol(m, "System.Boolean"),
                                                              isOverrides:=True, isOverloads:=True, paramCount:=1)
 
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object"), method.Parameters(0).Type)
 
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object").
                                                                    GetMembers("Equals").Where(Function(s) Not s.IsShared).Single(),
                                                               method.OverriddenMethod)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub CheckEmittedSymbol_GetHashCode()
            Dim compilationDef =
    <compilation name="CheckEmittedSymbol_GetHashCode">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { Key .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Dim method = type.GetMember(Of MethodSymbol)("GetHashCode")
 
                                                  CheckMethod(m, method, "GetHashCode", Accessibility.Public,
                                                              retType:=GetNamedTypeSymbol(m, "System.Int32"),
                                                              isOverrides:=True, isOverloads:=True)
 
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object").GetMember("GetHashCode"), method.OverriddenMethod)
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub CheckEmittedSymbol_IEquatableImplementation()
            Dim compilationDef =
    <compilation name="CheckEmittedSymbol_GetHashCode">
        <file name="b.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { Key .aa = 1, .BB = "", .CCC = new SSS() }
    End Sub
End Module
        </file>
    </compilation>
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             symbolValidator:=Sub(m As ModuleSymbol)
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
 
                                                  Assert.Equal(1, type.Interfaces.Length)
                                                  Dim [interface] = type.Interfaces(0)
 
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.IEquatable").Construct(type), [interface])
 
                                                  Dim method = DirectCast(type.GetMembers("Equals").
                                                                                    Where(Function(s)
                                                                                              Return DirectCast(s, MethodSymbol).ExplicitInterfaceImplementations.Length = 1
                                                                                          End Function).Single(),
                                                                          MethodSymbol)
 
                                                  CheckMethod(m, method, "Equals", Accessibility.Public,
                                                              retType:=GetNamedTypeSymbol(m, "System.Boolean"), paramCount:=1,
                                                              isOverloads:=True)
 
                                                  Assert.Equal(type, method.Parameters(0).Type)
                                                  Assert.Equal([interface].GetMember("Equals"), method.ExplicitInterfaceImplementations(0))
                                              End Sub)
        End Sub
 
        <Fact>
        Public Sub NotEmittingAnonymousTypeCreatedSolelyViaSemanticAPI()
            Dim compilationDef =
    <compilation name="NotEmittingAnonymousTypeCreatedSolelyViaSemanticAPI">
        <file name="a.vb">
Module ModuleB
    Structure SSS
    End Structure 
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1, .BB = "", .CCC = new SSS() } 
        'POSITION
    End Sub
End Module
        </file>
    </compilation>
 
            Dim position = compilationDef.<file>.Value.IndexOf("'POSITION", StringComparison.Ordinal)
 
            CompileAndVerify(compilationDef,
                             references:={SystemCoreRef},
                             sourceSymbolValidator:=Sub(m As ModuleSymbol)
                                                        Dim compilation = m.DeclaringCompilation
                                                        Dim tree = compilation.SyntaxTrees(0)
 
                                                        Dim model = compilation.GetSemanticModel(tree)
                                                        Dim node0 = DirectCast(tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectCreationExpression).AsNode(), ExpressionSyntax)
                                                        Dim info0 = model.GetSemanticInfoSummary(node0)
                                                        Assert.NotNull(info0.Type)
                                                        Assert.IsType(GetType(AnonymousTypeManager.AnonymousTypePublicSymbol), info0.Type)
                                                        Assert.False(DirectCast(info0.Type, INamedTypeSymbol).IsSerializable)
 
                                                        Dim expr1 = SyntaxFactory.ParseExpression(<text>New With { .aa = 1, .BB = "", .CCC = new SSS() }</text>.Value)
                                                        Dim info1 = model.GetSpeculativeTypeInfo(position, expr1, SpeculativeBindingOption.BindAsExpression)
                                                        Assert.NotNull(info1.Type)
                                                        Assert.Equal(info0.Type.OriginalDefinition, info1.Type.OriginalDefinition)
 
                                                        Dim expr2 = SyntaxFactory.ParseExpression(<text>New With { .aa = 1, Key .BB = "", .CCC = new SSS() }</text>.Value)
                                                        Dim info2 = model.GetSpeculativeTypeInfo(position, expr2, SpeculativeBindingOption.BindAsExpression)
                                                        Assert.NotNull(info2.Type)
                                                        Assert.NotEqual(info0.Type.OriginalDefinition, info2.Type.OriginalDefinition)
 
                                                    End Sub,
                             symbolValidator:=Sub(m As ModuleSymbol)
 
                                                  Dim type = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_0`3")
                                                  Assert.NotNull(type)
                                                  Assert.Equal(GetNamedTypeSymbol(m, "System.Object"), type.BaseType)
                                                  Assert.True(type.IsGenericType)
                                                  Assert.Equal(3, type.TypeParameters.Length)
 
                                                  ' Only one type should be emitted!!
                                                  Dim type2 = m.ContainingAssembly.GetTypeByMetadataName("VB$AnonymousType_1`3")
                                                  Assert.Null(type2)
                                              End Sub)
        End Sub
 
        <Fact>
        <WorkItem(641639, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/641639")>
        Public Sub Bug641639()
            Dim moduleDef =
    <compilation name="TestModule">
        <file name="a.vb">
Module ModuleB
    Sub Test1(x As Integer)
        Dim v1 As Object = New With { .aa = 1 } 
        Dim v2 As Object = Function(y as Integer) y + 1
    End Sub
End Module
        </file>
    </compilation>
 
            Dim testModule = CreateCompilationWithMscorlib40AndVBRuntime(moduleDef, TestOptions.ReleaseModule)
 
            Dim compilationDef =
    <compilation>
        <file name="a.vb">
Module ModuleA
End Module
        </file>
    </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndVBRuntimeAndReferences(moduleDef, {testModule.EmitToImageReference()}, TestOptions.ReleaseDll)
 
            Assert.Equal(1, compilation.Assembly.Modules(1).GlobalNamespace.GetTypeMembers("VB$AnonymousDelegate_0<TestModule>", 2).Length)
            Assert.Equal(1, compilation.Assembly.Modules(1).GlobalNamespace.GetTypeMembers("VB$AnonymousType_0<TestModule>", 1).Length)
        End Sub
 
#Region "Utils"
 
        Private Shared Sub CheckPropertyAccessorsAndField(m As ModuleSymbol, type As NamedTypeSymbol, propName As String, propType As TypeSymbol, isKey As Boolean)
            Dim prop = type.GetMembers().OfType(Of PropertySymbol)().Single()
            Assert.Equal(propType, prop.Type)
            Assert.Equal(propName, prop.Name)
            Assert.Equal(propName, prop.MetadataName)
            Assert.Equal(Accessibility.Public, prop.DeclaredAccessibility)
            Assert.False(prop.IsDefault)
            Assert.False(prop.IsMustOverride)
            Assert.False(prop.IsNotOverridable)
            Assert.False(prop.IsOverridable)
            Assert.False(prop.IsOverrides)
            Assert.False(prop.IsOverloads)
            Assert.Equal(isKey, prop.IsReadOnly)
            Assert.False(prop.IsShared)
            Assert.False(prop.IsWriteOnly)
            Assert.Equal(0, prop.Parameters.Length)
            Assert.False(prop.ShadowsExplicitly)
 
            Dim getter = prop.GetMethod
            CheckMethod(m, getter, "get_" & prop.Name,
                        Accessibility.Public,
                        retType:=getter.ReturnType)
 
            If Not isKey Then
                Dim setter = prop.SetMethod
                CheckMethod(m, setter, "set_" & prop.Name,
                            Accessibility.Public,
                            paramCount:=1,
                            isSub:=True)
 
                Assert.Equal(propType, setter.Parameters(0).Type)
            Else
                Assert.Null(prop.SetMethod)
            End If
 
            Dim field = type.GetMembers().OfType(Of FieldSymbol)().Single()
            Assert.Equal(propType, field.Type)
            Assert.Equal("$" & propName, field.Name)
            Assert.Equal("$" & propName, field.MetadataName)
            Assert.Equal(Accessibility.Private, field.DeclaredAccessibility)
 
            Dim parameter = type.Constructors.Single().Parameters(0)
            Assert.Equal(propType, parameter.Type)
            Assert.Equal(propName, parameter.Name)
            Assert.Equal(propName, parameter.MetadataName)
        End Sub
 
        Private Shared Sub CheckMethod(m As ModuleSymbol, method As MethodSymbol,
                                       name As String, accessibility As Accessibility,
                                       Optional paramCount As Integer = 0,
                                       Optional retType As TypeSymbol = Nothing,
                                       Optional isSub As Boolean = False,
                                       Optional isOverloads As Boolean = False,
                                       Optional isOverrides As Boolean = False,
                                       Optional isOverridable As Boolean = False,
                                       Optional isNotOverridable As Boolean = False)
 
            Assert.NotNull(method)
            Assert.Equal(name, method.Name)
            Assert.Equal(name, method.MetadataName)
            Assert.Equal(paramCount, method.ParameterCount)
 
            If isSub Then
                Assert.Null(retType)
                Assert.Equal(GetNamedTypeSymbol(m, "System.Void"), method.ReturnType)
                Assert.True(method.IsSub)
            End If
 
            If retType IsNot Nothing Then
                Assert.False(isSub)
                Assert.Equal(retType, method.ReturnType)
                Assert.False(method.IsSub)
            End If
 
            Assert.Equal(accessibility, method.DeclaredAccessibility)
            Assert.Equal(isOverloads, method.IsOverloads)
            Assert.Equal(isOverrides, method.IsOverrides)
            Assert.Equal(isOverridable, method.IsOverridable)
            Assert.Equal(isNotOverridable, method.IsNotOverridable)
 
            Assert.False(method.IsShared)
            Assert.False(method.IsMustOverride)
            Assert.False(method.IsGenericMethod)
            Assert.False(method.ShadowsExplicitly)
        End Sub
 
        Private Shared Function GetNamedTypeSymbol(m As ModuleSymbol, namedTypeName As String) As NamedTypeSymbol
            Dim nameParts = namedTypeName.Split("."c)
 
            Dim peAssembly = DirectCast(m.ContainingAssembly, PEAssemblySymbol)
            Dim nsSymbol As NamespaceSymbol = Nothing
            For Each ns In nameParts.Take(nameParts.Length - 1)
                nsSymbol = DirectCast(If(nsSymbol Is Nothing,
                                         m.ContainingAssembly.CorLibrary.GlobalNamespace.GetMember(ns),
                                         nsSymbol.GetMember(ns)), NamespaceSymbol)
            Next
            Return DirectCast(nsSymbol.GetTypeMember(nameParts(nameParts.Length - 1)), NamedTypeSymbol)
        End Function
 
#End Region
 
        <WorkItem(1319, "https://github.com/dotnet/roslyn/issues/1319")>
        <ConditionalFact(GetType(DesktopOnly), Reason:=ConditionalSkipReason.NetModulesNeedDesktop)>
        Public Sub MultipleNetmodulesWithAnonymousTypes()
            Dim compilationDef1 =
    <compilation>
        <file name="a.vb">
Class A
    Friend o1 As Object = new with { .hello = 1, .world = 2 }
    Friend d1 As Object = Function() 1
    public shared Function M1() As String
        return "Hello, "
    End Function
End Class
        </file>
    </compilation>
 
            Dim compilationDef2 =
    <compilation>
        <file name="a.vb">
Class B
    Inherits A
 
    Friend o2 As Object = new with { .hello = 1, .world = 2 }
    Friend d2 As Object = Function() 1
    public shared Function M2() As String
        return "world!"
    End Function
End Class
        </file>
    </compilation>
 
            Dim compilationDef3 =
    <compilation>
        <file name="a.vb">
Class Module1
    Friend o3 As Object = new with { .hello = 1, .world = 2 }
    Friend d3 As Object = Function() 1
 
    public shared Sub Main()
        System.Console.Write(A.M1())
        System.Console.WriteLine(B.M2())
    End Sub
End Class
        </file>
    </compilation>
 
            Dim comp1 = CreateCompilationWithMscorlib40(compilationDef1, options:=TestOptions.ReleaseModule.WithModuleName("A"))
            comp1.VerifyDiagnostics()
            Dim ref1 = comp1.EmitToImageReference()
 
            Dim comp2 = CreateCompilationWithMscorlib40AndReferences(compilationDef2, {ref1}, options:=TestOptions.ReleaseModule.WithModuleName("B"))
            comp2.VerifyDiagnostics()
            Dim ref2 = comp2.EmitToImageReference()
 
            Dim comp3 = CreateCompilationWithMscorlib40AndReferences(compilationDef3, {ref1, ref2}, options:=TestOptions.ReleaseExe.WithModuleName("C"))
            comp3.VerifyDiagnostics()
 
            Dim mA = comp3.Assembly.Modules(1)
            Assert.Equal("VB$AnonymousType_0<A>`2", mA.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousType")).Single().MetadataName)
            Assert.Equal("VB$AnonymousDelegate_0<A>`1", mA.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousDelegate")).Single().MetadataName)
 
            Dim mB = comp3.Assembly.Modules(2)
            Assert.Equal("VB$AnonymousType_0<B>`2", mB.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousType")).Single().MetadataName)
            Assert.Equal("VB$AnonymousDelegate_0<B>`1", mB.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousDelegate")).Single().MetadataName)
 
            CompileAndVerify(comp3, expectedOutput:="Hello, world!", symbolValidator:=
                             Sub(m)
                                 Dim mC = DirectCast(m, PEModuleSymbol)
                                 Assert.Equal("VB$AnonymousType_0`2", mC.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousType")).Single().MetadataName)
                                 Assert.Equal("VB$AnonymousDelegate_0`1", mC.GlobalNamespace.GetTypeMembers().Where(Function(t) t.Name.StartsWith("VB$AnonymousDelegate")).Single().MetadataName)
                             End Sub)
        End Sub
 
    End Class
 
End Namespace