File: Symbols\AnonymousTypesSymbolTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.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.
 
#nullable disable
 
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols
{
    public class AnonymousTypesSymbolTests : CompilingTestBase
    {
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_InQuery()
        {
            var source = LINQ + @"
class Query
{
    public static void Main(string[] args)
    {
        List1<int> c1 = new List1<int>(1, 2, 3);
        List1<int> r1 =
            from int x in c1
            let g = x * 10
            let z = g + x*100
            select x + z;
        System.Console.WriteLine(r1);
    }
}
";
            var verifier = CompileAndVerify(
                source,
                symbolValidator: module => TestAnonymousTypeSymbols(
                                               module,
                                               new TypeDescr() { FieldNames = new string[] { "x", "g" } },
                                               new TypeDescr() { FieldNames = new string[] { "<>h__TransparentIdentifier0", "z" } }
                                           )
            );
 
            TestAnonymousTypeFieldSymbols_InQuery(verifier.EmittedAssemblyData);
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_Mix()
        {
            var source = @"
using System;
 
namespace Test
{
    class Program
    {
        static int Main()
        {
            int result = 0;
 
            var a0 = new { b1 = true, b2 = false };
 
            var a1 = new
            {
                b1 = 0123456789,
                b2 = 1234567890U,
                b3 = 2345678901u,
                b4 = 3456789012L,
                b5 = 4567890123l,
                b6 = 5678901234UL,
                b7 = 6789012345Ul,
                b8 = 7890123456uL,
                b9 = 8901234567ul,
                b10 = 9012345678LU,
                b11 = 9123456780Lu,
                b12 = 1234567809lU,
                b13 = 2345678091lu
            };
            return result;        
        }
    }
}
";
            CompileAndVerify(source);
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeInConstructedMethod_NonEmpty()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Goo<int>()());
    }
 
    static Func<object> Goo<T>()
    {
        T x2 = default(T);
        return (Func<object>) (() => new { x2 });
    }
}";
            CompileAndVerify(
                source,
                expectedOutput: "{ x2 = 0 }"
            );
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeInConstructedMethod_NonEmpty2()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Goo<int>()());
    }
 
    static Func<object> Goo<T>()
    {
        T x2 = default(T);
        Func<object> x3 = () => new { x2 };
        return x3;
    }
}";
            CompileAndVerify(
                source,
                expectedOutput: "{ x2 = 0 }"
            );
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeInConstructedMethod_NonEmpty3()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Goo<int>());
        Console.WriteLine(Goo<string>());
        Console.WriteLine(Goo<int?>());
    }
 
    static object Goo<T>()
    {
        T x2 = default(T);
        return new { x2 };
    }
}";
            CompileAndVerify(
                source,
                expectedOutput:
@"{ x2 = 0 }
{ x2 =  }
{ x2 =  }"
            );
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeInConstructedMethod_NonEmpty4()
        {
            var source = @"
using System;
using System.Collections.Generic;
 
class Program
{
    static void Main(string[] args)
    {
        foreach(var x in Goo<int>())
        {
            Console.Write(x);
        }
    }
 
    static IEnumerable<object> Goo<T>()
    {
        T x2 = default(T);
        yield return new { x2 }.ToString();
        yield return new { YYY = default(T), z = new { field = x2 } };
    }
}";
            CompileAndVerify(
                source,
                expectedOutput: "{ x2 = 0 }{ YYY = 0, z = { field = 0 } }"
            );
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeInConstructedMethod_Empty()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Goo<int>()());
    }
 
    static Func<object> Goo<T>()
    {
        T x2 = default(T);
        return (Func<object>) (() => new { });
    }
}";
            CompileAndVerify(
                source,
                expectedOutput: "{ }"
            );
        }
 
        #region AnonymousTypeSymbol_InQuery :: Checking fields via reflection
 
        private void TestAnonymousTypeFieldSymbols_InQuery(ImmutableArray<byte> image)
        {
            Assembly refAsm = Assembly.Load(image.ToArray());
            Type type = refAsm.GetType("<>f__AnonymousType0`2");
            Assert.NotNull(type);
            Assert.Equal(2, type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Count());
 
            CheckField(type.GetField("<x>i__Field", BindingFlags.NonPublic | BindingFlags.Instance), type.GetGenericArguments()[0]);
            CheckField(type.GetField("<g>i__Field", BindingFlags.NonPublic | BindingFlags.Instance), type.GetGenericArguments()[1]);
        }
 
        private void CheckField(FieldInfo field, Type fieldType)
        {
            Assert.NotNull(field);
            Assert.NotNull(fieldType);
            Assert.Equal(fieldType, field.FieldType);
            Assert.Equal(FieldAttributes.Private | FieldAttributes.InitOnly, field.Attributes);
 
            var attrs = field.CustomAttributes.ToList();
            Assert.Equal(1, attrs.Count);
            Assert.Equal(typeof(DebuggerBrowsableAttribute), attrs[0].AttributeType);
 
            var args = attrs[0].ConstructorArguments.ToArray();
            Assert.Equal(1, args.Length);
            Assert.Equal(typeof(DebuggerBrowsableState), args[0].ArgumentType);
            Assert.Equal(DebuggerBrowsableState.Never, (DebuggerBrowsableState)args[0].Value);
        }
 
        #endregion
 
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_Simple()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { a = 1, b = 2 };
        object at2 = new { (new string[2]).Length, at1, C = new Object() };
        object at3 = new { a = '1', b = at1 };
 
        PrintFields(at1.GetType());
        PrintFields(at2.GetType());
        PrintFields(at3.GetType());
    }
    
    static void PrintFields(Type type)
    {
        Console.WriteLine(type.Name + "": "");
        foreach (var field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic))
        {
            Console.Write(""  "");
            Console.Write(field.Attributes);
            Console.Write("" "");
            Console.Write(field.FieldType.Name);
            Console.Write("" "");
            Console.Write(field.Name);
            Console.WriteLine();
        }
    }
}
";
            CompileAndVerify(
                source,
                symbolValidator: module => TestAnonymousTypeSymbols(
                                               module,
                                               new TypeDescr() { FieldNames = new string[] { "a", "b" } },
                                               new TypeDescr() { FieldNames = new string[] { "Length", "at1", "C" } }
                                           ),
                expectedOutput: @"
<>f__AnonymousType0`2: 
  Private, InitOnly Int32 <a>i__Field
  Private, InitOnly Int32 <b>i__Field
<>f__AnonymousType1`3: 
  Private, InitOnly Int32 <Length>i__Field
  Private, InitOnly <>f__AnonymousType0`2 <at1>i__Field
  Private, InitOnly Object <C>i__Field
<>f__AnonymousType0`2: 
  Private, InitOnly Char <a>i__Field
  Private, InitOnly <>f__AnonymousType0`2 <b>i__Field
"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>..ctor(<Length>j__TPar, <at1>j__TPar, <C>j__TPar)",
@"{
  // Code size       28 (0x1c)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  call       ""object..ctor()""
  IL_0006:  ldarg.0
  IL_0007:  ldarg.1
  IL_0008:  stfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_000d:  ldarg.0
  IL_000e:  ldarg.2
  IL_000f:  stfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_0014:  ldarg.0
  IL_0015:  ldarg.3
  IL_0016:  stfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_001b:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.Length.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.at1.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.C.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.Equals",
@"{
  // Code size       89 (0x59)
  .maxstack  3
  .locals init (<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar> V_0)
  IL_0000:  ldarg.1
  IL_0001:  isinst     ""<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>""
  IL_0006:  stloc.0
  IL_0007:  ldarg.0
  IL_0008:  ldloc.0
  IL_0009:  beq.s      IL_0057
  IL_000b:  ldloc.0
  IL_000c:  brfalse.s  IL_0055
  IL_000e:  call       ""System.Collections.Generic.EqualityComparer<<Length>j__TPar> System.Collections.Generic.EqualityComparer<<Length>j__TPar>.Default.get""
  IL_0013:  ldarg.0
  IL_0014:  ldfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_0019:  ldloc.0
  IL_001a:  ldfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_001f:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<Length>j__TPar>.Equals(<Length>j__TPar, <Length>j__TPar)""
  IL_0024:  brfalse.s  IL_0055
  IL_0026:  call       ""System.Collections.Generic.EqualityComparer<<at1>j__TPar> System.Collections.Generic.EqualityComparer<<at1>j__TPar>.Default.get""
  IL_002b:  ldarg.0
  IL_002c:  ldfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_0031:  ldloc.0
  IL_0032:  ldfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_0037:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<at1>j__TPar>.Equals(<at1>j__TPar, <at1>j__TPar)""
  IL_003c:  brfalse.s  IL_0055
  IL_003e:  call       ""System.Collections.Generic.EqualityComparer<<C>j__TPar> System.Collections.Generic.EqualityComparer<<C>j__TPar>.Default.get""
  IL_0043:  ldarg.0
  IL_0044:  ldfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_0049:  ldloc.0
  IL_004a:  ldfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_004f:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<C>j__TPar>.Equals(<C>j__TPar, <C>j__TPar)""
  IL_0054:  ret
  IL_0055:  ldc.i4.0
  IL_0056:  ret
  IL_0057:  ldc.i4.1
  IL_0058:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.GetHashCode",
@"{
  // Code size       75 (0x4b)
  .maxstack  3
  IL_0000:  ldc.i4     " + GetHashCodeInitialValue("<Length>i__Field", "<at1>i__Field", "<C>i__Field") + @"
  IL_0005:  ldc.i4     0xa5555529
  IL_000a:  mul
  IL_000b:  call       ""System.Collections.Generic.EqualityComparer<<Length>j__TPar> System.Collections.Generic.EqualityComparer<<Length>j__TPar>.Default.get""
  IL_0010:  ldarg.0
  IL_0011:  ldfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_0016:  callvirt   ""int System.Collections.Generic.EqualityComparer<<Length>j__TPar>.GetHashCode(<Length>j__TPar)""
  IL_001b:  add
  IL_001c:  ldc.i4     0xa5555529
  IL_0021:  mul
  IL_0022:  call       ""System.Collections.Generic.EqualityComparer<<at1>j__TPar> System.Collections.Generic.EqualityComparer<<at1>j__TPar>.Default.get""
  IL_0027:  ldarg.0
  IL_0028:  ldfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_002d:  callvirt   ""int System.Collections.Generic.EqualityComparer<<at1>j__TPar>.GetHashCode(<at1>j__TPar)""
  IL_0032:  add
  IL_0033:  ldc.i4     0xa5555529
  IL_0038:  mul
  IL_0039:  call       ""System.Collections.Generic.EqualityComparer<<C>j__TPar> System.Collections.Generic.EqualityComparer<<C>j__TPar>.Default.get""
  IL_003e:  ldarg.0
  IL_003f:  ldfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_0044:  callvirt   ""int System.Collections.Generic.EqualityComparer<<C>j__TPar>.GetHashCode(<C>j__TPar)""
  IL_0049:  add
  IL_004a:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.ToString",
@"{
  // Code size      138 (0x8a)
  .maxstack  7
  .locals init (<Length>j__TPar V_0,
                <at1>j__TPar V_1,
                <C>j__TPar V_2)
  IL_0000:  ldnull
  IL_0001:  ldstr      ""{{ Length = {0}, at1 = {1}, C = {2} }}""
  IL_0006:  ldc.i4.3
  IL_0007:  newarr     ""object""
  IL_000c:  dup
  IL_000d:  ldc.i4.0
  IL_000e:  ldarg.0
  IL_000f:  ldfld      ""<Length>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<Length>i__Field""
  IL_0014:  stloc.0
  IL_0015:  ldloca.s   V_0
  IL_0017:  dup
  IL_0018:  ldobj      ""<Length>j__TPar""
  IL_001d:  box        ""<Length>j__TPar""
  IL_0022:  brtrue.s   IL_0028
  IL_0024:  pop
  IL_0025:  ldnull
  IL_0026:  br.s       IL_0033
  IL_0028:  constrained. ""<Length>j__TPar""
  IL_002e:  callvirt   ""string object.ToString()""
  IL_0033:  stelem.ref
  IL_0034:  dup
  IL_0035:  ldc.i4.1
  IL_0036:  ldarg.0
  IL_0037:  ldfld      ""<at1>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<at1>i__Field""
  IL_003c:  stloc.1
  IL_003d:  ldloca.s   V_1
  IL_003f:  dup
  IL_0040:  ldobj      ""<at1>j__TPar""
  IL_0045:  box        ""<at1>j__TPar""
  IL_004a:  brtrue.s   IL_0050
  IL_004c:  pop
  IL_004d:  ldnull
  IL_004e:  br.s       IL_005b
  IL_0050:  constrained. ""<at1>j__TPar""
  IL_0056:  callvirt   ""string object.ToString()""
  IL_005b:  stelem.ref
  IL_005c:  dup
  IL_005d:  ldc.i4.2
  IL_005e:  ldarg.0
  IL_005f:  ldfld      ""<C>j__TPar <>f__AnonymousType1<<Length>j__TPar, <at1>j__TPar, <C>j__TPar>.<C>i__Field""
  IL_0064:  stloc.2
  IL_0065:  ldloca.s   V_2
  IL_0067:  dup
  IL_0068:  ldobj      ""<C>j__TPar""
  IL_006d:  box        ""<C>j__TPar""
  IL_0072:  brtrue.s   IL_0078
  IL_0074:  pop
  IL_0075:  ldnull
  IL_0076:  br.s       IL_0083
  IL_0078:  constrained. ""<C>j__TPar""
  IL_007e:  callvirt   ""string object.ToString()""
  IL_0083:  stelem.ref
  IL_0084:  call       ""string string.Format(System.IFormatProvider, string, params object[])""
  IL_0089:  ret
}"
            );
        }
 
        [Fact]
        public void AnonymousTypeSymbol_Simple_Threadsafety()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { a = 1, b = 2 };
        var at2 = new { a = 1, b = 2, c = 3};
        var at3 = new { a = 1, b = 2, c = 3, d = 4};
        var at4 = new { a = 1, b = 2, c = 3, d = 4, e = 5};
        var at5 = new { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6};
        var at6 = new { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7};
        var at7 = new { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8};
        var at8 = new { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9};
        var at9 = new { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9, k = 10};
 
        var at11 = new { aa = 1, b = 2 };
        var at12 = new { aa = 1, b = 2, c = 3};
        var at13 = new { aa = 1, b = 2, c = 3, d = 4};
        var at14 = new { aa = 1, b = 2, c = 3, d = 4, e = 5};
        var at15 = new { aa = 1, b = 2, c = 3, d = 4, e = 5, f = 6};
        var at16 = new { aa = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7};
        var at17 = new { aa = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8};
        var at18 = new { aa = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9};
        var at19 = new { aa = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9, k = 10};
 
        var at21 = new { ba = 1, b = 2 };
        var at22 = new { ba = 1, b = 2, c = 3};
        var at23 = new { ba = 1, b = 2, c = 3, d = 4};
        var at24 = new { ba = 1, b = 2, c = 3, d = 4, e = 5};
        var at25 = new { ba = 1, b = 2, c = 3, d = 4, e = 5, f = 6};
        var at26 = new { ba = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7};
        var at27 = new { ba = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8};
        var at28 = new { ba = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9};
        var at29 = new { ba = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9, k = 10};
 
        var at31 = new { ca = 1, b = 2 };
        var at32 = new { ca = 1, b = 2, c = 3};
        var at33 = new { ca = 1, b = 2, c = 3, d = 4};
        var at34 = new { ca = 1, b = 2, c = 3, d = 4, e = 5};
        var at35 = new { ca = 1, b = 2, c = 3, d = 4, e = 5, f = 6};
        var at36 = new { ca = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7};
        var at37 = new { ca = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8};
        var at38 = new { ca = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9};
        var at39 = new { ca = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9, k = 10};
 
        var at41 = new { da = 1, b = 2 };
        var at42 = new { da = 1, b = 2, c = 3};
        var at43 = new { da = 1, b = 2, c = 3, d = 4};
        var at44 = new { da = 1, b = 2, c = 3, d = 4, e = 5};
        var at45 = new { da = 1, b = 2, c = 3, d = 4, e = 5, f = 6};
        var at46 = new { da = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7};
        var at47 = new { da = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8};
        var at48 = new { da = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9};
        var at49 = new { da = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, j = 9, k = 10};
 
 
        PrintFields(at1.GetType());
        PrintFields(at2.GetType());
        PrintFields(at3.GetType());
    }
    
    static void PrintFields(Type type)
    {
        Console.WriteLine(type.Name + "": "");
        foreach (var field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic))
        {
            Console.Write(""  "");
            Console.Write(field.Attributes);
            Console.Write("" "");
            Console.Write(field.FieldType.Name);
            Console.Write("" "");
            Console.Write(field.Name);
            Console.WriteLine();
        }
    }
}
";
            for (int i = 0; i < 100; i++)
            {
                var compilation = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe);
 
                var tasks = new Task[10];
                for (int j = 0; j < tasks.Length; j++)
                {
                    var metadataOnly = j % 2 == 0;
                    tasks[j] = Task.Run(() =>
                    {
                        var stream = new MemoryStream();
                        var result = compilation.Emit(stream, options: new EmitOptions(metadataOnly: metadataOnly));
                        result.Diagnostics.Verify();
                    });
                }
 
                // this should not fail. if you ever see a NRE or some kind of crash here enter a bug.
                // it may be reproducing just once in a while, in Release only... 
                // it is still a bug.
                Task.WaitAll(tasks);
            }
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_Empty()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { };
        var at2 = new { };
 
        at2 = at1;
 
        string x = at1.ToString() + at2.ToString();
 
        PrintFields(at1.GetType());
    }
    
    static void PrintFields(Type type)
    {
        Console.WriteLine(type.Name + "": "");
        foreach (var field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic))
        {
            Console.Write(""  "");
            Console.Write(field.Attributes);
            Console.Write("" "");
            Console.Write(field.FieldType.Name);
            Console.Write("" "");
            Console.Write(field.Name);
            Console.WriteLine();
        }
    }
}
";
            CompileAndVerify(
                source,
                symbolValidator: module => TestAnonymousTypeSymbols(
                                               module,
                                               new TypeDescr() { FieldNames = new string[] { } }
                                           ),
                expectedOutput: @"
<>f__AnonymousType0:
"
            ).VerifyIL(
                "<>f__AnonymousType0..ctor()",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       ""object..ctor()""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0.Equals",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  .locals init (<>f__AnonymousType0 V_0)
  IL_0000:  ldarg.1
  IL_0001:  isinst     ""<>f__AnonymousType0""
  IL_0006:  stloc.0
  IL_0007:  ldarg.0
  IL_0008:  ldloc.0
  IL_0009:  beq.s      IL_0010
  IL_000b:  ldloc.0
  IL_000c:  ldnull
  IL_000d:  cgt.un
  IL_000f:  ret
  IL_0010:  ldc.i4.1
  IL_0011:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0.GetHashCode",
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldc.i4.0
  IL_0001:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0.ToString",
@"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  ldstr      ""{ }""
  IL_0005:  ret
}"
            );
        }
 
        [WorkItem(543022, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543022")]
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_StandardNames()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { GetHashCode = new { } };
        Console.Write(at1.GetType());
        Console.Write(""-"");
        Console.Write(at1.GetHashCode.GetType());
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: "<>f__AnonymousType0`1[<>f__AnonymousType1]-<>f__AnonymousType1");
        }
 
        [WorkItem(543022, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543022")]
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_StandardNames2()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { ToString = ""Field"" };
        Console.Write(at1.ToString());
        Console.Write(""-"");
        Console.Write(at1.ToString);
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: "{ ToString = Field }-Field");
        }
 
        [Fact]
        public void AnonymousTypeSymbol_StandardNames3()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var at1 = new { ToString = 1, Equals = new Object(), GetHashCode = ""GetHashCode"" };
        PrintFields(at1.GetType());
    }
    
    static void PrintFields(Type type)
    {
        Console.WriteLine(type.Name + "": "");
        foreach (var field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic))
        {
            Console.Write(""  "");
            Console.Write(field.Attributes);
            Console.Write("" "");
            Console.Write(field.FieldType.Name);
            Console.Write("" "");
            Console.Write(field.Name);
            Console.WriteLine();
        }
    }
}
";
            CompileAndVerify(
                source,
                symbolValidator: module => TestAnonymousTypeSymbols(
                                               module,
                                               new TypeDescr() { FieldNames = new string[] { "ToString", "Equals", "GetHashCode" } }
                                           ),
                expectedOutput: @"
<>f__AnonymousType0`3: 
  Private, InitOnly Int32 <ToString>i__Field
  Private, InitOnly Object <Equals>i__Field
  Private, InitOnly String <GetHashCode>i__Field
"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>..ctor",
@"{
  // Code size       28 (0x1c)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  call       ""object..ctor()""
  IL_0006:  ldarg.0
  IL_0007:  ldarg.1
  IL_0008:  stfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_000d:  ldarg.0
  IL_000e:  ldarg.2
  IL_000f:  stfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_0014:  ldarg.0
  IL_0015:  ldarg.3
  IL_0016:  stfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_001b:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.Equals",
@"{
  // Code size       89 (0x59)
  .maxstack  3
  .locals init (<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar> V_0)
  IL_0000:  ldarg.1
  IL_0001:  isinst     ""<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>""
  IL_0006:  stloc.0
  IL_0007:  ldarg.0
  IL_0008:  ldloc.0
  IL_0009:  beq.s      IL_0057
  IL_000b:  ldloc.0
  IL_000c:  brfalse.s  IL_0055
  IL_000e:  call       ""System.Collections.Generic.EqualityComparer<<ToString>j__TPar> System.Collections.Generic.EqualityComparer<<ToString>j__TPar>.Default.get""
  IL_0013:  ldarg.0
  IL_0014:  ldfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_0019:  ldloc.0
  IL_001a:  ldfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_001f:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<ToString>j__TPar>.Equals(<ToString>j__TPar, <ToString>j__TPar)""
  IL_0024:  brfalse.s  IL_0055
  IL_0026:  call       ""System.Collections.Generic.EqualityComparer<<Equals>j__TPar> System.Collections.Generic.EqualityComparer<<Equals>j__TPar>.Default.get""
  IL_002b:  ldarg.0
  IL_002c:  ldfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_0031:  ldloc.0
  IL_0032:  ldfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_0037:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<Equals>j__TPar>.Equals(<Equals>j__TPar, <Equals>j__TPar)""
  IL_003c:  brfalse.s  IL_0055
  IL_003e:  call       ""System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar> System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar>.Default.get""
  IL_0043:  ldarg.0
  IL_0044:  ldfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_0049:  ldloc.0
  IL_004a:  ldfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_004f:  callvirt   ""bool System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar>.Equals(<GetHashCode>j__TPar, <GetHashCode>j__TPar)""
  IL_0054:  ret
  IL_0055:  ldc.i4.0
  IL_0056:  ret
  IL_0057:  ldc.i4.1
  IL_0058:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.GetHashCode",
@"{
  // Code size       75 (0x4b)
  .maxstack  3
  IL_0000:  ldc.i4     0x3711624
  IL_0005:  ldc.i4     0xa5555529
  IL_000a:  mul
  IL_000b:  call       ""System.Collections.Generic.EqualityComparer<<ToString>j__TPar> System.Collections.Generic.EqualityComparer<<ToString>j__TPar>.Default.get""
  IL_0010:  ldarg.0
  IL_0011:  ldfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_0016:  callvirt   ""int System.Collections.Generic.EqualityComparer<<ToString>j__TPar>.GetHashCode(<ToString>j__TPar)""
  IL_001b:  add
  IL_001c:  ldc.i4     0xa5555529
  IL_0021:  mul
  IL_0022:  call       ""System.Collections.Generic.EqualityComparer<<Equals>j__TPar> System.Collections.Generic.EqualityComparer<<Equals>j__TPar>.Default.get""
  IL_0027:  ldarg.0
  IL_0028:  ldfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_002d:  callvirt   ""int System.Collections.Generic.EqualityComparer<<Equals>j__TPar>.GetHashCode(<Equals>j__TPar)""
  IL_0032:  add
  IL_0033:  ldc.i4     0xa5555529
  IL_0038:  mul
  IL_0039:  call       ""System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar> System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar>.Default.get""
  IL_003e:  ldarg.0
  IL_003f:  ldfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_0044:  callvirt   ""int System.Collections.Generic.EqualityComparer<<GetHashCode>j__TPar>.GetHashCode(<GetHashCode>j__TPar)""
  IL_0049:  add
  IL_004a:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.ToString",
@"{
  // Code size      138 (0x8a)
  .maxstack  7
  .locals init (<ToString>j__TPar V_0,
                <Equals>j__TPar V_1,
                <GetHashCode>j__TPar V_2)
  IL_0000:  ldnull
  IL_0001:  ldstr      ""{{ ToString = {0}, Equals = {1}, GetHashCode = {2} }}""
  IL_0006:  ldc.i4.3
  IL_0007:  newarr     ""object""
  IL_000c:  dup
  IL_000d:  ldc.i4.0
  IL_000e:  ldarg.0
  IL_000f:  ldfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_0014:  stloc.0
  IL_0015:  ldloca.s   V_0
  IL_0017:  dup
  IL_0018:  ldobj      ""<ToString>j__TPar""
  IL_001d:  box        ""<ToString>j__TPar""
  IL_0022:  brtrue.s   IL_0028
  IL_0024:  pop
  IL_0025:  ldnull
  IL_0026:  br.s       IL_0033
  IL_0028:  constrained. ""<ToString>j__TPar""
  IL_002e:  callvirt   ""string object.ToString()""
  IL_0033:  stelem.ref
  IL_0034:  dup
  IL_0035:  ldc.i4.1
  IL_0036:  ldarg.0
  IL_0037:  ldfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_003c:  stloc.1
  IL_003d:  ldloca.s   V_1
  IL_003f:  dup
  IL_0040:  ldobj      ""<Equals>j__TPar""
  IL_0045:  box        ""<Equals>j__TPar""
  IL_004a:  brtrue.s   IL_0050
  IL_004c:  pop
  IL_004d:  ldnull
  IL_004e:  br.s       IL_005b
  IL_0050:  constrained. ""<Equals>j__TPar""
  IL_0056:  callvirt   ""string object.ToString()""
  IL_005b:  stelem.ref
  IL_005c:  dup
  IL_005d:  ldc.i4.2
  IL_005e:  ldarg.0
  IL_005f:  ldfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_0064:  stloc.2
  IL_0065:  ldloca.s   V_2
  IL_0067:  dup
  IL_0068:  ldobj      ""<GetHashCode>j__TPar""
  IL_006d:  box        ""<GetHashCode>j__TPar""
  IL_0072:  brtrue.s   IL_0078
  IL_0074:  pop
  IL_0075:  ldnull
  IL_0076:  br.s       IL_0083
  IL_0078:  constrained. ""<GetHashCode>j__TPar""
  IL_007e:  callvirt   ""string object.ToString()""
  IL_0083:  stelem.ref
  IL_0084:  call       ""string string.Format(System.IFormatProvider, string, params object[])""
  IL_0089:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.ToString.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<ToString>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<ToString>i__Field""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.Equals.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<Equals>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<Equals>i__Field""
  IL_0006:  ret
}"
            ).VerifyIL(
                "<>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.GetHashCode.get",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""<GetHashCode>j__TPar <>f__AnonymousType0<<ToString>j__TPar, <Equals>j__TPar, <GetHashCode>j__TPar>.<GetHashCode>i__Field""
  IL_0006:  ret
}"
            );
        }
 
        #region "Utility methods"
 
        /// <summary>
        /// This method duplicates the generation logic for initial value used 
        /// in anonymous type's GetHashCode function
        /// </summary>
        public static string GetHashCodeInitialValue(params string[] names)
        {
            const int HASH_FACTOR = -1521134295; // (int)0xa5555529
            int init = 0;
            foreach (var name in names)
            {
                init = unchecked(init * HASH_FACTOR + Hash.GetFNVHashCode(name));
            }
            return "0x" + init.ToString("X").ToLower();
        }
 
        private struct TypeDescr
        {
            public string[] FieldNames;
        }
 
        private void TestAnonymousTypeSymbols(ModuleSymbol module, params TypeDescr[] typeDescrs)
        {
            int cnt = typeDescrs.Length;
            Assert.Equal(0, module.GlobalNamespace.GetMembers("<>f__AnonymousType" + cnt.ToString()).Length);
 
            //  test template classes
            for (int i = 0; i < cnt; i++)
            {
                TestAnonymousType(module.GlobalNamespace.GetMember<NamedTypeSymbol>("<>f__AnonymousType" + i.ToString()), i, typeDescrs[i]);
            }
        }
 
        private void TestAnonymousType(NamedTypeSymbol type, int typeIndex, TypeDescr typeDescr)
        {
            Assert.NotEqual(default, typeDescr);
            Assert.NotNull(typeDescr.FieldNames);
 
            //  prepare 
            int fieldsCount = typeDescr.FieldNames.Length;
            string[] genericParameters = new string[fieldsCount];
            string genericParametersList = null;
            for (int i = 0; i < fieldsCount; i++)
            {
                genericParameters[i] = String.Format("<{0}>j__TPar", typeDescr.FieldNames[i]);
 
                genericParametersList = genericParametersList == null
                                            ? genericParameters[i]
                                            : genericParametersList + ", " + genericParameters[i];
            }
            string genericParametersSuffix = fieldsCount == 0 ? "" : "<" + genericParametersList + ">";
 
            string typeViewName = String.Format("<>f__AnonymousType{0}{1}", typeIndex.ToString(), genericParametersSuffix);
 
            //  test
            Assert.Equal(typeViewName, type.ToDisplayString());
            Assert.Equal("object", type.BaseType().ToDisplayString());
            Assert.True(fieldsCount == 0 ? !type.IsGenericType : type.IsGenericType);
            Assert.Equal(fieldsCount, type.Arity);
            Assert.Equal(Accessibility.Internal, type.DeclaredAccessibility);
            Assert.True(type.IsSealed);
            Assert.False(type.IsStatic);
            Assert.Equal(0, type.Interfaces().Length);
 
            //  test non-existing members
            Assert.Equal(0, type.GetMembers("doesnotexist").Length);
 
            TestAttributeOnSymbol(
                type,
                new AttributeInfo
                {
                    CtorName = "System.Runtime.CompilerServices.CompilerGeneratedAttribute.CompilerGeneratedAttribute()",
                    ConstructorArguments = new string[] { }
                }
            );
 
            //  test properties
            for (int i = 0; i < fieldsCount; i++)
            {
                var typeParameter = type.TypeParameters[i];
                Assert.Equal(genericParameters[i], typeParameter.ToDisplayString());
                TestAnonymousTypeProperty(type, typeViewName, typeDescr.FieldNames[i], typeParameter);
            }
 
            //  methods
            CheckMethodSymbol(
                this.GetMemberByName<MethodSymbol>(type, ".ctor"),
                String.Format("{0}.<>f__AnonymousType{1}({2})", typeViewName, typeIndex.ToString(), genericParametersList),
                "void",
                attr: new AttributeInfo() { CtorName = "System.Diagnostics.DebuggerHiddenAttribute.DebuggerHiddenAttribute()", ConstructorArguments = new string[] { } }
            );
            CheckMethodSymbol(
                this.GetMemberByName<MethodSymbol>(type, "Equals"),
                String.Format("{0}.Equals(object)", typeViewName),
                "bool",
                isVirtualAndOverride: true,
                attr: new AttributeInfo() { CtorName = "System.Diagnostics.DebuggerHiddenAttribute.DebuggerHiddenAttribute()", ConstructorArguments = new string[] { } }
            );
            CheckMethodSymbol(
                this.GetMemberByName<MethodSymbol>(type, "GetHashCode"),
                String.Format("{0}.GetHashCode()", typeViewName),
                "int",
                isVirtualAndOverride: true,
                attr: new AttributeInfo() { CtorName = "System.Diagnostics.DebuggerHiddenAttribute.DebuggerHiddenAttribute()", ConstructorArguments = new string[] { } }
            );
            CheckMethodSymbol(
                this.GetMemberByName<MethodSymbol>(type, "ToString"),
                String.Format("{0}.ToString()", typeViewName),
                "string",
                isVirtualAndOverride: true,
                attr: new AttributeInfo() { CtorName = "System.Diagnostics.DebuggerHiddenAttribute.DebuggerHiddenAttribute()", ConstructorArguments = new string[] { } }
            );
        }
 
        private T GetMemberByName<T>(NamedTypeSymbol type, string name) where T : Symbol
        {
            foreach (var symbol in type.GetMembers(name))
            {
                if (symbol is T)
                {
                    return (T)symbol;
                }
            }
            return null;
        }
 
        private void TestAnonymousTypeProperty(NamedTypeSymbol type, string typeViewName, string name, TypeSymbol propType)
        {
            PropertySymbol property = this.GetMemberByName<PropertySymbol>(type, name);
            Assert.NotNull(property);
            Assert.Equal(propType, property.Type);
            Assert.Equal(Accessibility.Public, property.DeclaredAccessibility);
            Assert.False(property.IsAbstract);
            Assert.False(property.IsIndexer);
            Assert.False(property.IsOverride);
            Assert.True(property.IsReadOnly);
            Assert.False(property.IsStatic);
            Assert.False(property.IsSealed);
            Assert.False(property.IsVirtual);
            Assert.False(property.IsWriteOnly);
 
            var getter = property.GetMethod;
            Assert.NotNull(getter);
            Assert.Equal("get_" + name, getter.Name);
            CheckMethodSymbol(
                getter,
                typeViewName + "." + name + ".get",
                propType.ToDisplayString()
            );
        }
 
        private void CheckMethodSymbol(
            MethodSymbol method,
            string signature,
            string retType,
            bool isVirtualAndOverride = false,
            AttributeInfo attr = null
        )
        {
            Assert.NotNull(method);
            Assert.Equal(signature, method.ToDisplayString());
            Assert.Equal(Accessibility.Public, method.DeclaredAccessibility);
            Assert.False(method.IsAbstract);
            Assert.Equal(isVirtualAndOverride, method.IsOverride);
            Assert.False(method.IsStatic);
            Assert.False(method.IsSealed);
            Assert.False(method.IsVararg);
            Assert.False(method.IsVirtual);
            Assert.Equal(isVirtualAndOverride, method.IsMetadataVirtual());
            Assert.Equal(retType, method.ReturnTypeWithAnnotations.ToDisplayString());
 
            TestAttributeOnSymbol(method, attr == null ? new AttributeInfo[] { } : new AttributeInfo[] { attr });
        }
 
        private class AttributeInfo
        {
            public string CtorName;
            public string[] ConstructorArguments;
        }
 
        private void TestAttributeOnSymbol(Symbol symbol, params AttributeInfo[] attributes)
        {
            var actual = symbol.GetAttributes();
            Assert.Equal(attributes.Length, actual.Length);
 
            for (int index = 0; index < attributes.Length; index++)
            {
                var attr = attributes[index];
 
                Assert.Equal(attr.CtorName, actual[index].AttributeConstructor.ToDisplayString());
 
                Assert.Equal(attr.ConstructorArguments.Length, actual[index].CommonConstructorArguments.Length);
                for (int argIndex = 0; argIndex < attr.ConstructorArguments.Length; argIndex++)
                {
                    Assert.Equal(
                        attr.ConstructorArguments[argIndex],
                        actual[index].CommonConstructorArguments[argIndex].Value.ToString()
                    );
                }
            }
        }
 
        #endregion
 
        [ClrOnlyFact]
        public void AnonymousType_BaseAccess()
        {
            var source = @"
using System;
 
class Base
{
    protected int field = 123;
}
 
class Derived: Base
{
    public static void Main(string[] args)
    {
        (new Derived()).Test();
    }
    public void Test()
    {
        var a = new { base.field };
        Console.WriteLine(a.ToString());
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: "{ field = 123 }");
        }
 
        [ClrOnlyFact]
        public void AnonymousType_PropertyAccess()
        {
            var source = @"
using System;
 
class Class1
{
    public static void Main(string[] args)
    {
        var a = new { (new Class1()).PropertyA };
        Console.WriteLine(a.ToString());
    }
    public string PropertyA
    {
        get { return ""pa-value""; }
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: "{ PropertyA = pa-value }");
        }
 
        [ClrOnlyFact]
        public void AnonymousType_Simple()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        int a = (new {a = 1, b=""text"", }).a;
        string b = (new {a = 1, b=""text""}).b;
        Console.WriteLine(string.Format(""a={0}; b={1}"", a, b));
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: "a=1; b=text");
        }
 
        [ClrOnlyFact]
        public void AnonymousType_CustModifiersOnPropertyFields()
        {
            var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        var intArrMod = Modifiers.F9();
        var at1 = new { f = intArrMod };
        var at2 = new { f = new int[] {} };
        at1 = at2;
        at2 = at1;
    }
}
";
            CompileAndVerify(
                source,
                references: new[] { TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll });
        }
 
        [ClrOnlyFact]
        public void AnonymousType_ToString()
        {
            // test AnonymousType.ToString()
            using (new EnsureInvariantCulture())
            {
                var source = @"
using System;
 
class Query
{
    public static void Main(string[] args)
    {
        Console.WriteLine((new { a = 1, b=""text"", c=123.456}).ToString());
    }
}
";
                CompileAndVerify(
                    source,
                    expectedOutput: "{ a = 1, b = text, c = 123.456 }");
 
            }
        }
 
        [ClrOnlyFact]
        public void AnonymousType_Equals()
        {
            var source = @"
using System;
using System.Collections.Generic;
 
struct S: IEquatable<S>
{
    public int X;
    public int Y;
    public S(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
 
    public override string ToString()
    {
        return string.Format(""({0}, {1})"", this.X, this.Y);
    }
 
    public bool Equals(S other)
    {
        bool equals = this.X == other.X && this.Y == other.Y;
        this.X = other.X = -1;
        this.Y = other.Y = -1;
        return equals;
    }
}
 
class Query
{
    public static void Main(string[] args)
    {
        Compare(new { a = new S(1, 2), b = new S(1, 2) }, new { a = new S(1, 2), b = new S(1, 2) });
        Compare(new { a = new S(1, 2), b = new S(1, 2) }, new { b = new S(1, 2), a = new S(1, 2) });
        
        object a = new { a = new S(1, 2) };
        Compare(a, new { a = new S(1, 2) });
        Compare(a, new { a = new S(-1, -1) });
 
        Compare(new { a = new S(1, 2) }, a);
        Compare(new { a = new S(-1, -1) }, a);
    }
    public static void Compare(object a, object b)
    {
        Console.WriteLine(string.Format(""{0}.Equals({1}) = {2}"", a.ToString(), b.ToString(), a.Equals(b).ToString()));
    }
}";
            CompileAndVerify(
                source,
                expectedOutput: @"
{ a = (1, 2), b = (1, 2) }.Equals({ a = (1, 2), b = (1, 2) }) = True
{ a = (1, 2), b = (1, 2) }.Equals({ b = (1, 2), a = (1, 2) }) = False
{ a = (1, 2) }.Equals({ a = (1, 2) }) = True
{ a = (1, 2) }.Equals({ a = (-1, -1) }) = False
{ a = (1, 2) }.Equals({ a = (1, 2) }) = True
{ a = (-1, -1) }.Equals({ a = (1, 2) }) = False
");
        }
 
        [ClrOnlyFact]
        public void AnonymousType_GetHashCode()
        {
            var source = @"
using System;
 
struct S
{
    public int X;
    public int Y;
    public S(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
 
    public override bool Equals(object obj)
    {
        throw new Exception();
    }
 
    public override int GetHashCode()
    {
        return this.X + this.Y;
    }
 
    public override string ToString()
    {
        return string.Format(""({0}, {1})"", this.X, this.Y);
    }
}
 
class Query
{
    public static void Main(string[] args)
    {
        Print(new { }, new S(0, 0));
        Print(new { a = new S(2, 2), b = new S(1, 2) }, new { a = new S(4, 0), b = new S(2, 1) });
        Print(new { a = new S(4, 0), b = new S(2, 1) }, new { b = new S(4, 0), a = new S(2, 1) });
    }
    public static void Print(object a, object b)
    {
        Console.WriteLine(string.Format(""{0}.GetHashCode() == {1}.GetHashCode() = {2}"", a.ToString(), b.ToString(), a.GetHashCode() == b.GetHashCode()));
    }
}
";
            CompileAndVerify(
                source,
                expectedOutput: @"
{ }.GetHashCode() == (0, 0).GetHashCode() = True
{ a = (2, 2), b = (1, 2) }.GetHashCode() == { a = (4, 0), b = (2, 1) }.GetHashCode() = True
{ a = (4, 0), b = (2, 1) }.GetHashCode() == { b = (4, 0), a = (2, 1) }.GetHashCode() = False
");
        }
 
        [ClrOnlyFact]
        public void AnonymousType_MultiplyEmitDoesNotChangeTheOrdering()
        {
            //  this test checks whether or not anonymous types which came from speculative 
            //  semantic API have any effect on the anonymous types emitted and
            //  whether or not the order is still the same across several emits
 
            var source1 = @"
using System;
 
class Class2
{
    public static void Main2()
    {
        var d = new { args = 0 };
        var b = new { a = """", b = 1 };
    }
}
";
            var source2 = @"
using System;
 
class Class1
{
    public static void Main(string[] args)
    {
        var a = new { };
        var b = new { a = """", b = 1 };
        var c = new { b = 1, a = .2 };
        var d = new { args };
    }
}
";
            var source3 = @"
using System;
 
class Class3
{
    public static void Main2()
    {
        var c = new { b = 1, a = .2 };
        var a = new { };
    }
}
";
            var compilation = CreateCompilationWithMscorlib40(new string[] { source1, source2, source3 }, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal), parseOptions: TestOptions.Regular);
 
            for (int i = 0; i < 10; i++)
            {
                this.CompileAndVerify(
                    compilation,
                    symbolValidator: module =>
                    {
                        var types = module.GlobalNamespace.GetTypeMembers()
                                        .Where(t => t.Name.StartsWith("<>", StringComparison.Ordinal))
                                        .Select(t => t.ToDisplayString())
                                        .OrderBy(t => t)
                                        .ToArray();
 
                        Assert.Equal(4, types.Length);
                        Assert.Equal("<>f__AnonymousType0<<args>j__TPar>", types[0]);
                        Assert.Equal("<>f__AnonymousType1<<a>j__TPar, <b>j__TPar>", types[1]);
                        Assert.Equal("<>f__AnonymousType2", types[2]);
                        Assert.Equal("<>f__AnonymousType3<<b>j__TPar, <a>j__TPar>", types[3]);
                    },
                    verify: Verification.Passes
                );
 
                // do some speculative semantic query
                var model = compilation.GetSemanticModel(compilation.SyntaxTrees[0]);
                var position = source1.IndexOf("var d", StringComparison.Ordinal) - 1;
                var expr1 = SyntaxFactory.ParseExpression("new { x = 1, y" + i.ToString() + " = \"---\" }");
                var info1 = model.GetSpeculativeTypeInfo(position, expr1, SpeculativeBindingOption.BindAsExpression);
                Assert.NotNull(info1.Type);
            }
        }
 
        [WorkItem(543134, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543134")]
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_Simple_1()
        {
            var source = @"
class Test
{
    public static void Main()
    {
        var a = new { };
        var b = new { p1 = 10 };
    }
}
";
            CompileAndVerify(source);
        }
 
        [ClrOnlyFact]
        public void AnonymousTypeSymbol_NamesConflictInsideLambda()
        {
            var source = @"
using System;
class Test
{
    public static void Main()
    {
        M(123);
    }
 
    public static void M<T>(T p)
    {
        Action a = () => { Console.Write(new { x = 1221, get_x = p }.x.ToString()); };
        a();
    }
}
";
            CompileAndVerify(source, expectedOutput: "1221");
        }
 
        [WorkItem(543693, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543693")]
        [ClrOnlyFact]
        public void Bug11593a()
        {
            var source = @"
delegate T Func<A0, T>(A0 a0);
class Y<U>
{
    public U u;
    public Y(U u)
    {
        this.u = u;
    }
    public Y<T> Select<T>(Func<U, T> selector)
    {
        return new Y<T>(selector(u));
    }
}
class P
{
    static void Main()
    {
        var src = new Y<int>(2);
        var q = from x in src
                let y = x + 3
                select new { X = x, Y = y };
 
        if ((q.u.X != 2 || q.u.Y != 5))
        {
        }
        System.Console.WriteLine(""Success"");
    }
}
";
            CompileAndVerify(source, expectedOutput: "Success");
        }
 
        [WorkItem(543693, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543693")]
        [ClrOnlyFact]
        public void Bug11593b()
        {
            var source = @"
delegate T Func<A0, T>(A0 a0);
class Y<U>
{
    public U u;
    public Y(U u)
    {
        this.u = u;
    }
    public Y<T> Select<T>(Func<U, T> selector)
    {
        return new Y<T>(selector(u));
    }
}
class P
{
    static void Main()
    {
        var xxx = new { X = 1, Y = 2 };
 
        var src = new Y<int>(2);
        var q = from x in src
                let y = x + 3
                select new { X = x, Y = y };
 
        if ((q.u.X != 2 || q.u.Y != 5))
        {
        }
        System.Console.WriteLine(""Success"");
    }
}
";
            CompileAndVerify(source, expectedOutput: "Success");
        }
 
        [WorkItem(543177, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543177")]
        [ClrOnlyFact]
        public void AnonymousTypePropertyValueWithWarning()
        {
            var source = @"
using System;
 
class Program
{
    static void Main()
    {
        var a1 = new
        {
            p1 = 0123456789L,
            p2 = 0123456789l, // Warning CS0078
        };
 
        Console.Write(a1.p1 == a1.p2);
    }
}
";
            CompileAndVerify(source, expectedOutput: "True");
        }
 
        [Fact(), WorkItem(544323, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544323")]
        public void AnonymousTypeAndMemberSymbolsLocations()
        {
            var source = @"
using System;
 
class Program
{
    static void Main()
    {
        var an = new  {    id = 1, name = ""QC""    };
    }
}
";
            var tree = SyntaxFactory.ParseSyntaxTree(source);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var expr = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousObjectCreationExpressionSyntax>().Single();
 
            var sym = model.GetSymbolInfo(expr);
            Assert.NotNull(sym.Symbol);
            Assert.True(sym.Symbol.GetSymbol().IsFromCompilation(comp), "IsFromCompilation");
            Assert.False(sym.Symbol.Locations.IsEmpty, "Symbol Location");
            Assert.True(sym.Symbol.Locations[0].IsInSource);
 
            var info = model.GetTypeInfo(expr);
            Assert.NotNull(info.Type);
            var mems = info.Type.GetMembers();
            foreach (var m in mems)
            {
                Assert.True(m.GetSymbol().IsFromCompilation(comp), "IsFromCompilation");
                Assert.False(m.Locations.IsEmpty, String.Format("No Location: {0}", m));
                Assert.True(m.Locations[0].IsInSource);
            }
        }
 
        [Fact]
        public void SameAnonymousTypeInTwoLocations()
        {
            // This code declares the same anonymous type twice. Make sure the locations
            // reflect this.
            var source = @"
using System;
 
class Program
{
    static void Main()
    {
        var a1 = new  { id = 1, name = ""QC"" };
        var a2 = new  { id = 1, name = ""QC"" };
        var a3 = a1;
        var a4 = a2;
    }
}
";
            var tree = SyntaxFactory.ParseSyntaxTree(source);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var programType = (NamedTypeSymbol)(comp.GlobalNamespace.GetTypeMembers("Program").Single());
            var mainMethod = (MethodSymbol)(programType.GetMembers("Main").Single());
            var mainSyntax = mainMethod.DeclaringSyntaxReferences.Single().GetSyntax() as MethodDeclarationSyntax;
            var mainBlock = mainSyntax.Body;
            var statement1 = mainBlock.Statements[0] as LocalDeclarationStatementSyntax;
            var statement2 = mainBlock.Statements[1] as LocalDeclarationStatementSyntax;
            var statement3 = mainBlock.Statements[2] as LocalDeclarationStatementSyntax;
            var statement4 = mainBlock.Statements[3] as LocalDeclarationStatementSyntax;
            var localA3 = model.GetDeclaredSymbol(statement3.Declaration.Variables[0]) as ILocalSymbol;
            var localA4 = model.GetDeclaredSymbol(statement4.Declaration.Variables[0]) as ILocalSymbol;
            var typeA3 = localA3.Type;
            var typeA4 = localA4.Type;
 
            // A3 and A4 should have different type objects, that compare equal. They should have 
            // different locations.
            Assert.Equal(typeA3, typeA4);
            Assert.NotSame(typeA3, typeA4);
            Assert.NotEqual(typeA3.Locations[0], typeA4.Locations[0]);
 
            // The locations of a3's type should be the type declared in statement 1, the location
            // of a4's type should be the type declared in statement 2.
            Assert.True(statement1.Span.Contains(typeA3.Locations[0].SourceSpan));
            Assert.True(statement2.Span.Contains(typeA4.Locations[0].SourceSpan));
        }
 
        private static readonly SyntaxTree s_equalityComparerSourceTree = Parse(@"
namespace System.Collections
{
  public interface IEqualityComparer
  {
    bool Equals(object x, object y);
    int GetHashCode(object obj);
  }
}
 
namespace System.Collections.Generic
{
  public interface IEqualityComparer<T>
  {
    bool Equals(T x, T y);
    int GetHashCode(T obj);
  }
 
  public abstract class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
  {
      protected EqualityComparer() { }
      public abstract bool Equals(T x, T y);
      public abstract int GetHashCode(T obj);
      bool IEqualityComparer.Equals(object x, object y) { return true; }
      int IEqualityComparer.GetHashCode(object obj) { return 0; }
 
      // Properties
      public static EqualityComparer<T> Default { get { return null; } }
  }
}
");
 
        /// <summary>
        /// Bug#15914: Breaking Changes
        /// </summary>
        [Fact, WorkItem(530365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530365")]
        public void NoStdLibNoEmitToStringForAnonymousType()
        {
            var source = @"
class Program
{
    static int Main()
    {
        var t = new { Test = 1 };
        return 0;
    }
}";
 
            // Dev11: omits methods that are not defined on Object (see also Dev10 bug 487707)
            // Roslyn: we require Equals, ToString, GetHashCode, Format to be defined
 
            var comp = CreateEmptyCompilation(new[] { Parse(source), s_equalityComparerSourceTree }, new[] { MinCorlibRef });
            var result = comp.Emit(new MemoryStream());
 
            result.Diagnostics.Verify(
                // error CS0656: Missing compiler required member 'System.Object.Equals'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "Equals"),
                // error CS0656: Missing compiler required member 'System.Object.ToString'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "ToString"),
                // error CS0656: Missing compiler required member 'System.Object.GetHashCode'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "GetHashCode"),
                // error CS0656: Missing compiler required member 'System.String.Format'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.String", "Format"));
        }
 
        [Fact, WorkItem(530365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530365")]
        public void NoDebuggerBrowsableStateType()
        {
            var stateSource = @"
namespace System.Diagnostics
{
    public enum DebuggerBrowsableState
    {
        Collapsed = 2,
        Never = 0,
        RootHidden = 3
    }
}
";
            var stateLib = CreateEmptyCompilation(stateSource, new[] { MinCorlibRef });
 
            var attributeSource = @"
namespace System.Diagnostics
{
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false)]
    public sealed class DebuggerBrowsableAttribute : Attribute
    {
        public DebuggerBrowsableAttribute(DebuggerBrowsableState state)
        {
        }
    }
}
";
            var attributeLib = CreateEmptyCompilation(attributeSource, new[] { MinCorlibRef, stateLib.ToMetadataReference() });
 
            var source = @"
class Program
{
    static int Main()
    {
        var t = new { Test = 1 };
        return 0;
    }
}";
 
            var comp = CreateEmptyCompilation(new[] { Parse(source), s_equalityComparerSourceTree }, new[] { MinCorlibRef, attributeLib.ToMetadataReference() });
            var result = comp.Emit(new MemoryStream());
 
            result.Diagnostics.Verify(
                // error CS0656: Missing compiler required member 'System.Object.Equals'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "Equals"),
                // error CS0656: Missing compiler required member 'System.Object.ToString'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "ToString"),
                // error CS0656: Missing compiler required member 'System.Object.GetHashCode'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Object", "GetHashCode"),
                // error CS0656: Missing compiler required member 'System.String.Format'
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.String", "Format"));
        }
 
        [Fact]
        public void ConditionalAccessErrors()
        {
            var source = @"
 
class C
{
    int M() { return 0; }
 
    void Test()
    {
        C local = null;
        C[] array = null;
 
        var x1 = new { local?.M() };
        var x2 = new { array?[0] };
    }
}
";
 
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,24): error CS0746: Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.
                //         var x1 = new { local?.M() };
                Diagnostic(ErrorCode.ERR_InvalidAnonymousTypeMemberDeclarator, "local?.M()").WithLocation(12, 24),
                // (13,24): error CS0746: Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.
                //         var x2 = new { array?[0] };
                Diagnostic(ErrorCode.ERR_InvalidAnonymousTypeMemberDeclarator, "array?[0]").WithLocation(13, 24));
        }
 
        [ClrOnlyFact]
        [WorkItem(991505, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991505")]
        [WorkItem(199, "CodePlex")]
        public void Bug991505()
        {
            var source = @"
class C 
{
    C P { get { return null; } }
    int L { get { return 0; } } 
    int M { get { return 0; } } 
    int N { get { return 0; } } 
 
    void Test()
    {
        C local = null;
        C[] array = null;
 
        var x1 = new { local };
        var x2_1 = new { local.P };
        var x2_2 = new { local?.P };
        var x3_1 = new { local.L };
        var x3_2 = new { local?.L };
        var x4_1 = new { local.P.M };
        var x4_2 = new { local?.P.M };
        var x4_3 = new { local?.P?.M };
        var x5_1 = new { array[0].N };
        var x5_2 = new { array?[0].N };
    }
}
";
 
            CompileAndVerify(
                source,
                symbolValidator: module =>
                    TestAnonymousTypeSymbols(
                        module,
                        new TypeDescr() { FieldNames = new[] { "local" } },
                        new TypeDescr() { FieldNames = new[] { "P" } },
                        new TypeDescr() { FieldNames = new[] { "L" } },
                        new TypeDescr() { FieldNames = new[] { "M" } },
                        new TypeDescr() { FieldNames = new[] { "N" } }));
        }
 
        [ClrOnlyFact]
        public void CallingCreateAnonymousTypeDoesNotChangeIL()
        {
            var source = @"
class C
{
    public static void Main(string[] args)
    {
        var v = new { m1 = 1, m2 = true };
    }
}";
 
            var expectedIL = @"{
  // Code size        9 (0x9)
  .maxstack  2
  IL_0000:  ldc.i4.1
  IL_0001:  ldc.i4.1
  IL_0002:  newobj     ""<>f__AnonymousType0<int, bool>..ctor(int, bool)""
  IL_0007:  pop
  IL_0008:  ret
}";
 
            CompileAndVerify(source).VerifyIL("C.Main", expectedIL);
 
            var compilation = CreateCompilationWithMscorlib40(source);
            compilation.CreateAnonymousTypeSymbol(
                ImmutableArray.Create<ITypeSymbol>(compilation.GetSpecialType(SpecialType.System_Int32).GetPublicSymbol(), compilation.GetSpecialType(SpecialType.System_Boolean).GetPublicSymbol()),
                ImmutableArray.Create("m1", "m2"));
 
            this.CompileAndVerify(compilation).VerifyIL("C.Main", expectedIL);
        }
    }
}