// 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.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols
{
    public class AnonymousTypesSemanticsTests : CompilingTestBase
    {
        [Fact()]
        public void AnonymousTypeSymbols_Simple()
        {
            var source = @"
public class ClassA
{
    public struct SSS
    {
    }

    public static void Test1(int x)
    {
        object v1 = [# new
        {
            [# aa  #] = 1,
            [# BB  #] = """",
            [# CCC #] = new SSS()
        } #];

        object v2 = [# new
        {
            [# aa  #] = new SSS(),
            [# BB  #] = 123.456,
            [# CCC #] = [# new
            {
                (new ClassA()).[# aa  #],
                ClassA.[# BB  #],
                ClassA.[# CCC #]
            } #]
        } #];

        object v3 = [# new {} #];
        var v4 = [# new {} #];
    }

    public int aa
    {
        get { return 123; }
    }

    public const string BB = ""-=-=-"";

    public static SSS CCC = new SSS();
}";
            var data = Compile(source, 14);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, 2, 3);

            var info1 = GetAnonymousTypeInfoSummary(data, 4,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 3).Span,
                            5, 6, 7);

            var info2 = GetAnonymousTypeInfoSummary(data, 8,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 5).Span,
                            9, 10, 11);

            Assert.Equal("AnonymousTypePublicSymbol", info0.Type.GetSymbol().GetType().Name);
            Assert.False(((INamedTypeSymbol)info0.Type).IsSerializable);

            Assert.Equal(info0.Type, info2.Type);
            Assert.NotEqual(info0.Type, info1.Type);

            var info3 = GetAnonymousTypeInfoSummary(data, 12,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 7).Span);
            var info4 = GetAnonymousTypeInfoSummary(data, 13,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 8).Span);
            Assert.Equal(info3.Type, info4.Type);
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_Simple_OperationTree()
        {
            string source = @"
class ClassA
{
    public struct SSS
    {
    }

    public static void Test1(int x)
    /*<bind>*/{
        object v1 = new
        {
            aa = 1,
            BB = """",
            CCC = new SSS()
        };

        object v2 = new
        {
            aa = new SSS(),
            BB = 123.456,
            CCC = new
            {
                (new ClassA()).aa,
                ClassA.BB,
                ClassA.CCC
            }
        };

        object v3 = new { };
        var v4 = new { };
    }/*</bind>*/

    public int aa
    {
        get { return 123; }
    }

    public const string BB = ""-=-= -"";

    public static SSS CCC = new SSS();
}
";
            string expectedOperationTree = @"
IBlockOperation (4 statements, 4 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
  Locals: Local_1: System.Object v1
    Local_2: System.Object v2
    Local_3: System.Object v3
    Local_4: <empty anonymous type> v4
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'object v1 = ... };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'object v1 = ... }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: System.Object v1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'v1 = new ... }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= new ... }')
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'new ... }')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
                  Operand: 
                    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>) (Syntax: 'new ... }')
                      Initializers(3):
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'aa = 1')
                            Left: 
                              IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.aa { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'aa')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: """") (Syntax: 'BB = """"')
                            Left: 
                              IPropertyReferenceOperation: System.String <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.BB { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'BB')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ClassA.SSS) (Syntax: 'CCC = new SSS()')
                            Left: 
                              IPropertyReferenceOperation: ClassA.SSS <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.CCC { get; } (OperationKind.PropertyReference, Type: ClassA.SSS) (Syntax: 'CCC')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IObjectCreationOperation (Constructor: ClassA.SSS..ctor()) (OperationKind.ObjectCreation, Type: ClassA.SSS) (Syntax: 'new SSS()')
                                Arguments(0)
                                Initializer: 
                                  null
      Initializer: 
        null
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'object v2 = ... };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'object v2 = ... }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: System.Object v2) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'v2 = new ... }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= new ... }')
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'new ... }')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
                  Operand: 
                    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>) (Syntax: 'new ... }')
                      Initializers(3):
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ClassA.SSS) (Syntax: 'aa = new SSS()')
                            Left: 
                              IPropertyReferenceOperation: ClassA.SSS <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>.aa { get; } (OperationKind.PropertyReference, Type: ClassA.SSS) (Syntax: 'aa')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IObjectCreationOperation (Constructor: ClassA.SSS..ctor()) (OperationKind.ObjectCreation, Type: ClassA.SSS) (Syntax: 'new SSS()')
                                Arguments(0)
                                Initializer: 
                                  null
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Double, Constant: 123.456) (Syntax: 'BB = 123.456')
                            Left: 
                              IPropertyReferenceOperation: System.Double <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>.BB { get; } (OperationKind.PropertyReference, Type: System.Double) (Syntax: 'BB')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              ILiteralOperation (OperationKind.Literal, Type: System.Double, Constant: 123.456) (Syntax: '123.456')
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>) (Syntax: 'CCC = new ... }')
                            Left: 
                              IPropertyReferenceOperation: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>.CCC { get; } (OperationKind.PropertyReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>) (Syntax: 'CCC')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ClassA.SSS aa, System.Double BB, <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC> CCC>, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>) (Syntax: 'new ... }')
                                Initializers(3):
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: '(new ClassA()).aa')
                                      Left: 
                                        IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.aa { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: '(new ClassA()).aa')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IPropertyReferenceOperation: System.Int32 ClassA.aa { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: '(new ClassA()).aa')
                                          Instance Receiver: 
                                            IObjectCreationOperation (Constructor: ClassA..ctor()) (OperationKind.ObjectCreation, Type: ClassA) (Syntax: 'new ClassA()')
                                              Arguments(0)
                                              Initializer: 
                                                null
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: ""-=-= -"", IsImplicit) (Syntax: 'ClassA.BB')
                                      Left: 
                                        IPropertyReferenceOperation: System.String <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.BB { get; } (OperationKind.PropertyReference, Type: System.String, IsImplicit) (Syntax: 'ClassA.BB')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IFieldReferenceOperation: System.String ClassA.BB (Static) (OperationKind.FieldReference, Type: System.String, Constant: ""-=-= -"") (Syntax: 'ClassA.BB')
                                          Instance Receiver: 
                                            null
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ClassA.SSS, IsImplicit) (Syntax: 'ClassA.CCC')
                                      Left: 
                                        IPropertyReferenceOperation: ClassA.SSS <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>.CCC { get; } (OperationKind.PropertyReference, Type: ClassA.SSS, IsImplicit) (Syntax: 'ClassA.CCC')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String BB, ClassA.SSS CCC>, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IFieldReferenceOperation: ClassA.SSS ClassA.CCC (Static) (OperationKind.FieldReference, Type: ClassA.SSS) (Syntax: 'ClassA.CCC')
                                          Instance Receiver: 
                                            null
      Initializer: 
        null
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'object v3 = new { };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'object v3 = new { }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: System.Object v3) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'v3 = new { }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= new { }')
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'new { }')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
                  Operand: 
                    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
                      Initializers(0)
      Initializer: 
        null
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'var v4 = new { };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'var v4 = new { }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: <empty anonymous type> v4) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'v4 = new { }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= new { }')
                IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
                  Initializers(0)
      Initializer: 
        null
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_ContextualKeywordsInFields()
        {
            var source = @"
class ClassA
{
    static void Test1(int x)
    {
        object v1 = [# new
        {
            [# var #] = ""var"",
            [# get #] = new {},
            [# partial #] = [# new
                            {
                                (new ClassA()).[# select #],
                                [# global  #]
                            } #]
        } #];
    }

    public int select
    {
        get { return 123; }
    }

    public const string global = ""-=-=-"";
}";
            var data = Compile(source, 7);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, 2, 3);

            var info1 = GetAnonymousTypeInfoSummary(data, 4,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 3).Span,
                            5, 6);

            Assert.Equal(
                "<anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>",
                info0.Type.ToTestDisplayString());

            Assert.Equal(
                "<anonymous type: System.Int32 select, System.String global>..ctor(System.Int32 select, System.String global)",
                info1.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_ContextualKeywordsInFields_OperationTree()
        {
            string source = @"
class ClassA
{
    static void Test1(int x)
    {
        object v1 = /*<bind>*/new
        {
            var = ""var"",
            get = new { },
            partial = new
            {
                (new ClassA()).select,
                global
            }
        }/*</bind>*/;
    }

    public int select
    {
        get { return 123; }
    }

    public const string global = "" -=-= -"";
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>) (Syntax: 'new ... }')
  Initializers(3):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: ""var"") (Syntax: 'var = ""var""')
        Left: 
          IPropertyReferenceOperation: System.String <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>.var { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'var')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>, IsImplicit) (Syntax: 'new ... }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""var"") (Syntax: '""var""')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <empty anonymous type>) (Syntax: 'get = new { }')
        Left: 
          IPropertyReferenceOperation: <empty anonymous type> <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>.get { get; } (OperationKind.PropertyReference, Type: <empty anonymous type>) (Syntax: 'get')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>, IsImplicit) (Syntax: 'new ... }')
        Right: 
          IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
            Initializers(0)
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <anonymous type: System.Int32 select, System.String global>) (Syntax: 'partial = n ... }')
        Left: 
          IPropertyReferenceOperation: <anonymous type: System.Int32 select, System.String global> <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>.partial { get; } (OperationKind.PropertyReference, Type: <anonymous type: System.Int32 select, System.String global>) (Syntax: 'partial')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.String var, <empty anonymous type> get, <anonymous type: System.Int32 select, System.String global> partial>, IsImplicit) (Syntax: 'new ... }')
        Right: 
          IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 select, System.String global>) (Syntax: 'new ... }')
            Initializers(2):
                ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: '(new ClassA()).select')
                  Left: 
                    IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 select, System.String global>.select { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: '(new ClassA()).select')
                      Instance Receiver: 
                        IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 select, System.String global>, IsImplicit) (Syntax: 'new ... }')
                  Right: 
                    IPropertyReferenceOperation: System.Int32 ClassA.select { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: '(new ClassA()).select')
                      Instance Receiver: 
                        IObjectCreationOperation (Constructor: ClassA..ctor()) (OperationKind.ObjectCreation, Type: ClassA) (Syntax: 'new ClassA()')
                          Arguments(0)
                          Initializer: 
                            null
                ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: "" -=-= -"", IsImplicit) (Syntax: 'global')
                  Left: 
                    IPropertyReferenceOperation: System.String <anonymous type: System.Int32 select, System.String global>.global { get; } (OperationKind.PropertyReference, Type: System.String, IsImplicit) (Syntax: 'global')
                      Instance Receiver: 
                        IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 select, System.String global>, IsImplicit) (Syntax: 'new ... }')
                  Right: 
                    IFieldReferenceOperation: System.String ClassA.global (Static) (OperationKind.FieldReference, Type: System.String, Constant: "" -=-= -"") (Syntax: 'global')
                      Instance Receiver: 
                        null
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_DelegateMembers()
        {
            var source = @"
delegate bool D1();
class ClassA
{
    void Main()
    {
        var at1 = [# new { [# module #] = (D1)(() => false)} #].module();
    }
}";
            var data = Compile(source, 2);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1);

            Assert.Equal("<anonymous type: D1 module>", info0.Type.ToTestDisplayString());
            Assert.Equal("<anonymous type: D1 module>..ctor(D1 module)", info0.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_DelegateMembers_OperationTree()
        {
            string source = @"
delegate bool D1();
class ClassA
{
    void Main()
    {
        var at1 = /*<bind>*/new { module = (D1)(() => false) }/*</bind>*/.module();
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: D1 module>) (Syntax: 'new { modul ... => false) }')
  Initializers(1):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: D1) (Syntax: 'module = (D ... ) => false)')
        Left: 
          IPropertyReferenceOperation: D1 <anonymous type: D1 module>.module { get; } (OperationKind.PropertyReference, Type: D1) (Syntax: 'module')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: D1 module>, IsImplicit) (Syntax: 'new { modul ... => false) }')
        Right: 
          IDelegateCreationOperation (OperationKind.DelegateCreation, Type: D1) (Syntax: '(D1)(() => false)')
            Target: 
              IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: '() => false')
                IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'false')
                  IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'false')
                    ReturnedValue: 
                      ILiteralOperation (OperationKind.Literal, Type: System.Boolean, Constant: False) (Syntax: 'false')
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_BaseAccessInMembers()
        {
            var source = @"
delegate bool D1();
class ClassB
{
    protected System.Func<int, int> F = x => x;
}
class ClassA: ClassB
{
    void Main()
    {
        var at1 = [# [# new { base.[# F #] } #].F(1) #];
    }
}";
            var data = Compile(source, 3);

            var info0 = GetAnonymousTypeInfoSummary(data, 1,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            2);

            Assert.Equal("<anonymous type: System.Func<System.Int32, System.Int32> F>", info0.Type.ToTestDisplayString());

            var info1 = data.Model.GetSemanticInfoSummary(data.Nodes[0]);

            Assert.Equal("System.Int32 System.Func<System.Int32, System.Int32>.Invoke(System.Int32 arg)", info1.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_BaseAccessInMembers_OperationTree()
        {
            string source = @"
delegate bool D1();
class ClassB
{
    protected System.Func<int, int> F = x => x;
}
class ClassA : ClassB
{
    void Main()
    {
        var at1 = /*<bind>*/new { base.F }/*</bind>*/.F(1);
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Func<System.Int32, System.Int32> F>) (Syntax: 'new { base.F }')
  Initializers(1):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func<System.Int32, System.Int32>, IsImplicit) (Syntax: 'base.F')
        Left: 
          IPropertyReferenceOperation: System.Func<System.Int32, System.Int32> <anonymous type: System.Func<System.Int32, System.Int32> F>.F { get; } (OperationKind.PropertyReference, Type: System.Func<System.Int32, System.Int32>, IsImplicit) (Syntax: 'base.F')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Func<System.Int32, System.Int32> F>, IsImplicit) (Syntax: 'new { base.F }')
        Right: 
          IFieldReferenceOperation: System.Func<System.Int32, System.Int32> ClassB.F (OperationKind.FieldReference, Type: System.Func<System.Int32, System.Int32>) (Syntax: 'base.F')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: ClassB) (Syntax: 'base')
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_InFieldInitializer()
        {
            var source = @"
class ClassA
{
    private static object F = [# new { [# F123 #] = typeof(ClassA) } #];
}";
            var data = Compile(source, 2);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1);

            Assert.Equal("<anonymous type: System.Type F123>", info0.Type.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_InFieldInitializer_OperationTree()
        {
            string source = @"
class ClassA
{
    private static object F = /*<bind>*/new { F123 = typeof(ClassA) }/*</bind>*/;
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Type F123>) (Syntax: 'new { F123  ... f(ClassA) }')
  Initializers(1):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Type) (Syntax: 'F123 = typeof(ClassA)')
        Left: 
          IPropertyReferenceOperation: System.Type <anonymous type: System.Type F123>.F123 { get; } (OperationKind.PropertyReference, Type: System.Type) (Syntax: 'F123')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Type F123>, IsImplicit) (Syntax: 'new { F123  ... f(ClassA) }')
        Right: 
          ITypeOfOperation (OperationKind.TypeOf, Type: System.Type) (Syntax: 'typeof(ClassA)')
            TypeOperand: ClassA
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_Equals()
        {
            var source = @"
class ClassA
{
    static void Test1(int x)
    {
        bool result = [# new { f1 = 1, f2 = """" }.Equals(new { }) #];
    }
}";
            var data = Compile(source, 1);

            var info = data.Model.GetSemanticInfoSummary(data.Nodes[0]);

            var method = info.Symbol;
            Assert.NotNull(method);
            Assert.Equal(SymbolKind.Method, method.Kind);
            Assert.Equal("object.Equals(object)", method.ToDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_Equals_OperationTree()
        {
            string source = @"
class ClassA
{
    static void Test1(int x)
    {
        bool result = /*<bind>*/new { f1 = 1, f2 = """" }.Equals(new { })/*</bind>*/;
    }
}
";
            string expectedOperationTree = @"
IInvocationOperation (virtual System.Boolean System.Object.Equals(System.Object obj)) (OperationKind.Invocation, Type: System.Boolean) (Syntax: 'new { f1 =  ... ls(new { })')
  Instance Receiver: 
    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 f1, System.String f2>) (Syntax: 'new { f1 = 1, f2 = """" }')
      Initializers(2):
          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'f1 = 1')
            Left: 
              IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 f1, System.String f2>.f1 { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'f1')
                Instance Receiver: 
                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 f1, System.String f2>, IsImplicit) (Syntax: 'new { f1 = 1, f2 = """" }')
            Right: 
              ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: """") (Syntax: 'f2 = """"')
            Left: 
              IPropertyReferenceOperation: System.String <anonymous type: System.Int32 f1, System.String f2>.f2 { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'f2')
                Instance Receiver: 
                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 f1, System.String f2>, IsImplicit) (Syntax: 'new { f1 = 1, f2 = """" }')
            Right: 
              ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
  Arguments(1):
      IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: obj) (OperationKind.Argument, Type: null) (Syntax: 'new { }')
        IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'new { }')
          Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
          Operand: 
            IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
              Initializers(0)
        InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
        OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<InvocationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_ToString()
        {
            var source = @"
class ClassA
{
    static void Test1(int x)
    {
        string result = [# new { f1 = 1, f2 = """" }.ToString() #];
    }
}";
            var data = Compile(source, 1);

            var info = data.Model.GetSemanticInfoSummary(data.Nodes[0]);

            var method = info.Symbol;
            Assert.NotNull(method);
            Assert.Equal(SymbolKind.Method, method.Kind);
            Assert.Equal("object.ToString()", method.ToDisplayString());
        }

        [Fact()]
        public void AnonymousTypeSymbols_GetHashCode()
        {
            var source = @"
class ClassA
{
    static void Test1(int x)
    {
        int result = [# new { f1 = 1, f2 = """" }.GetHashCode() #];
    }
}";
            var data = Compile(source, 1);

            var info = data.Model.GetSemanticInfoSummary(data.Nodes[0]);

            var method = info.Symbol;
            Assert.NotNull(method);
            Assert.Equal(SymbolKind.Method, method.Kind);
            Assert.Equal("object.GetHashCode()", method.ToDisplayString());
        }

        [Fact()]
        public void AnonymousTypeSymbols_Ctor()
        {
            var source = @"
class ClassA
{
    static void Test1(int x)
    {
        var result = [# new { f1 = 1, f2 = """" } #];
    }
}";
            var data = Compile(source, 1);

            var info = data.Model.GetSemanticInfoSummary(data.Nodes[0]);

            var method = info.Symbol;
            Assert.NotNull(method);
            Assert.Equal(SymbolKind.Method, method.Kind);
            Assert.Equal("<anonymous type: int f1, string f2>..ctor(int, string)", method.ToDisplayString());
            Assert.Equal("<anonymous type: System.Int32 f1, System.String f2>..ctor(System.Int32 f1, System.String f2)", method.ToTestDisplayString());
        }

        [Fact()]
        public void AnonymousTypeTemplateCannotConstruct()
        {
            var source = @"
class ClassA
{
    object F = [# new { [# F123 #] = typeof(ClassA) } #];
}";
            var data = Compile(source, 2);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1);

            var type = info0.Type;
            Assert.Equal("<anonymous type: System.Type F123>", type.ToTestDisplayString());
            Assert.True(type.IsDefinition);
            AssertCannotConstruct(type);
        }

        [Fact()]
        public void AnonymousTypeTemplateCannotConstruct_Empty()
        {
            var source = @"
class ClassA
{
    object F = [# new { } #];
}";
            var data = Compile(source, 1);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span);

            var type = info0.Type;
            Assert.Equal("<empty anonymous type>", type.ToTestDisplayString());
            Assert.True(type.IsDefinition);
            AssertCannotConstruct(type);
        }

        [Fact()]
        public void AnonymousTypeFieldDeclarationIdentifier()
        {
            var source = @"
class ClassA
{
    object F = new { [# F123 #] = typeof(ClassA) };
}";
            var data = Compile(source, 1);
            var info = data.Model.GetSymbolInfo((ExpressionSyntax)data.Nodes[0]);
            Assert.NotNull(info.Symbol);
            Assert.Equal(SymbolKind.Property, info.Symbol.Kind);
            Assert.Equal("System.Type <anonymous type: System.Type F123>.F123 { get; }", info.Symbol.ToTestDisplayString());
        }

        [Fact()]
        public void AnonymousTypeFieldCreatedInQuery()
        {
            var source = LINQ + @"
class ClassA
{
    void m()
    {
        var o = from x in new List1<int>(1, 2, 3) select [# new { [# x #], [# y #] = x } #];
    }
}";
            var data = Compile(source, 3);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, NumberOfNewKeywords(LINQ) + 2).Span,
                1, 2);

            var info1 = data.Model.GetSymbolInfo(((AnonymousObjectMemberDeclaratorSyntax)data.Nodes[1]).Expression);
            Assert.NotNull(info1.Symbol);
            Assert.Equal(SymbolKind.RangeVariable, info1.Symbol.Kind);
            Assert.Equal("x", info1.Symbol.ToDisplayString());

            var info2 = data.Model.GetSymbolInfo((ExpressionSyntax)data.Nodes[2]);
            Assert.NotNull(info2.Symbol);
            Assert.Equal(SymbolKind.Property, info2.Symbol.Kind);
            Assert.Equal("System.Int32 <anonymous type: System.Int32 x, System.Int32 y>.y { get; }", info2.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeFieldCreatedInQuery_OperationTree()
        {
            string source = @"
using System.Collections.Generic;
using System.Linq;

class ClassA
{
    void m()
    {
        var o = from x in new List<int>() { 1, 2, 3 } select /*<bind>*/new { x, y = x }/*</bind>*/;
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 x, System.Int32 y>) (Syntax: 'new { x, y = x }')
  Initializers(2):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'x')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, System.Int32 y>.x { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'x')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, System.Int32 y>, IsImplicit) (Syntax: 'new { x, y = x }')
        Right: 
          IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32) (Syntax: 'y = x')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, System.Int32 y>.y { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'y')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, System.Int32 y>, IsImplicit) (Syntax: 'new { x, y = x }')
        Right: 
          IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x')
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeFieldCreatedInQuery2()
        {
            var source = LINQ + @"
class ClassA
{
    void m()
    {
        var o = from x in new List1<int>(1, 2, 3) let y = """" select [# new { [# x #], [# y #] } #];
    }
}";
            var data = Compile(source, 3);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, NumberOfNewKeywords(LINQ) + 2).Span,
                1, 2);

            Assert.Equal("<anonymous type: System.Int32 x, System.String y>", info0.Type.ToTestDisplayString());

            var info1 = data.Model.GetSymbolInfo(((AnonymousObjectMemberDeclaratorSyntax)data.Nodes[1]).Expression);
            Assert.NotNull(info1.Symbol);
            Assert.Equal(SymbolKind.RangeVariable, info1.Symbol.Kind);
            Assert.Equal("x", info1.Symbol.ToDisplayString());

            var info2 = data.Model.GetSymbolInfo(((AnonymousObjectMemberDeclaratorSyntax)data.Nodes[2]).Expression);
            Assert.NotNull(info2.Symbol);
            Assert.Equal(SymbolKind.RangeVariable, info2.Symbol.Kind);
            Assert.Equal("y", info2.Symbol.ToDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeFieldCreatedInQuery2_OperationTree()
        {
            string source = @"
using System.Collections.Generic;
using System.Linq;

class ClassA
{
    void m()
    {
        var o = from x in new List<int>() { 1, 2, 3 } let y = """" select /*<bind>*/new { x, y }/*</bind>*/;
    }
}
";
            // OperationKind.None is for Range variables, IOperation support for it is NYI.
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 x, System.String y>) (Syntax: 'new { x, y }')
  Initializers(2):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'x')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, System.String y>.x { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'x')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, System.String y>, IsImplicit) (Syntax: 'new { x, y }')
        Right: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, System.String y>.x { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'x')
            Instance Receiver: 
              IParameterReferenceOperation: <>h__TransparentIdentifier0 (OperationKind.ParameterReference, Type: <anonymous type: System.Int32 x, System.String y>, IsImplicit) (Syntax: 'x')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, IsImplicit) (Syntax: 'y')
        Left: 
          IPropertyReferenceOperation: System.String <anonymous type: System.Int32 x, System.String y>.y { get; } (OperationKind.PropertyReference, Type: System.String, IsImplicit) (Syntax: 'y')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, System.String y>, IsImplicit) (Syntax: 'new { x, y }')
        Right: 
          IPropertyReferenceOperation: System.String <anonymous type: System.Int32 x, System.String y>.y { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'y')
            Instance Receiver: 
              IParameterReferenceOperation: <>h__TransparentIdentifier0 (OperationKind.ParameterReference, Type: <anonymous type: System.Int32 x, System.String y>, IsImplicit) (Syntax: 'y')
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeFieldCreatedInLambda()
        {
            var source = @"
using System;
class ClassA
{
    void m()
    {
        var o = (Action)(() => ( [# new { [# x #] = 1, [# y #] = [# new { } #] } #]).ToString());;
    }
}";
            var data = Compile(source, 4);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                1, 2);

            var info1 = GetAnonymousTypeInfoSummary(data, 3,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 2).Span);

            Assert.Equal("<anonymous type: System.Int32 x, <empty anonymous type> y>..ctor(System.Int32 x, <empty anonymous type> y)", info0.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeFieldCreatedInLambda_OperationTree()
        {
            string source = @"
using System;
class ClassA
{
    void m()
    {
        var o = (Action)(() => (/*<bind>*/new { x = 1, y = new { } }/*</bind>*/).ToString()); ;
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>) (Syntax: 'new { x = 1 ... = new { } }')
  Initializers(2):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'x = 1')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, <empty anonymous type> y>.x { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'x')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>, IsImplicit) (Syntax: 'new { x = 1 ... = new { } }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <empty anonymous type>) (Syntax: 'y = new { }')
        Left: 
          IPropertyReferenceOperation: <empty anonymous type> <anonymous type: System.Int32 x, <empty anonymous type> y>.y { get; } (OperationKind.PropertyReference, Type: <empty anonymous type>) (Syntax: 'y')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>, IsImplicit) (Syntax: 'new { x = 1 ... = new { } }')
        Right: 
          IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
            Initializers(0)
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeFieldCreatedInLambda2()
        {
            var source = @"
using System;
class ClassA
{
    void m()
    {
        var o = (Action)
                    (() =>
                        ((Func<string>) (() => ( [# new { [# x #] = 1, [# y #] = [# new { } #] } #]).ToString())
                    ).Invoke());
    }
}";
            var data = Compile(source, 4);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                1, 2);

            var info1 = GetAnonymousTypeInfoSummary(data, 3,
                data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 2).Span);

            Assert.Equal("<anonymous type: System.Int32 x, <empty anonymous type> y>..ctor(System.Int32 x, <empty anonymous type> y)", info0.Symbol.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeFieldCreatedInLambda2_OperationTree()
        {
            string source = @"
using System;
class ClassA
{
    void m()
    {
        var o = (Action)
                    (() =>
                        ((Func<string>)(() => (/*<bind>*/new { x = 1, y = new { } }/*</bind>*/).ToString())
                    ).Invoke());
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>) (Syntax: 'new { x = 1 ... = new { } }')
  Initializers(2):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'x = 1')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 x, <empty anonymous type> y>.x { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'x')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>, IsImplicit) (Syntax: 'new { x = 1 ... = new { } }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <empty anonymous type>) (Syntax: 'y = new { }')
        Left: 
          IPropertyReferenceOperation: <empty anonymous type> <anonymous type: System.Int32 x, <empty anonymous type> y>.y { get; } (OperationKind.PropertyReference, Type: <empty anonymous type>) (Syntax: 'y')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 x, <empty anonymous type> y>, IsImplicit) (Syntax: 'new { x = 1 ... = new { } }')
        Right: 
          IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>) (Syntax: 'new { }')
            Initializers(0)
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [ClrOnlyFact]
        public void AnonymousTypeSymbols_DontCrashIfNameIsQueriedBeforeEmit()
        {
            var source = @"
public class ClassA
{
    public static void Test1(int x)
    {
        object v1 = [# new { [# aa  #] = 1, [# BB  #] = 2 } #];
        object v2 = [# new { } #];
    }
}";
            var data = Compile(source, 4);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, 2);

            CheckAnonymousType(info0.Type, "", "");

            info0 = GetAnonymousTypeInfoSummary(data, 3,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 2).Span);

            CheckAnonymousType(info0.Type, "", "");

            //  perform emit
            CompileAndVerify(
                data.Compilation,
                symbolValidator: module => CheckAnonymousTypes(module)
            );
        }

        #region "AnonymousTypeSymbols_DontCrashIfNameIsQueriedBeforeEmit"

        private static void CheckAnonymousType(TypeSymbol type, string name, string metadataName)
        {
            Assert.NotNull(type);
            Assert.Equal(name, type.Name);
            Assert.Equal(metadataName, type.MetadataName);
        }

        private static void CheckAnonymousType(ITypeSymbol type, string name, string metadataName)
        {
            Assert.NotNull(type);
            Assert.Equal(name, type.Name);
            Assert.Equal(metadataName, type.MetadataName);
        }

        private void CheckAnonymousTypes(ModuleSymbol module)
        {
            var ns = module.GlobalNamespace;
            Assert.NotNull(ns);

            CheckAnonymousType(ns.GetMember<NamedTypeSymbol>("<>f__AnonymousType0"), "<>f__AnonymousType0", "<>f__AnonymousType0`2");
            CheckAnonymousType(ns.GetMember<NamedTypeSymbol>("<>f__AnonymousType1"), "<>f__AnonymousType1", "<>f__AnonymousType1");
        }

        #endregion

        [Fact()]
        public void AnonymousTypeSymbols_Error_Simple()
        {
            var source = @"
public class ClassA
{
    public static void Test1(int x)
    {
        object v1 = [# new
        {
            [# aa  #] = xyz,
            [# BB  #] = """",
            [# CCC #] = new SSS()
        } #];

        object v2 = [# new
        {
            [# aa  #] = new SSS(),
            [# BB  #] = 123.456,
            [# CCC #] = [# new
            {
                (new ClassA()).[# aa  #],
                ClassA.[# BB  #],
                ClassA.[# CCC #]
            } #]
        } #];
    }
}";
            var data = Compile(source, 12,
                // (8,25): error CS0103: The name 'xyz' does not exist in the current context
                //                aa     = xyz,
                Diagnostic(ErrorCode.ERR_NameNotInContext, "xyz").WithArguments("xyz"),
                // (10,29): error CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?)
                //                CCC    = new SSS()
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS"),
                // (15,29): error CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?)
                //                aa     = new SSS(),
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS"),
                // (19,35): error CS1061: 'ClassA' does not contain a definition for 'aa' and no extension method 'aa' accepting a first argument of type 'ClassA' could be found (are you missing a using directive or an assembly reference?)
                //                 (new ClassA()).   aa    ,
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "aa").WithArguments("ClassA", "aa"),
                // (20,27): error CS0117: 'ClassA' does not contain a definition for 'BB'
                //                 ClassA.   BB    ,
                Diagnostic(ErrorCode.ERR_NoSuchMember, "BB").WithArguments("ClassA", "BB"),
                // (21,27): error CS0117: 'ClassA' does not contain a definition for 'CCC'
                //                 ClassA.   CCC   
                Diagnostic(ErrorCode.ERR_NoSuchMember, "CCC").WithArguments("ClassA", "CCC")
            );

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, 2, 3);

            var info1 = GetAnonymousTypeInfoSummary(data, 4,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 3).Span,
                            5, 6, 7);

            var info2 = GetAnonymousTypeInfoSummary(data, 8,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 5).Span,
                            9, 10, 11);

            Assert.Equal("<anonymous type: ? aa, System.String BB, SSS CCC>", info0.Type.ToTestDisplayString());
            Assert.Equal("<anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>", info1.Type.ToTestDisplayString());
            Assert.Equal("<anonymous type: ? aa, ? BB, ? CCC>", info2.Type.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_Error_Simple_OperationTree()
        {
            string source = @"
class ClassA
{
    public static void Test1(int x)
    /*<bind>*/{
        object v1 = new
        {
            aa = xyz,
            BB = """",
            CCC = new SSS()
        };

        object v2 = new
        {
            aa = new SSS(),
            BB = 123.456,
            CCC = new
            {
                (new ClassA()).aa,
                ClassA.BB,
                ClassA.CCC
            }
        };
    }/*</bind>*/
}
";
            string expectedOperationTree = @"
IBlockOperation (2 statements, 2 locals) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }')
  Locals: Local_1: System.Object v1
    Local_2: System.Object v2
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null, IsInvalid) (Syntax: 'object v1 = ... };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'object v1 = ... }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: System.Object v1) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 'v1 = new ... }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= new ... }')
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
                  Operand: 
                    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: ? aa, System.String BB, SSS CCC>, IsInvalid) (Syntax: 'new ... }')
                      Initializers(3):
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ?, IsInvalid) (Syntax: 'aa = xyz')
                            Left: 
                              IPropertyReferenceOperation: ? <anonymous type: ? aa, System.String BB, SSS CCC>.aa { get; } (OperationKind.PropertyReference, Type: ?) (Syntax: 'aa')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, System.String BB, SSS CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'xyz')
                                Children(0)
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, Constant: """") (Syntax: 'BB = """"')
                            Left: 
                              IPropertyReferenceOperation: System.String <anonymous type: ? aa, System.String BB, SSS CCC>.BB { get; } (OperationKind.PropertyReference, Type: System.String) (Syntax: 'BB')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, System.String BB, SSS CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: SSS, IsInvalid) (Syntax: 'CCC = new SSS()')
                            Left: 
                              IPropertyReferenceOperation: SSS <anonymous type: ? aa, System.String BB, SSS CCC>.CCC { get; } (OperationKind.PropertyReference, Type: SSS) (Syntax: 'CCC')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, System.String BB, SSS CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IInvalidOperation (OperationKind.Invalid, Type: SSS, IsInvalid) (Syntax: 'new SSS()')
                                Children(0)
      Initializer: 
        null
  IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null, IsInvalid) (Syntax: 'object v2 = ... };')
    IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'object v2 = ... }')
      Declarators:
          IVariableDeclaratorOperation (Symbol: System.Object v2) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 'v2 = new ... }')
            Initializer: 
              IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= new ... }')
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
                  Operand: 
                    IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>, IsInvalid) (Syntax: 'new ... }')
                      Initializers(3):
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: SSS, IsInvalid) (Syntax: 'aa = new SSS()')
                            Left: 
                              IPropertyReferenceOperation: SSS <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>.aa { get; } (OperationKind.PropertyReference, Type: SSS) (Syntax: 'aa')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IInvalidOperation (OperationKind.Invalid, Type: SSS, IsInvalid) (Syntax: 'new SSS()')
                                Children(0)
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Double, Constant: 123.456) (Syntax: 'BB = 123.456')
                            Left: 
                              IPropertyReferenceOperation: System.Double <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>.BB { get; } (OperationKind.PropertyReference, Type: System.Double) (Syntax: 'BB')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              ILiteralOperation (OperationKind.Literal, Type: System.Double, Constant: 123.456) (Syntax: '123.456')
                          ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <anonymous type: ? aa, ? BB, ? CCC>, IsInvalid) (Syntax: 'CCC = new ... }')
                            Left: 
                              IPropertyReferenceOperation: <anonymous type: ? aa, ? BB, ? CCC> <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>.CCC { get; } (OperationKind.PropertyReference, Type: <anonymous type: ? aa, ? BB, ? CCC>) (Syntax: 'CCC')
                                Instance Receiver: 
                                  IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: SSS aa, System.Double BB, <anonymous type: ? aa, ? BB, ? CCC> CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                            Right: 
                              IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: ? aa, ? BB, ? CCC>, IsInvalid) (Syntax: 'new ... }')
                                Initializers(3):
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ?, IsInvalid, IsImplicit) (Syntax: '(new ClassA()).aa')
                                      Left: 
                                        IPropertyReferenceOperation: ? <anonymous type: ? aa, ? BB, ? CCC>.aa { get; } (OperationKind.PropertyReference, Type: ?, IsInvalid, IsImplicit) (Syntax: '(new ClassA()).aa')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, ? BB, ? CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: '(new ClassA()).aa')
                                          Children(1):
                                              IObjectCreationOperation (Constructor: ClassA..ctor()) (OperationKind.ObjectCreation, Type: ClassA) (Syntax: 'new ClassA()')
                                                Arguments(0)
                                                Initializer: 
                                                  null
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ?, IsInvalid, IsImplicit) (Syntax: 'ClassA.BB')
                                      Left: 
                                        IPropertyReferenceOperation: ? <anonymous type: ? aa, ? BB, ? CCC>.BB { get; } (OperationKind.PropertyReference, Type: ?, IsInvalid, IsImplicit) (Syntax: 'ClassA.BB')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, ? BB, ? CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'ClassA.BB')
                                          Children(1):
                                              IOperation:  (OperationKind.None, Type: ClassA) (Syntax: 'ClassA')
                                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ?, IsInvalid, IsImplicit) (Syntax: 'ClassA.CCC')
                                      Left: 
                                        IPropertyReferenceOperation: ? <anonymous type: ? aa, ? BB, ? CCC>.CCC { get; } (OperationKind.PropertyReference, Type: ?, IsInvalid, IsImplicit) (Syntax: 'ClassA.CCC')
                                          Instance Receiver: 
                                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: ? aa, ? BB, ? CCC>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
                                      Right: 
                                        IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'ClassA.CCC')
                                          Children(1):
                                              IOperation:  (OperationKind.None, Type: ClassA) (Syntax: 'ClassA')
      Initializer: 
        null
";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // CS0103: The name 'xyz' does not exist in the current context
                //             aa = xyz,
                Diagnostic(ErrorCode.ERR_NameNotInContext, "xyz").WithArguments("xyz").WithLocation(8, 18),
                // CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?)
                //             CCC = new SSS()
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS").WithLocation(10, 23),
                // CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?)
                //             aa = new SSS(),
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS").WithLocation(15, 22),
                // CS1061: 'ClassA' does not contain a definition for 'aa' and no extension method 'aa' accepting a first argument of type 'ClassA' could be found (are you missing a using directive or an assembly reference?)
                //                 (new ClassA()).aa,
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "aa").WithArguments("ClassA", "aa").WithLocation(19, 32),
                // CS0117: 'ClassA' does not contain a definition for 'BB'
                //                 ClassA.BB,
                Diagnostic(ErrorCode.ERR_NoSuchMember, "BB").WithArguments("ClassA", "BB").WithLocation(20, 24),
                // CS0117: 'ClassA' does not contain a definition for 'CCC'
                //                 ClassA.CCC
                Diagnostic(ErrorCode.ERR_NoSuchMember, "CCC").WithArguments("ClassA", "CCC").WithLocation(21, 24)
            };

            VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_Error_InUsingStatement()
        {
            var source = @"
public class ClassA
{
    public static void Test1(int x)
    {
        using (var v1 = [# new { } #])
        {
        }
    }
}";
            var data = Compile(source, 1,
                // (6,16): error CS1674: '<empty anonymous type>': type used in a using statement must implement 'System.IDisposable'.
                //         using (var v1 =    new { }   )
                Diagnostic(ErrorCode.ERR_NoConvToIDisp, "var v1 =    new { }").WithArguments("<empty anonymous type>")
            );

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span);

            Assert.Equal("<empty anonymous type>", info0.Type.ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void AnonymousTypeSymbols_Error_InUsingStatement_OperationTree()
        {
            string source = @"
class ClassA
{
    public static void Test1(int x)
    {
        using (/*<bind>*/var v1 = new { }/*</bind>*/)
        {
        }
    }
}
";
            string expectedOperationTree = @"
IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'var v1 = new { }')
  Declarators:
      IVariableDeclaratorOperation (Symbol: <empty anonymous type> v1) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 'v1 = new { }')
        Initializer: 
          IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= new { }')
            IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <empty anonymous type>, IsInvalid) (Syntax: 'new { }')
              Initializers(0)
  Initializer: 
    null";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // CS1674: '<empty anonymous type>': type used in a using statement must implement 'System.IDisposable'.
                //         using (/*<bind>*/var v1 = new { }/*</bind>*/)
                Diagnostic(ErrorCode.ERR_NoConvToIDisp, "var v1 = new { }").WithArguments("<empty anonymous type>").WithLocation(6, 26)
            };

            VerifyOperationTreeAndDiagnosticsForTest<VariableDeclarationSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_Error_DuplicateName()
        {
            var source = @"
public class ClassA
{
    public static void Test1(int x)
    {
        object v1 = [# new
        {
            [# aa  #] = 1,
            ClassA.[# aa #],
            [# bb #] = 1.2
        } #];
    }

    public static string aa = ""-field-aa-"";
}";
            var data = Compile(source, 4,
                // (9,13): error CS0833: An anonymous type cannot have multiple properties with the same name
                //             ClassA.   aa   ,
                Diagnostic(ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, "ClassA.   aa")
            );

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, /*2,*/ 3);

            Assert.Equal("<anonymous type: System.Int32 aa, System.String $1, System.Double bb>", info0.Type.ToTestDisplayString());

            var properties = (from m in info0.Type.GetMembers() where m.Kind == SymbolKind.Property select m).ToArray();
            Assert.Equal(3, properties.Length);

            Assert.Equal("System.Int32 <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.aa { get; }", properties[0].ToTestDisplayString());
            Assert.Equal("System.String <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.$1 { get; }", properties[1].ToTestDisplayString());
            Assert.Equal("System.Double <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.bb { get; }", properties[2].ToTestDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact, WorkItem(20338, "https://github.com/dotnet/roslyn/issues/20338")]
        public void AnonymousTypeSymbols_Error_DuplicateName_OperationTree()
        {
            string source = @"
class ClassA
{
    public static void Test1(int x)
    {
        object v1 = /*<bind>*/new
        {
            aa = 1,
            ClassA.aa,
            bb = 1.2
        }/*</bind>*/;
    }

    public static string aa = ""-field-aa-"";
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 aa, System.String $1, System.Double bb>, IsInvalid) (Syntax: 'new ... }')
  Initializers(3):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'aa = 1')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.aa { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'aa')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String $1, System.Double bb>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ClassA.aa')
        Left: 
          IPropertyReferenceOperation: System.String <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.$1 { get; } (OperationKind.PropertyReference, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'ClassA.aa')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String $1, System.Double bb>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
        Right: 
          IFieldReferenceOperation: System.String ClassA.aa (Static) (OperationKind.FieldReference, Type: System.String, IsInvalid) (Syntax: 'ClassA.aa')
            Instance Receiver: 
              null
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Double, Constant: 1.2) (Syntax: 'bb = 1.2')
        Left: 
          IPropertyReferenceOperation: System.Double <anonymous type: System.Int32 aa, System.String $1, System.Double bb>.bb { get; } (OperationKind.PropertyReference, Type: System.Double) (Syntax: 'bb')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 aa, System.String $1, System.Double bb>, IsInvalid, IsImplicit) (Syntax: 'new ... }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Double, Constant: 1.2) (Syntax: '1.2')
";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // CS0833: An anonymous type cannot have multiple properties with the same name
                //             ClassA.aa,
                Diagnostic(ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, "ClassA.aa").WithLocation(9, 13)
            };

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact()]
        public void AnonymousTypeSymbols_LookupSymbols()
        {
            var source = @"
public class ClassA
{
    public static void Test1(int x)
    {
        object v1 = [# new
        {
            [# aa  #] = """",
            [# abc #] = 123.456
        } #];
        object v2 = [# new{ } #];
    }
}";
            var data = Compile(source, 4);

            var info0 = GetAnonymousTypeInfoSummary(data, 0,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 1).Span,
                            1, 2);

            Assert.Equal("<anonymous type: System.String aa, System.Double abc>", info0.Type.ToTestDisplayString());

            var pos = data.Nodes[0].Span.End;
            var syms = data.Model.LookupSymbols(pos, container: info0.Type).Select(x => x.ToTestDisplayString()).OrderBy(x => x).ToArray();
            Assert.Equal(8, syms.Length);

            int index = 0;
            Assert.Equal("System.Boolean System.Object.Equals(System.Object obj)", syms[index++]);
            Assert.Equal("System.Boolean System.Object.Equals(System.Object objA, System.Object objB)", syms[index++]);
            Assert.Equal("System.Boolean System.Object.ReferenceEquals(System.Object objA, System.Object objB)", syms[index++]);
            Assert.Equal("System.Double <anonymous type: System.String aa, System.Double abc>.abc { get; }", syms[index++]);
            Assert.Equal("System.Int32 System.Object.GetHashCode()", syms[index++]);
            Assert.Equal("System.String <anonymous type: System.String aa, System.Double abc>.aa { get; }", syms[index++]);
            Assert.Equal("System.String System.Object.ToString()", syms[index++]);
            Assert.Equal("System.Type System.Object.GetType()", syms[index++]);

            info0 = GetAnonymousTypeInfoSummary(data, 3,
                            data.Tree.FindNodeOrTokenByKind(SyntaxKind.NewKeyword, 2).Span);

            Assert.Equal("<empty anonymous type>", info0.Type.ToTestDisplayString());

            pos = data.Nodes[3].Span.End;
            syms = data.Model.LookupSymbols(pos, container: info0.Type).Select(x => x.ToTestDisplayString()).OrderBy(x => x).ToArray();
            Assert.Equal(6, syms.Length);

            index = 0;
            Assert.Equal("System.Boolean System.Object.Equals(System.Object obj)", syms[index++]);
            Assert.Equal("System.Boolean System.Object.Equals(System.Object objA, System.Object objB)", syms[index++]);
            Assert.Equal("System.Boolean System.Object.ReferenceEquals(System.Object objA, System.Object objB)", syms[index++]);
            Assert.Equal("System.Int32 System.Object.GetHashCode()", syms[index++]);
            Assert.Equal("System.String System.Object.ToString()", syms[index++]);
            Assert.Equal("System.Type System.Object.GetType()", syms[index++]);
        }

        [WorkItem(543189, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543189")]
        [Fact()]
        public void CheckAnonymousTypeAsConstValue()
        {
            var source = @"
public class A
{
    const int i = /*<bind>*/(new {a = 2}).a/*</bind>*/;
}";

            var comp = CreateCompilation(source);
            var tuple = GetBindingNodeAndModel<ExpressionSyntax>(comp);
            var info = tuple.Item2.GetSymbolInfo(tuple.Item1);
            Assert.NotNull(info.Symbol);
            Assert.Equal("<anonymous type: int a>.a", info.Symbol.ToDisplayString());
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact()]
        public void CheckAnonymousTypeAsConstValue_OperationTree()
        {
            string source = @"
class A
{
    const int i = (/*<bind>*/new { a = 2 }/*</bind>*/).a;
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 a>, IsInvalid) (Syntax: 'new { a = 2 }')
  Initializers(1):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 2) (Syntax: 'a = 2')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 a>.a { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'a')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 a>, IsInvalid, IsImplicit) (Syntax: 'new { a = 2 }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // CS0836: Cannot use anonymous type in a constant expression
                //     const int i = (/*<bind>*/new { a = 2 }/*</bind>*/).a;
                Diagnostic(ErrorCode.ERR_AnonymousTypeNotAvailable, "new").WithLocation(4, 30)
            };

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")]
        [ClrOnlyFact]
        public void TestAnonymousTypeInsideGroupBy_Queryable()
        {
            CompileAndVerify(
 @"using System.Linq;

public class Product
{
    public int ProductID;
    public string ProductName;
    public int SupplierID;
}
public class DB
{
    public IQueryable<Product> Products;
}

public class Program
{
    public static void Main()
    {
        var db = new DB();
        var q0 = db.Products.GroupBy(p => new { Conditional = false ? new { p.ProductID, p.ProductName, p.SupplierID } : new { p.ProductID, p.ProductName, p.SupplierID } }).ToList();
    }
}").VerifyDiagnostics();
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")]
        [ClrOnlyFact]
        public void TestAnonymousTypeInsideGroupBy_Queryable_OperationTree()
        {
            string source = @"
using System.Linq;

class Product
{
    public int ProductID;
    public string ProductName;
    public int SupplierID;
}
class DB
{
    public IQueryable<Product> Products;
}

class Program
{
    public static void Main()
    {
        var db = new DB();
        var q0 = db.Products.GroupBy(p => /*<bind>*/new { Conditional = false ? new { p.ProductID, p.ProductName, p.SupplierID } : new { p.ProductID, p.ProductName, p.SupplierID } }/*</bind>*/).ToList();
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID> Conditional>) (Syntax: 'new { Condi ... plierID } }')
  Initializers(1):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>) (Syntax: 'Conditional ... upplierID }')
        Left: 
          IPropertyReferenceOperation: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID> <anonymous type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID> Conditional>.Conditional { get; } (OperationKind.PropertyReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>) (Syntax: 'Conditional')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID> Conditional>, IsImplicit) (Syntax: 'new { Condi ... plierID } }')
        Right: 
          IConditionalOperation (OperationKind.Conditional, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>) (Syntax: 'false ? new ... upplierID }')
            Condition: 
              ILiteralOperation (OperationKind.Literal, Type: System.Boolean, Constant: False) (Syntax: 'false')
            WhenTrue: 
              IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>) (Syntax: 'new { p.Pro ... upplierID }')
                Initializers(3):
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'p.ProductID')
                      Left: 
                        IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.ProductID { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'p.ProductID')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.Int32 Product.ProductID (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'p.ProductID')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, IsImplicit) (Syntax: 'p.ProductName')
                      Left: 
                        IPropertyReferenceOperation: System.String <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.ProductName { get; } (OperationKind.PropertyReference, Type: System.String, IsImplicit) (Syntax: 'p.ProductName')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.String Product.ProductName (OperationKind.FieldReference, Type: System.String) (Syntax: 'p.ProductName')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'p.SupplierID')
                      Left: 
                        IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.SupplierID { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'p.SupplierID')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.Int32 Product.SupplierID (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'p.SupplierID')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
            WhenFalse: 
              IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>) (Syntax: 'new { p.Pro ... upplierID }')
                Initializers(3):
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'p.ProductID')
                      Left: 
                        IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.ProductID { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'p.ProductID')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.Int32 Product.ProductID (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'p.ProductID')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.String, IsImplicit) (Syntax: 'p.ProductName')
                      Left: 
                        IPropertyReferenceOperation: System.String <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.ProductName { get; } (OperationKind.PropertyReference, Type: System.String, IsImplicit) (Syntax: 'p.ProductName')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.String Product.ProductName (OperationKind.FieldReference, Type: System.String) (Syntax: 'p.ProductName')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
                    ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'p.SupplierID')
                      Left: 
                        IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>.SupplierID { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'p.SupplierID')
                          Instance Receiver: 
                            IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 ProductID, System.String ProductName, System.Int32 SupplierID>, IsImplicit) (Syntax: 'new { p.Pro ... upplierID }')
                      Right: 
                        IFieldReferenceOperation: System.Int32 Product.SupplierID (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'p.SupplierID')
                          Instance Receiver: 
                            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: Product) (Syntax: 'p')
";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // CS0649: Field 'Product.ProductName' is never assigned to, and will always have its default value null
                //     public string ProductName;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ProductName").WithArguments("Product.ProductName", "null").WithLocation(7, 19),
                // CS0649: Field 'Product.SupplierID' is never assigned to, and will always have its default value 0
                //     public int SupplierID;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "SupplierID").WithArguments("Product.SupplierID", "0").WithLocation(8, 16),
                // CS0649: Field 'Product.ProductID' is never assigned to, and will always have its default value 0
                //     public int ProductID;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ProductID").WithArguments("Product.ProductID", "0").WithLocation(6, 16),
                // CS0649: Field 'DB.Products' is never assigned to, and will always have its default value null
                //     public IQueryable<Product> Products;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Products").WithArguments("DB.Products", "null").WithLocation(12, 32)
            };

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")]
        [ClrOnlyFact]
        public void TestAnonymousTypeInsideGroupBy_Enumerable()
        {
            CompileAndVerify(
 @"using System.Linq;
using System.Collections.Generic;

public class Product
{
    public int ProductID;
    public string ProductName;
    public int SupplierID;
}
public class DB
{
    public IEnumerable<Product> Products;
}

public class Program
{
    public static void Main()
    {
        var db = new DB();
        var q0 = db.Products.GroupBy(p => new { Conditional = false ? new { p.ProductID, p.ProductName, p.SupplierID } : new { p.ProductID, p.ProductName, p.SupplierID } }).ToList();
    }
}").VerifyDiagnostics();
        }

        [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")]
        [ClrOnlyFact]
        public void TestAnonymousTypeInsideGroupBy_Enumerable2()
        {
            CompileAndVerify(
 @"using System.Linq;
using System.Collections.Generic;

public class Product
{
    public int ProductID;
    public int SupplierID;
}
public class DB
{
    public IEnumerable<Product> Products;
}

public class Program
{
    public static void Main()
    {
        var db = new DB();
        var q0 = db.Products.GroupBy(p => new { Conditional = false ? new { p.ProductID, p.SupplierID } : new { p.ProductID, p.SupplierID } }).ToList();
        var q1 = db.Products.GroupBy(p => new { Conditional = false ? new { p.ProductID, p.SupplierID } : new { p.ProductID, p.SupplierID } }).ToList();
    }
}").VerifyDiagnostics();
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact, WorkItem(22588, "https://github.com/dotnet/roslyn/issues/22588")]
        public void AnonymousTypeSymbols_ErrorCases()
        {
            string source = @"
class ClassA
{
    static void Test1(int x)
    {
        var obj = /*<bind>*/new { f1 = null, f2 = M, f3 = default }/*</bind>*/;
    }

    static void M()
    {
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: error f1, error f2, ? f3>, IsInvalid) (Syntax: 'new { f1 =  ... = default }')
  Initializers(3):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: error, Constant: null, IsInvalid) (Syntax: 'f1 = null')
        Left: 
          IPropertyReferenceOperation: error <anonymous type: error f1, error f2, ? f3>.f1 { get; } (OperationKind.PropertyReference, Type: error, IsInvalid) (Syntax: 'f1')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: error f1, error f2, ? f3>, IsInvalid, IsImplicit) (Syntax: 'new { f1 =  ... = default }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: null, Constant: null, IsInvalid) (Syntax: 'null')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: error, IsInvalid) (Syntax: 'f2 = M')
        Left: 
          IPropertyReferenceOperation: error <anonymous type: error f1, error f2, ? f3>.f2 { get; } (OperationKind.PropertyReference, Type: error, IsInvalid) (Syntax: 'f2')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: error f1, error f2, ? f3>, IsInvalid, IsImplicit) (Syntax: 'new { f1 =  ... = default }')
        Right: 
          IOperation:  (OperationKind.None, Type: null, IsInvalid) (Syntax: 'M')
            Children(1):
                IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: ClassA, IsInvalid, IsImplicit) (Syntax: 'M')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: ?, IsInvalid) (Syntax: 'f3 = default')
        Left: 
          IPropertyReferenceOperation: ? <anonymous type: error f1, error f2, ? f3>.f3 { get; } (OperationKind.PropertyReference, Type: ?) (Syntax: 'f3')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: error f1, error f2, ? f3>, IsInvalid, IsImplicit) (Syntax: 'new { f1 =  ... = default }')
        Right: 
          IDefaultValueOperation (OperationKind.DefaultValue, Type: ?, IsInvalid) (Syntax: 'default')
";
            var expectedDiagnostics = new DiagnosticDescription[] {
                // file.cs(6,35): error CS0828: Cannot assign '<null>' to anonymous type property
                //         var obj = /*<bind>*/new { f1 = null, f2 = M, f3 = default }/*</bind>*/;
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "f1 = null").WithArguments("<null>").WithLocation(6, 35),
                // file.cs(6,46): error CS0828: Cannot assign 'method group' to anonymous type property
                //         var obj = /*<bind>*/new { f1 = null, f2 = M, f3 = default }/*</bind>*/;
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "f2 = M").WithArguments("method group").WithLocation(6, 46),
                // file.cs(6,59): error CS8716: There is no target type for the default literal.
                //         var obj = /*<bind>*/new { f1 = null, f2 = M, f3 = default }/*</bind>*/;
                Diagnostic(ErrorCode.ERR_DefaultLiteralNoTargetType, "default").WithLocation(6, 59)
            };

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [CompilerTrait(CompilerFeature.IOperation)]
        [Fact, WorkItem(27338, "https://github.com/dotnet/roslyn/issues/27338")]
        public void AnonymousTypeCreation_MixedInitializers()
        {
            string source = @"
using System.Collections.Generic;
using System.Linq;

class ClassA
{
    void M(int a)
    {
        var o = /*<bind>*/new { a, b = 1 }/*</bind>*/;
    }
}
";
            string expectedOperationTree = @"
IAnonymousObjectCreationOperation (OperationKind.AnonymousObjectCreation, Type: <anonymous type: System.Int32 a, System.Int32 b>) (Syntax: 'new { a, b = 1 }')
  Initializers(2):
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'a')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 a, System.Int32 b>.a { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'a')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 a, System.Int32 b>, IsImplicit) (Syntax: 'new { a, b = 1 }')
        Right: 
          IParameterReferenceOperation: a (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'a')
      ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, Constant: 1) (Syntax: 'b = 1')
        Left: 
          IPropertyReferenceOperation: System.Int32 <anonymous type: System.Int32 a, System.Int32 b>.b { get; } (OperationKind.PropertyReference, Type: System.Int32) (Syntax: 'b')
            Instance Receiver: 
              IInstanceReferenceOperation (ReferenceKind: ImplicitReceiver) (OperationKind.InstanceReference, Type: <anonymous type: System.Int32 a, System.Int32 b>, IsImplicit) (Syntax: 'new { a, b = 1 }')
        Right: 
          ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
";
            var expectedDiagnostics = DiagnosticDescription.None;

            VerifyOperationTreeAndDiagnosticsForTest<AnonymousObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67330")]
        public void AnonymousTypeSymbols_PointerArrayField()
        {
            var source = """
unsafe class C
{
    static unsafe void Main()
    {
        var array = new int*[0];
        var result = C.M(array);
        if (array == result)
        {
            System.Console.Write("RAN");
        }
    }

    static int*[] M(int*[] a)
    {
        var b = new { F = a };
        return b.F;
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe);
            comp.VerifyDiagnostics();
            CompileAndVerify(comp, expectedOutput: "RAN", verify: Verification.FailsPEVerify);
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67330")]
        public void AnonymousTypeSymbols_NestedPointerArrayField()
        {
            var source = """
unsafe class C<T>
{
    static C<int*[]> M()
    {
        var a = new { F = new C<int*[]>() };
        return a.F;
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics();
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67330")]
        public void AnonymousTypeSymbols_PointerField()
        {
            var source = """
unsafe class C
{
    static int* M(int* i)
    {
        var a = new { F = i };
        return a.F;
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (5,23): error CS0828: Cannot assign 'int*' to anonymous type property
                //         var a = new { F = i };
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "F = i").WithArguments("int*").WithLocation(5, 23)
                );
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67330")]
        public void AnonymousTypeSymbols_FunctionPointerField()
        {
            var source = """
unsafe class C
{
    static delegate*<void> M(delegate*<void> i)
    {
        var a = new { F = i };
        return a.F;
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (5,23): error CS0828: Cannot assign 'delegate*<void>' to anonymous type property
                //         var a = new { F = i };
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "F = i").WithArguments("delegate*<void>").WithLocation(5, 23)
                );
        }

        #region "Utility methods"

        private void AssertCannotConstruct(ISymbol type)
        {
            var namedType = type as INamedTypeSymbol;
            Assert.NotNull(namedType);

            var objType = namedType.BaseType;
            Assert.NotNull(objType);
            Assert.Equal("System.Object", objType.ToTestDisplayString());

            ITypeSymbol[] args = new ITypeSymbol[namedType.Arity];
            for (int i = 0; i < namedType.Arity; i++)
            {
                args[i] = objType;
            }

            Assert.Throws<InvalidOperationException>(() => namedType.Construct(args));
        }

        private CompilationUtils.SemanticInfoSummary GetAnonymousTypeInfoSummary(TestData data, int node, TextSpan typeSpan, params int[] fields)
        {
            var info = data.Model.GetSemanticInfoSummary(data.Nodes[node]);
            var type = info.Type;

            Assert.True(type.IsAnonymousType);
            Assert.False(type.CanBeReferencedByName);

            Assert.Equal("System.Object", type.BaseType.ToTestDisplayString());
            Assert.Equal(0, type.Interfaces.Length);

            Assert.Equal(1, type.Locations.Length);
            Assert.Equal(typeSpan, type.Locations[0].SourceSpan);

            foreach (int field in fields)
            {
                CheckFieldNameAndLocation(data, type, data.Nodes[field]);
            }

            return info;
        }

        private void CheckFieldNameAndLocation(TestData data, ITypeSymbol type, SyntaxNode identifier)
        {
            var anonymousType = (INamedTypeSymbol)type;

            var current = identifier;
            while (current.Span == identifier.Span && !current.IsKind(SyntaxKind.IdentifierName))
            {
                current = current.ChildNodes().Single();
            }
            var node = (IdentifierNameSyntax)current;
            Assert.NotNull(node);

            var span = node.Span;
            var fieldName = node.ToString();

            var property = anonymousType.GetMember<IPropertySymbol>(fieldName);
            Assert.NotNull(property);
            Assert.Equal(fieldName, property.Name);
            Assert.Equal(1, property.Locations.Length);
            Assert.Equal(span, property.Locations[0].SourceSpan);

            IMethodSymbol getter = property.GetMethod;
            Assert.NotNull(getter);
            Assert.Equal("get_" + fieldName, getter.Name);
        }

        private struct TestData
        {
            public CSharpCompilation Compilation;
            public SyntaxTree Tree;
            public List<SyntaxNode> Nodes;
            public SemanticModel Model;
        }

        private TestData Compile(string source, int expectedIntervals, params DiagnosticDescription[] diagnostics)
        {
            var intervals = ExtractTextIntervals(ref source);
            Assert.Equal(expectedIntervals, intervals.Count);

            var compilation = Compile(source);

            compilation.VerifyDiagnostics(diagnostics);

            var tree = compilation.SyntaxTrees[0];
            var nodes = new List<SyntaxNode>();

            foreach (var span in intervals)
            {
                var stack = new Stack<SyntaxNode>();
                stack.Push(tree.GetCompilationUnitRoot());

                while (stack.Count > 0)
                {
                    var node = stack.Pop();
                    if (span.Contains(node.Span))
                    {
                        nodes.Add(node);
                        break;
                    }

                    foreach (var child in node.ChildNodes())
                    {
                        stack.Push(child);
                    }
                }
            }
            Assert.Equal(expectedIntervals, nodes.Count);

            return new TestData()
            {
                Compilation = compilation,
                Tree = tree,
                Model = compilation.GetSemanticModel(tree),
                Nodes = nodes
            };
        }

        private CSharpCompilation Compile(string source) =>
            CreateCompilationWithMscorlib40(
                source,
                options: TestOptions.ReleaseDll,
                parseOptions: TestOptions.Regular);

        private static List<TextSpan> ExtractTextIntervals(ref string source)
        {
            const string startTag = "[#";
            const string endTag = "#]";

            List<TextSpan> intervals = new List<TextSpan>();

            var all = (from s in FindAll(source, startTag)
                       select new { start = true, offset = s }).Union(
                                from s in FindAll(source, endTag)
                                select new { start = false, offset = s }
                      ).OrderBy(value => value.offset).ToList();

            while (all.Count > 0)
            {
                int i = 1;
                bool added = false;
                while (i < all.Count)
                {
                    if (all[i - 1].start && !all[i].start)
                    {
                        intervals.Add(TextSpan.FromBounds(all[i - 1].offset, all[i].offset));
                        all.RemoveAt(i);
                        all.RemoveAt(i - 1);
                        added = true;
                    }
                    else
                    {
                        i++;
                    }
                }
                Assert.True(added);
            }

            source = source.Replace(startTag, "  ").Replace(endTag, "  ");

            intervals.Sort((x, y) => x.Start.CompareTo(y.Start));
            return intervals;
        }

        private static IEnumerable<int> FindAll(string source, string what)
        {
            int index = source.IndexOf(what, StringComparison.Ordinal);
            while (index >= 0)
            {
                yield return index;
                index = source.IndexOf(what, index + 1, StringComparison.Ordinal);
            }
        }

        private int NumberOfNewKeywords(string source)
        {
            int cnt = 0;
            foreach (var line in source.Split(new String[] { Environment.NewLine }, StringSplitOptions.None))
            {
                if (!string.IsNullOrWhiteSpace(line))
                {
                    if (!line.Trim().StartsWith("//", StringComparison.Ordinal))
                    {
                        for (int index = line.IndexOf("new ", StringComparison.Ordinal); index >= 0;)
                        {
                            cnt++;
                            index = line.IndexOf("new ", index + 1, StringComparison.Ordinal);
                        }
                    }
                }
            }
            return cnt;
        }

        #endregion
    }
}
