File: Compilation\SemanticModelGetDeclaredSymbolAPITests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public partial class SemanticModelTests : CSharpTestBase
    {
        [Fact]
        public void RefForEachVar()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M(Span<int> span)
    {
        foreach (ref readonly int rx in span) { }
    }
}");
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees.Single();
            var root = tree.GetCompilationUnitRoot();
            var rxDecl = root.DescendantNodes().OfType<ForEachStatementSyntax>().Single();
            var model = comp.GetSemanticModel(tree);
            ILocalSymbol rx = model.GetDeclaredSymbol(rxDecl);
            Assert.NotNull(rx);
            Assert.True(rx.IsRef);
            Assert.Equal(RefKind.RefReadOnly, rx.RefKind);
        }
 
        [Fact]
        public void RefForVar()
        {
            var comp = CreateCompilation(@"
class C
{
    void M(int x)
    {
        for (ref readonly int rx = ref x;;) { }
    }
}");
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees.Single();
            var root = tree.GetCompilationUnitRoot();
            var rxDecl = root.DescendantNodes().OfType<ForStatementSyntax>().Single().Declaration;
            var model = comp.GetSemanticModel(tree);
            ISymbol rx = model.GetDeclaredSymbol(rxDecl.Variables.Single());
            Assert.NotNull(rx);
            var rxLocal = Assert.IsAssignableFrom<ILocalSymbol>(rx);
            Assert.True(rxLocal.IsRef);
            Assert.Equal(RefKind.RefReadOnly, rxLocal.RefKind);
        }
 
        [Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
        public void TestGetDeclaredSymbolFromNamespace(string ob, string cb)
        {
            var compilation = CreateCompilation($@"
namespace A.B
{ob}
{cb}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var decl = (BaseNamespaceDeclarationSyntax)root.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.NotNull(symbol);
            Assert.Equal("B", symbol.Name);
        }
 
        [Fact]
        public void NamespaceAndClassWithNoNames()
        {
            var compilation = CreateCompilation(@"
class
{
}
 
namespace
{
}
 
class
{
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var decl = (NamespaceDeclarationSyntax)root.Members[1];
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.NotNull(symbol);
            Assert.Equal("", symbol.Name);
        }
 
        [Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
        public void TestGetDeclaredSymbolFromNestedNamespace(string ob, string cb)
        {
            var compilation = CreateCompilation($@"
namespace A.B
{ob}
   namespace C.D
   {ob}
   {cb}
{cb}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var abns = (BaseNamespaceDeclarationSyntax)root.Members[0];
            var cdns = (BaseNamespaceDeclarationSyntax)abns.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(cdns);
            Assert.NotNull(symbol);
            Assert.Equal("D", symbol.Name);
        }
 
        [Fact]
        public void IncompleteNamespaceDeclaration()
        {
            var compilation = CreateCompilation(@"
namespace
 
class C
{
    void M() { }
}
"
            );
 
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var classC = (root.Members[0] as NamespaceDeclarationSyntax).Members[0] as TypeDeclarationSyntax;
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(classC);
            Assert.NotNull(symbol);
            Assert.Equal("C", symbol.Name);
        }
 
        [Fact]
        public void AmbiguousSymbolInNamespaceName()
        {
            var compilation = CreateCompilation(@"
class C { }
 
namespace C.B 
{ 
    class Y { }
}
");
 
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var classY = ((root.
                Members[1] as NamespaceDeclarationSyntax).
                Members[0] as TypeDeclarationSyntax);
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(classY);
            Assert.NotNull(symbol);
            Assert.Equal("C.B.Y", symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void GetEnumDeclaration()
        {
            var compilation = CreateCompilation(@"
enum E { }
");
 
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var enumE = root.Members[0] as EnumDeclarationSyntax;
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(enumE);
            Assert.NotNull(symbol);
            Assert.Equal("E", symbol.ToTestDisplayString());
        }
 
        [Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
        public void GenericNameInNamespaceName(string ob, string cb)
        {
            var compilation = CreateCompilation(@"
namespace C<int>.B
" + ob + @"
    class Y { }
" + cb + @"
");
 
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var classY = ((root.
                Members[0] as BaseNamespaceDeclarationSyntax).
                Members[0] as TypeDeclarationSyntax);
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(classY);
            Assert.NotNull(symbol);
            Assert.Equal("C.B.Y", symbol.ToTestDisplayString());
        }
 
        [Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
        public void AliasedNameInNamespaceName(string ob, string cb)
        {
            var compilation = CreateCompilation(@"
namespace alias::C<int>.B
" + ob + @"
    class Y { }
" + cb + @"
");
 
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var classY = ((root.
                Members[0] as BaseNamespaceDeclarationSyntax).
                Members[0] as TypeDeclarationSyntax);
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(classY);
            Assert.NotNull(symbol);
            Assert.Equal("C.B.Y", symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromType()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var typeSymbol = model.GetDeclaredSymbol(typeDecl);
            Assert.NotNull(typeSymbol);
            Assert.Equal("C", typeSymbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMethod()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var methodSymbol = model.GetDeclaredSymbol(methodDecl);
            Assert.NotNull(methodSymbol);
            Assert.Equal("M", methodSymbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromProperty()
        {
            var compilation = CreateCompilation(
@"class C
{
    object P
    {
        get { return null; }
        set { }
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var propertyDecl = (PropertyDeclarationSyntax)typeDecl.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var propertySymbol = model.GetDeclaredSymbol(propertyDecl);
            Assert.NotNull(propertySymbol);
            Assert.Equal("P", propertySymbol.Name);
 
            var accessorList = propertyDecl.AccessorList.Accessors;
            Assert.Equal(2, accessorList.Count);
            foreach (var accessorDecl in accessorList)
            {
                var accessorSymbol = model.GetDeclaredSymbol(accessorDecl);
                Assert.NotNull(accessorSymbol);
            }
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromIndexer()
        {
            var compilation = CreateCompilation(
@"class C
{
    object this[int x, int y]
    {
        get { return null; }
        set { }
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = (CSharpSemanticModel)compilation.GetSemanticModel(tree);
 
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var indexerDecl = (IndexerDeclarationSyntax)typeDecl.Members[0];
            var paramDecl = indexerDecl.ParameterList.Parameters[0];
            var getterDecl = indexerDecl.AccessorList.Accessors[0];
            var setterDecl = indexerDecl.AccessorList.Accessors[1];
 
            var propertySymbol = model.GetDeclaredSymbol(indexerDecl);
            Assert.NotNull(propertySymbol);
            Assert.Equal(WellKnownMemberNames.Indexer, propertySymbol.Name);
            Assert.Equal("Item", propertySymbol.MetadataName);
            Assert.Equal("System.Object C.this[System.Int32 x, System.Int32 y] { get; set; }", propertySymbol.ToTestDisplayString());
 
            var paramSymbol = model.GetDeclaredSymbol(paramDecl);
            Assert.NotNull(paramSymbol);
            Assert.Equal(SpecialType.System_Int32, paramSymbol.Type.SpecialType);
            Assert.Equal("x", paramSymbol.Name);
            Assert.Equal(propertySymbol, paramSymbol.ContainingSymbol);
            Assert.Equal("System.Int32 x", paramSymbol.ToTestDisplayString());
 
            var getterSymbol = model.GetDeclaredSymbol(getterDecl);
            Assert.NotNull(getterSymbol);
            Assert.Equal(MethodKind.PropertyGet, getterSymbol.MethodKind);
            Assert.Equal(propertySymbol.GetMethod, getterSymbol);
            Assert.Equal("System.Object C.this[System.Int32 x, System.Int32 y].get", getterSymbol.ToTestDisplayString());
 
            var setterSymbol = model.GetDeclaredSymbol(setterDecl);
            Assert.NotNull(setterSymbol);
            Assert.Equal(MethodKind.PropertySet, setterSymbol.MethodKind);
            Assert.Equal(propertySymbol.SetMethod, setterSymbol);
            Assert.Equal("void C.this[System.Int32 x, System.Int32 y].set", setterSymbol.ToTestDisplayString());
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromCustomEvent()
        {
            var compilation = CreateCompilation(
@"class C
{
    event System.Action E
    {
        add { }
        remove { }
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var eventDecl = (EventDeclarationSyntax)typeDecl.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var eventSymbol = model.GetDeclaredSymbol(eventDecl);
            Assert.NotNull(eventSymbol);
            Assert.Equal("E", eventSymbol.Name);
            Assert.IsType<SourceCustomEventSymbol>(eventSymbol.GetSymbol());
 
            var accessorList = eventDecl.AccessorList.Accessors;
            Assert.Equal(2, accessorList.Count);
            Assert.Same(eventSymbol.AddMethod, model.GetDeclaredSymbol(accessorList[0]));
            Assert.Same(eventSymbol.RemoveMethod, model.GetDeclaredSymbol(accessorList[1]));
        }
 
        [WorkItem(543494, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543494")]
        [Fact()]
        public void TestGetDeclaredSymbolFromFieldLikeEvent()
        {
            var compilation = CreateCompilation(
@"class C
{
    event System.Action E;
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var eventDecl = (EventFieldDeclarationSyntax)typeDecl.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var eventSymbol = model.GetDeclaredSymbol(eventDecl.Declaration.Variables[0]);
            Assert.NotNull(eventSymbol);
            Assert.Null(model.GetDeclaredSymbol(eventDecl)); // the event decl may have multiple variable declarators, the result for GetDeclaredSymbol will always be null
            Assert.Equal("E", eventSymbol.Name);
            Assert.IsType<SourceFieldLikeEventSymbol>(eventSymbol.GetSymbol());
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfEventDeclarationSyntaxAsBasePropertyDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    public event D Iter3 { add {return 5; } remove { return 5; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var node = root.FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("public event D Iter3", StringComparison.Ordinal)).Parent as BasePropertyDeclarationSyntax;
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Event, symbol.Kind);
            Assert.Equal("Iter3", symbol.Name);
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfPropertyDeclarationSyntaxAsBasePropertyDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    public int Prop { get { return 5; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var node = (BasePropertyDeclarationSyntax)typeDecl.Members[0];
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Property, symbol.Kind);
            Assert.Equal("Prop", symbol.Name);
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfIndexerDeclarationSyntaxAsBasePropertyDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    object this[int x, int y] { get { return null; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var node = (BasePropertyDeclarationSyntax)typeDecl.Members[0];
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Property, symbol.Kind);
            Assert.NotNull(symbol);
            Assert.Equal(WellKnownMemberNames.Indexer, symbol.Name);
            Assert.Equal("Item", symbol.MetadataName);
            Assert.Equal("System.Object Test.this[System.Int32 x, System.Int32 y] { get; }", symbol.ToTestDisplayString());
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfEventDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    public event D Iter3 { add {return 5; } remove { return 5; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var node = (EventDeclarationSyntax)typeDecl.Members[0];
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Event, symbol.Kind);
            Assert.Equal("Iter3", symbol.Name);
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfPropertyDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    public int Prop { get { return 5; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var node = (PropertyDeclarationSyntax)typeDecl.Members[0];
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Property, symbol.Kind);
            Assert.Equal("Prop", symbol.Name);
        }
 
        [WorkItem(543574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543574")]
        [Fact()]
        public void GetDeclaredSymbolOfIndexerDeclarationSyntax()
        {
            var compilation = CreateCompilation(
@"
public class Test
{
    object this[int x, int y] { get { return null; } }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)root.Members[0];
            var node = (IndexerDeclarationSyntax)typeDecl.Members[0];
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SymbolKind.Property, symbol.Kind);
            Assert.NotNull(symbol);
            Assert.Equal(WellKnownMemberNames.Indexer, symbol.Name);
            Assert.Equal("Item", symbol.MetadataName);
            Assert.Equal("System.Object Test.this[System.Int32 x, System.Int32 y] { get; }", symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromLocalDeclarator()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    int x = 10;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(localDecl.Declaration.Variables[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMultipleLocalDeclarators()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    int x = 10, y = 20;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(localDecl.Declaration.Variables[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
 
            symbol = model.GetDeclaredSymbol(localDecl.Declaration.Variables[1]);
            Assert.NotNull(symbol);
            Assert.Equal("y", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMultipleLabelDeclarators()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    label1:
    label2:
       object x = this;
  }
}
");
            dynamic tree = compilation.SyntaxTrees[0];
            dynamic methodDecl = tree.GetCompilationUnitRoot().Members[0].Members[0];
            var model = compilation.GetSemanticModel(tree);
 
            LabeledStatementSyntax labeled1 = methodDecl.Body.Statements[0];
            var symbol1 = (ISymbol)model.GetDeclaredSymbol(labeled1);
            Assert.NotNull(symbol1);
            Assert.Equal("label1", symbol1.Name);
 
            var labeled2 = (LabeledStatementSyntax)labeled1.Statement;
            var symbol2 = (ISymbol)model.GetDeclaredSymbol(labeled2);
            Assert.NotNull(symbol2);
            Assert.Equal("label2", symbol2.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromAnonymousTypePropertyInitializer()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    var o = new { a, b = """" };
  }
  public static int a = 123;
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            TestAnonymousTypePropertySymbol(model,
                                tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 1).AsNode(),
                                "System.Int32 <anonymous type: System.Int32 a, System.String b>.a { get; }");
 
            TestAnonymousTypePropertySymbol(model,
                                tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 2).AsNode(),
                                "System.String <anonymous type: System.Int32 a, System.String b>.b { get; }");
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromAnonymousTypePropertyInitializer_WithErrors()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    var o = new { a, a(), b = 123, c = null };
  }
  public static int a() { return 1; }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            TestAnonymousTypePropertySymbol(model,
                                            tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 1).AsNode(),
                                            "error <anonymous type: error a, System.Int32 $1, System.Int32 b, error c>.a { get; }");
 
            TestAnonymousTypePropertySymbol(model,
                                            tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 2).AsNode(),
                                            "System.Int32 <anonymous type: error a, System.Int32 $1, System.Int32 b, error c>.$1 { get; }");
 
            TestAnonymousTypePropertySymbol(model,
                                            tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 3).AsNode(),
                                            "System.Int32 <anonymous type: error a, System.Int32 $1, System.Int32 b, error c>.b { get; }");
 
            TestAnonymousTypePropertySymbol(model,
                                            tree.FindNodeOrTokenByKind(SyntaxKind.AnonymousObjectMemberDeclarator, 4).AsNode(),
                                            "error <anonymous type: error a, System.Int32 $1, System.Int32 b, error c>.c { get; }");
        }
 
        private void TestAnonymousTypePropertySymbol(SemanticModel model, SyntaxNode node, string name)
        {
            Assert.NotNull(node);
            var symbol = model.GetDeclaredSymbol(node);
            Assert.NotNull(symbol);
            Assert.Equal(name, symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromSwitchCaseLabel()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    int val = 0;
    switch(val)
    {
        case 0:
            break;
    }
  }
}
");
            dynamic tree = compilation.SyntaxTrees[0];
            dynamic methodDecl = tree.GetCompilationUnitRoot().Members[0].Members[0];
            var model = compilation.GetSemanticModel(tree);
 
            SwitchStatementSyntax switchStmt = methodDecl.Body.Statements[1];
            SwitchLabelSyntax switchLabel = switchStmt.Sections[0].Labels[0];
 
            var symbol = (ISymbol)model.GetDeclaredSymbol(switchLabel);
            Assert.NotNull(symbol);
 
            var labelSymbol = (SourceLabelSymbol)symbol.GetSymbol();
            Assert.Equal(ConstantValue.Default(SpecialType.System_Int32), labelSymbol.SwitchCaseLabelConstant);
            Assert.Equal(switchLabel, labelSymbol.IdentifierNodeOrToken.AsNode());
            Assert.Equal("case 0:", labelSymbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromSwitchDefaultLabel()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    int val = 0;
    switch(val)
    {
        default:
            break;
    }
  }
}
");
            dynamic tree = compilation.SyntaxTrees[0];
            dynamic methodDecl = tree.GetCompilationUnitRoot().Members[0].Members[0];
            var model = compilation.GetSemanticModel(tree);
 
            SwitchStatementSyntax switchStmt = methodDecl.Body.Statements[1];
            SwitchLabelSyntax switchLabel = switchStmt.Sections[0].Labels[0];
            var symbol1 = (ISymbol)model.GetDeclaredSymbol(switchLabel);
            Assert.NotNull(symbol1);
 
            var labelSymbol = (SourceLabelSymbol)symbol1.GetSymbol();
            Assert.Null(labelSymbol.SwitchCaseLabelConstant);
            Assert.Equal(switchLabel, labelSymbol.IdentifierNodeOrToken.AsNode());
            Assert.Equal("default", labelSymbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromFieldDeclarator()
        {
            var compilation = CreateCompilation(@"
class C 
{
  int x;
 
  void M()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var fieldDecl = (FieldDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(fieldDecl.Declaration.Variables[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMultipleFieldDeclarators()
        {
            var compilation = CreateCompilation(@"
class C 
{
  int x, y;
 
  void M()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var fieldDecl = (FieldDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(fieldDecl.Declaration.Variables[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
 
            symbol = model.GetDeclaredSymbol(fieldDecl.Declaration.Variables[1]);
            Assert.NotNull(symbol);
            Assert.Equal("y", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromParameter()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M(int x)
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(methodDecl.ParameterList.Parameters[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
        }
 
        [WorkItem(540108, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540108")]
        [Fact]
        public void TestGetDeclaredSymbolFromDelegateParameter()
        {
            var compilation = CreateCompilation(@"
delegate D(int x);
");
            var tree = compilation.SyntaxTrees[0];
            var delegateDecl = (DelegateDeclarationSyntax)(tree.GetCompilationUnitRoot().Members[0]);
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(delegateDecl.ParameterList.Parameters[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMultipleParameter()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M(int x, int y)
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(methodDecl.ParameterList.Parameters[0]);
            Assert.NotNull(symbol);
            Assert.Equal("x", symbol.Name);
 
            symbol = model.GetDeclaredSymbol(methodDecl.ParameterList.Parameters[1]);
            Assert.NotNull(symbol);
            Assert.Equal("y", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromClassTypeParameter()
        {
            var compilation = CreateCompilation(@"
class C<T>
{
  void M()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var typeDecl = (TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(typeDecl.TypeParameterList.Parameters[0]);
            Assert.NotNull(symbol);
            Assert.Equal("T", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromMethodTypeParameter()
        {
            var compilation = CreateCompilation(@"
class C
{
  void M<T>()
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(methodDecl.TypeParameterList.Parameters[0]);
            Assert.NotNull(symbol);
            Assert.Equal("T", symbol.Name);
        }
 
        [Fact]
        public void TestGetDeclaredSymbolFromGenericPartialType()
        {
            var compilation = CreateCompilation(@"
namespace N1.N2
{
    public struct St<T>
    {
        private T field;
        public enum Em { Zero, One, Two, Three}
    }
}
 
namespace N1.N2
{
    public partial interface IGoo<T, V>
    {
        St<object>.Em ReturnEnum();
    }
 
    public partial interface IGoo<T, V>
    {
        void M(St<T> p1, St<V> p2);
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var root = tree.GetCompilationUnitRoot();
            var nsDecl = (NamespaceDeclarationSyntax)root.Members[0];
            var nsSymbol = model.GetDeclaredSymbol(nsDecl);
            var typeDecl = (TypeDeclarationSyntax)nsDecl.Members[0];
            var structSymbol = model.GetDeclaredSymbol(typeDecl);
            Assert.NotNull(structSymbol);
            Assert.Equal(1, structSymbol.Arity);
            Assert.Equal("St", structSymbol.Name);
            Assert.Equal("N1.N2.St<T>", structSymbol.ToTestDisplayString());
 
            var fieldDecl = (FieldDeclarationSyntax)typeDecl.Members[0];
            var fSymbol = model.GetDeclaredSymbol(fieldDecl.Declaration.Variables[0]) as IFieldSymbol;
            Assert.Equal("field", fSymbol.Name);
            Assert.Equal("T", fSymbol.Type.Name);
            Assert.Equal<ISymbol>(structSymbol, fSymbol.ContainingSymbol);
            Assert.Null(model.GetDeclaredSymbol(fieldDecl));
 
            var enumDecl = (EnumDeclarationSyntax)typeDecl.Members[1];
            var enumSymbol = model.GetDeclaredSymbol(enumDecl);
            Assert.Equal("Em", enumSymbol.Name);
 
            nsDecl = (NamespaceDeclarationSyntax)root.Members[1];
            var nsSymbol01 = model.GetDeclaredSymbol(nsDecl);
            Assert.Equal(nsSymbol, nsSymbol01);
 
            typeDecl = (TypeDeclarationSyntax)nsDecl.Members[0];
            var itfcSymbol = model.GetDeclaredSymbol(typeDecl);
            Assert.Equal(2, itfcSymbol.Arity);
            Assert.Equal("N1.N2.IGoo<T, V>", itfcSymbol.ToTestDisplayString());
            // CC
            var pt = typeDecl.TypeParameterList.Parameters[1];
            var ptsym = model.GetDeclaredSymbol(pt);
            Assert.Equal(SymbolKind.TypeParameter, ptsym.Kind);
            Assert.Equal("V", ptsym.Name);
 
            var memDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var mSymbol = model.GetDeclaredSymbol(memDecl) as IMethodSymbol;
            Assert.Equal("ReturnEnum", mSymbol.Name);
            Assert.Equal("N1.N2.St<System.Object>.Em", mSymbol.ReturnType.ToTestDisplayString());
            Assert.Equal<ISymbol>(enumSymbol, mSymbol.ReturnType.OriginalDefinition);
 
            typeDecl = (TypeDeclarationSyntax)nsDecl.Members[1];
            memDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            mSymbol = model.GetDeclaredSymbol(memDecl) as IMethodSymbol;
            Assert.Equal(2, mSymbol.Parameters.Length);
            Assert.Equal("p1", mSymbol.Parameters[0].Name);
            Assert.Equal("St", mSymbol.Parameters[0].Type.Name);
            Assert.Equal<ISymbol>(structSymbol, mSymbol.Parameters[1].Type.OriginalDefinition);
            // CC
            var psym = model.GetDeclaredSymbol(memDecl.ParameterList.Parameters[0]);
            Assert.Equal(SymbolKind.Parameter, psym.Kind);
            Assert.Equal("p1", psym.Name);
        }
 
        [Fact]
        [WorkItem(7213, "https://github.com/dotnet/roslyn/issues/7213")]
        public void TestGetDeclaredSymbolWithIncompleteDeclaration()
        {
            var compilation = CreateCompilation(@"
class C0 { }
 
class 
 
class C1 { }
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var typeDecl = (ClassDeclarationSyntax)root.Members[1];
            var model = compilation.GetSemanticModel(tree);
 
            var symbol = model.GetDeclaredSymbol(typeDecl);
 
            Assert.NotNull(symbol);
            Assert.Equal(string.Empty, symbol.ToTestDisplayString());
            Assert.Equal(TypeKind.Class, symbol.TypeKind);
        }
 
        [WorkItem(537230, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537230")]
        [Theory]
        [MemberData(nameof(FileScopedOrBracedNamespace))]
        public void TestLookupUnresolvableNamespaceUsing(string ob, string cb)
        {
            var compilation = CreateCompilation(@"
                namespace A
                " + ob + @"
                    using B.C;
 
                    public class B : C
                    {    
                    }
                " + cb + @"
            ");
            var tree = compilation.SyntaxTrees.Single();
            var usingDirective = (UsingDirectiveSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.UsingDirective).AsNode();
            var model = compilation.GetSemanticModel(tree);
            var type = model.GetTypeInfo(usingDirective.Name);
            Assert.NotEmpty(compilation.GetDeclarationDiagnostics());
            // should validate type here
        }
 
        [Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
        public void TestLookupSourceSymbolHidesMetadataSymbol(string ob, string cb)
        {
            var compilation = CreateCompilation(@"
namespace System
" + ob + @"
    public class DateTime
    {
        string TheDateAndTime;
    }
" + cb + @"
");
 
            var tree = compilation.SyntaxTrees.Single();
 
            var namespaceDecl = (BaseNamespaceDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0];
            var classDecl = (ClassDeclarationSyntax)namespaceDecl.Members[0];
            var memberDecl = (FieldDeclarationSyntax)classDecl.Members[0];
 
            var model = compilation.GetSemanticModel(tree);
            var symbols = model.LookupSymbols(memberDecl.SpanStart, null, "DateTime");
            Assert.Equal(1, symbols.Length);
        }
 
        [Fact]
        public void TestLookupAllArities()
        {
            var compilation = CreateCompilation(@"
                class B {}
 
                class A
                {
                   class B<X> {}
                   class B<X,Y> {}
 
                   void M()
                   {
                      int B;
                   }
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[1];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[2];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbols = model.LookupSymbols(methodDecl.SpanStart, null, "B");
            Assert.Equal(3, symbols.Length);
            Assert.Equal(SymbolKind.NamedType, symbols[0].Kind);
 
            symbols = model.LookupSymbols(localDecl.SpanStart, null, "B");
            Assert.Equal(3, symbols.Length);
            Assert.Equal(SymbolKind.Local, symbols[0].Kind);
        }
 
        [Fact]
        public void TestLookupWithinClassAllArities()
        {
            var compilation = CreateCompilation(@"
                using AliasZ = B.Z;
 
                class A
                {
                   public class Z<X> {}
                   public class Z<X,Y> {}
                }
 
                class B : A
                {
                   public class Z {}
                   public class Z<X> {}
                }
 
                class C : B
                {
                   public int Z;
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclB = (TypeDeclarationSyntax)cu.Members[1];
            var someMemberInB = (MemberDeclarationSyntax)typeDeclB.Members[0];
            int positionInB = someMemberInB.SpanStart;
 
            var symbols = model.LookupSymbols(positionInB, name: "Z");
            Assert.Equal(3, symbols.Length);
            Assert.Equal(SymbolKind.NamedType, symbols[0].Kind);
 
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
            int positionInC = someMemberInC.SpanStart;
 
            symbols = model.LookupSymbols(positionInC, name: "Z");
            Assert.Equal(3, symbols.Length);
            Assert.Equal(SymbolKind.Field, symbols[0].Kind);
 
            symbols = model.LookupSymbols(positionInC, name: "AliasZ");
            Assert.Equal(1, symbols.Length);
            Assert.Equal(SymbolKind.Alias, symbols[0].Kind);
 
            symbols = model.LookupSymbols(positionInC, name: "C");
            var container = (INamespaceOrTypeSymbol)symbols.Single();
 
            symbols = model.LookupSymbols(positionInC, name: "AliasZ", container: container);
            Assert.Equal(0, symbols.Length);
        }
 
        [Fact]
        public void TestLookupTypesAllArities()
        {
            var compilation = CreateCompilation(@"
                class B {}
 
                class A
                {
                   class B<X> {}
                   class B<X,Y> {}
 
                   void M()
                   {
                      int B;
                   }
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[1];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[2];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
 
            var model = compilation.GetSemanticModel(tree);
 
            var symbols = model.LookupNamespacesAndTypes(localDecl.SpanStart, name: "B");
            Assert.Equal(3, symbols.Length);
            Assert.Equal(SymbolKind.NamedType, symbols[0].Kind);
        }
 
        [Fact]
        public void TestLookupSymbolNames()
        {
            var compilation = CreateCompilation(@"
                class A
                {
                   public int X;
                }
 
                class B : A
                {
                   public int Y;
                }
 
                class C : B
                {
                   public int Z;
 
                   public void M()
                   {
                   }
                }
            ", targetFramework: TargetFramework.NetStandard20);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
            int positionInC = someMemberInC.SpanStart;
 
            var namesInC = model.LookupNames(positionInC, namespacesAndTypesOnly: true);
            Assert.Equal(5, namesInC.Count);  // A, B, C, System, Microsoft
            Assert.Contains("A", namesInC);
            Assert.Contains("B", namesInC);
            Assert.Contains("C", namesInC);
            Assert.Contains("System", namesInC);
            Assert.Contains("Microsoft", namesInC);
 
            var methodM = (MethodDeclarationSyntax)typeDeclC.Members[1];
            var namesInM = model.LookupNames(methodM.Body.SpanStart);
            Assert.Equal(16, namesInM.Count);
        }
 
        [Fact]
        public void TestLookupSymbolNamesInCyclicClass()
        {
            var compilation = CreateCompilation(@"
                class A : B
                {
                   public int X;
                }
 
                class B : A
                {
                   public int Y;
                }
            ", targetFramework: TargetFramework.NetStandard20);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclA = (TypeDeclarationSyntax)cu.Members[0];
            var someMemberInA = (MemberDeclarationSyntax)typeDeclA.Members[0];
 
            var namesInA = model.LookupNames(someMemberInA.SpanStart);
            Assert.Equal(13, namesInA.Count);
            Assert.Contains("X", namesInA);
            Assert.Contains("Y", namesInA);
            Assert.Contains("ToString", namesInA);
        }
 
        [Fact]
        public void TestLookupSymbolNamesInInterface()
        {
            var compilation = CreateCompilation(@"
                interface A
                {
                   void AM();
                }
 
                interface B : A
                {
                   void BX();
                }
 
                interface C : B
                {
                   void CM();
                }
            ", targetFramework: TargetFramework.NetStandard20);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
 
            var namesInC = model.LookupNames(someMemberInC.SpanStart);
            Assert.Equal(13, namesInC.Count); // everything with exception of protected members in System.Object is included, with an uncertain count
            Assert.Contains("A", namesInC);
            Assert.Contains("B", namesInC);
            Assert.Contains("C", namesInC);
            Assert.Contains("AM", namesInC);
            Assert.Contains("BX", namesInC);
            Assert.Contains("CM", namesInC);
            Assert.Contains("System", namesInC);
            Assert.Contains("Microsoft", namesInC);
        }
 
        [Fact]
        public void TestLookupSymbolNamesInTypeParameter()
        {
            var compilation = CreateCompilation(@"
interface IA
{
    void MA();
}
interface IB
{
    void MB();
}
interface IC
{
    void M<T, U>();
}
class C : IA
{
    void IA.MA() { }
    public void M<T>() { }
}
class D<T>
    where T : IB
{
    void MD<U, V>(U u, V v)
        where U : C, T, IC
        where V : struct
    {
    }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[4];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var parameterDecl = (ParameterSyntax)methodDecl.ParameterList.Parameters[0];
            var paramSymbol = model.GetDeclaredSymbol(parameterDecl);
            var names = model.LookupNames(methodDecl.SpanStart, paramSymbol.Type);
            Assert.Equal(7, names.Count);
            Assert.Contains("M", names);
            Assert.Contains("ToString", names);
            Assert.Contains("ReferenceEquals", names);
            Assert.Contains("GetHashCode", names);
            Assert.Contains("GetType", names);
            Assert.Contains("Equals", names);
            Assert.Contains("MB", names);
 
            parameterDecl = (ParameterSyntax)methodDecl.ParameterList.Parameters[1];
            paramSymbol = model.GetDeclaredSymbol(parameterDecl);
            names = model.LookupNames(methodDecl.SpanStart, paramSymbol.Type);
            Assert.Equal(5, names.Count);
            Assert.Contains("ToString", names);
            Assert.Contains("ReferenceEquals", names);
            Assert.Contains("GetHashCode", names);
            Assert.Contains("GetType", names);
            Assert.Contains("Equals", names);
        }
 
        [Fact]
        public void TestLookupSymbolsInInterface()
        {
            var compilation = CreateCompilation(@"
                interface A
                {
                   void M<T>(T t);
                }
 
                interface B : A
                {
                   void M<T, U>(T t, U u);
                }
 
                interface C : B
                {
                   void F();
                   void M<T, U, V>(T t, U u, V v);
                }
            ", targetFramework: TargetFramework.NetStandard20);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
            int positionInC = someMemberInC.SpanStart;
 
            var symbolsInC = model.LookupSymbols(positionInC);
            var test = symbolsInC.Where(s => s.ContainingAssembly == null).ToList();
            Assert.Equal(9, symbolsInC.Where(s => s.ContainingType == null || s.ContainingType.SpecialType != SpecialType.System_Object).Count());
            Assert.True(symbolsInC.Any(s => s.Name == "A" && s.Kind == SymbolKind.NamedType));
            Assert.True(symbolsInC.Any(s => s.Name == "B" && s.Kind == SymbolKind.NamedType));
            Assert.True(symbolsInC.Any(s => s.Name == "C" && s.Kind == SymbolKind.NamedType));
            Assert.True(symbolsInC.Any(s => s.Name == "M" && s.Kind == SymbolKind.Method && s.ContainingType.Name == "A"));
            Assert.True(symbolsInC.Any(s => s.Name == "M" && s.Kind == SymbolKind.Method && s.ContainingType.Name == "B"));
            Assert.True(symbolsInC.Any(s => s.Name == "M" && s.Kind == SymbolKind.Method && s.ContainingType.Name == "C"));
            Assert.True(symbolsInC.Any(s => s.Name == "F" && s.Kind == SymbolKind.Method && s.ContainingType.Name == "C"));
            Assert.True(symbolsInC.Any(s => s.Name == "System" && s.Kind == SymbolKind.Namespace));
            Assert.True(symbolsInC.Any(s => s.Name == "Microsoft" && s.Kind == SymbolKind.Namespace));
        }
 
        [Fact]
        public void TestLookupSymbolsInTypeParameter()
        {
            var compilation = CreateCompilation(@"
interface IA
{
    void MA();
}
interface IB
{
    void MB();
}
interface IC
{
    void M<T, U>();
}
class C : IA
{
    void IA.MA() { }
    public void M<T>() { }
}
class D<T>
    where T : IB
{
    void MD<U, V>(U u, V v)
        where U : C, T, IC
        where V : struct
    {
    }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[4];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var parameterDecl = (ParameterSyntax)methodDecl.ParameterList.Parameters[0];
            var paramSymbol = model.GetDeclaredSymbol(parameterDecl);
            var symbols = model.LookupSymbols(methodDecl.SpanStart, paramSymbol.Type);
            CheckSymbolsUnordered(symbols,
                "void C.M<T>()",
                "void IC.M<T, U>()",
                "string object.ToString()",
                "bool object.Equals(object obj)",
                "bool object.Equals(object objA, object objB)",
                "bool object.ReferenceEquals(object objA, object objB)",
                "int object.GetHashCode()",
                "Type object.GetType()",
                "void IB.MB()");
 
            parameterDecl = (ParameterSyntax)methodDecl.ParameterList.Parameters[1];
            paramSymbol = model.GetDeclaredSymbol(parameterDecl);
            symbols = model.LookupSymbols(methodDecl.SpanStart, paramSymbol.Type);
            CheckSymbolsUnordered(symbols,
                "bool ValueType.Equals(object obj)",
                "bool object.Equals(object obj)",
                "bool object.Equals(object objA, object objB)",
                "int ValueType.GetHashCode()",
                "int object.GetHashCode()",
                "string ValueType.ToString()",
                "string object.ToString()",
                "bool object.ReferenceEquals(object objA, object objB)",
                "Type object.GetType()");
        }
 
        [Fact]
        public void TestLookupSymbolsTypeParameterConstraints()
        {
            var compilation = CreateCompilation(
@"interface I<T> where T : new() { }
class A
{
    void M<T>() where T : struct, I<int> { }
}
struct B<T> where T : A
{
    void M<U>() where U : T { }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var cu = tree.GetCompilationUnitRoot();
 
            var interfaceDecl = (InterfaceDeclarationSyntax)cu.Members[0];
            var symbol = LookupTypeParameterFromConstraintClause(model, interfaceDecl.ConstraintClauses[0], "T");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.Constructor);
 
            var classDecl = (ClassDeclarationSyntax)cu.Members[1];
            var methodDecl = (MethodDeclarationSyntax)classDecl.Members[0];
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "T");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.ValueType, "I<int>");
 
            var structDecl = (StructDeclarationSyntax)cu.Members[2];
            symbol = LookupTypeParameterFromConstraintClause(model, structDecl.ConstraintClauses[0], "T");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "A");
 
            methodDecl = (MethodDeclarationSyntax)structDecl.Members[0];
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "U");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "T");
        }
 
        /// <summary>
        /// Cycles should be broken at the first cycle encountered by
        /// traversing the constraints in declaration order. It should not depend
        /// on the order the symbols are queried from the binding API.
        /// </summary>
        [Fact]
        public void TestLookupSymbolsTypeParameterConstraintCycles()
        {
            var compilation = CreateCompilation(
@"interface IA<T1, T2>
    where T1 : T2
    where T2 : T1
{
    void M<U1, U2>()
        where U1 : U2
        where U2 : U1;
}
interface IB<T3, T4>
    where T3 : T4
    where T4 : T3
{
    void M<U3, U4>()
        where U3 : U4
        where U4 : U3;
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var cu = tree.GetCompilationUnitRoot();
 
            // Query for type parameters in declaration order.
            var interfaceDecl = (InterfaceDeclarationSyntax)cu.Members[0];
            var symbol = LookupTypeParameterFromConstraintClause(model, interfaceDecl.ConstraintClauses[0], "T1");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "T2");
            symbol = LookupTypeParameterFromConstraintClause(model, interfaceDecl.ConstraintClauses[0], "T2");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None);
            var methodDecl = (MethodDeclarationSyntax)interfaceDecl.Members[0];
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "U1");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "U2");
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "U2");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None);
 
            // Query for type parameters in reverse order.
            interfaceDecl = (InterfaceDeclarationSyntax)cu.Members[1];
            symbol = LookupTypeParameterFromConstraintClause(model, interfaceDecl.ConstraintClauses[0], "T4");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None);
            symbol = LookupTypeParameterFromConstraintClause(model, interfaceDecl.ConstraintClauses[0], "T3");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "T4");
            methodDecl = (MethodDeclarationSyntax)interfaceDecl.Members[0];
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "U4");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None);
            symbol = LookupTypeParameterFromConstraintClause(model, methodDecl.ConstraintClauses[0], "U3");
            CompilationUtils.CheckConstraints(symbol, TypeParameterConstraintKind.None, "U4");
        }
 
        private static ITypeParameterSymbol LookupTypeParameterFromConstraintClause(SemanticModel model, TypeParameterConstraintClauseSyntax constraintSyntax, string name)
        {
            var constraintStart = constraintSyntax.WhereKeyword.SpanStart;
            var symbols = model.LookupSymbols(constraintStart, null, name: name);
            Assert.Equal(1, symbols.Length);
            var symbol = symbols[0] as ITypeParameterSymbol;
            Assert.NotNull(symbol);
            return symbol;
        }
 
        [Fact]
        public void TestLookupSymbolsAllNames()
        {
            var compilation = CreateCompilation(@"
                class A
                {
                   public int X;
                }
 
                class B : A
                {
                   public int Y;
                }
 
                class C : B
                {
                   public int Z;
 
                   public void M()
                   {
                   }
                }
            ", targetFramework: TargetFramework.NetStandard20);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
 
            // specify (name = null) returns symbols for all names in scope
            var symbols = model.LookupNamespacesAndTypes(someMemberInC.SpanStart);
            Assert.Equal(5, symbols.Length);  // A, B, C, System, Microsoft
        }
 
        [Fact]
        public void TestLookupSymbolsAllNamesMustBeInstance()
        {
            var compilation = CreateCompilation(@"
                class A
                {
                   public int X;
                   public static int SX;
                }
 
                class B : A
                {
                   public int Y() { };
                   public static int SY() { };
                }
 
                class C : B
                {
                   public int Z;
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var symbolC = model.GetDeclaredSymbol(typeDeclC);
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
            int position = someMemberInC.SpanStart;
 
            var symbols = model.LookupSymbols(position).Where(s => !s.IsStatic && !((s is ITypeSymbol)));
            Assert.Equal(9, symbols.Count());  // A.X, B.Y, C.Z, Object.ToString, Object.Equals, Object.Finalize, Object.GetHashCode, Object.GetType, Object.MemberwiseClone
 
            var symbols2 = model.LookupSymbols(position, container: symbolC).Where(s => !s.IsStatic && !((s is ITypeSymbol)));
            Assert.Equal(9, symbols2.Count());  // A.X, B.Y, C.Z, Object.ToString, Object.Equals, Object.Finalize, Object.GetHashCode, Object.GetType, Object.MemberwiseClone
        }
 
        [Fact]
        public void TestLookupSymbolsAllNamesMustNotBeInstance()
        {
            var compilation = CreateCompilation(@"
                class A
                {
                   public int X;
                   public static int SX;
                }
 
                class B : A
                {
                   public int Y() { };
                   public static int SY() { };
                }
 
                class C : B
                {
                   public int Z;
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members[2];
            var symbolC = model.GetDeclaredSymbol(typeDeclC);
            var someMemberInC = (MemberDeclarationSyntax)typeDeclC.Members[0];
 
            var symbols = model.LookupStaticMembers(someMemberInC.SpanStart, container: symbolC);
            Assert.Equal(4, symbols.Length);  // A.SX, B.SY, Object.Equals, Object.ReferenceEquals
        }
 
        [Fact]
        public void TestLookupSymbolsExtensionMethods()
        {
            var compilation = (Compilation)CreateCompilation(
@"namespace N
{
    class C
    {
        void M()
        {
            this.E(1);
            this.F();
            this.G<int>();
        }
        void F() { }
    }
    static class S1
    {
        internal static void E(this object o, int x) { }
        internal static void F(this C c) { }
        internal static void G<T, U>(this object o) { }
        internal static void H(this int i) { }
    }
}
static class S2
{
    internal static void E(this N.C c) { }
    internal static void F<T>(this T t) { }
    internal static void G<T>(this object o) { }
    internal static void H(this double d) { }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var namespaceDecl = (NamespaceDeclarationSyntax)cu.Members[0];
            var typeDecl = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var statement = (ExpressionStatementSyntax)methodDecl.Body.Statements[0];
            var namespaceStart = namespaceDecl.OpenBraceToken.SpanStart;
            int typeDeclStart = typeDecl.OpenBraceToken.SpanStart;
            int statementStart = statement.SpanStart;
 
            var type = model.GetDeclaredSymbol(typeDecl);
            Assert.NotNull(type);
 
            Func<ISymbol, bool> isExtensionMethod = symbol =>
                symbol.Kind == SymbolKind.Method && (((IMethodSymbol)symbol).IsExtensionMethod || ((IMethodSymbol)symbol).MethodKind == MethodKind.ReducedExtension);
 
            // All extension methods available for specific type.
            var symbols = model.LookupSymbols(typeDeclStart, type, name: null, includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void object.E(int x)",
                "void C.F()",
                "void object.G<T, U>()",
                "void C.E()",
                "void C.F<C>()",
                "void object.G<T>()");
 
#if false
            // All extension methods of specific arity.
            symbols = model.LookupSymbols(typeDeclStart, type, name: null, arity: 0, includeReducedExtensionMethods: true);
            CheckSymbols(symbols,
                "bool object.Equals(object objA, object objB)",
                "bool object.ReferenceEquals(object objA, object objB)",
                "void object.E(int x)",
                "void C.F()",
                "void C.E()");
            symbols = model.LookupSymbols(typeDeclStart, type, name: null, arity: 1, includeReducedExtensionMethods: true);
            CheckSymbols(symbols,
                "void C.F<C>()",
                "void object.G<T>()");
            symbols = model.LookupSymbols(namespaceStart, type, name: null, arity: 2, includeReducedExtensionMethods: true);
            CheckSymbols(symbols,
                "void object.G<T, U>()");
#endif
 
            // All instance and extension methods of specific name.
            symbols = model.LookupSymbols(statementStart, type, "E", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "void object.E(int x)",
                "void C.E()");
            symbols = model.LookupSymbols(statementStart, type, "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "void C.F()",
                "void C.F()",
                "void C.F<C>()");
            symbols = model.LookupSymbols(statementStart, null, "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "void C.F()");
 
            // All extension methods for base type.
            var baseType = compilation.GetSpecialType(SpecialType.System_Object);
            symbols = model.LookupSymbols(namespaceStart, baseType, name: null, includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void object.E(int x)",
                "void object.G<T, U>()",
                "void object.F<object>()",
                "void object.G<T>()");
 
            // All extension methods of specific name for value type.
            var valueType = compilation.GetSpecialType(SpecialType.System_Int32);
            symbols = model.LookupSymbols(typeDeclStart, valueType, name: "E", includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void object.E(int x)");
 
            // Skip extension methods for which there are no "this" arg conversions.
            symbols = model.LookupSymbols(namespaceStart, valueType, name: "H", includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void int.H()");
 
            // All extension methods of unrecognized name.
            symbols = model.LookupSymbols(typeDeclStart, type, name: "C", includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols);
        }
 
        /// <summary>
        /// LookupSymbols should return partially constructed
        /// methods for generic extension methods.
        /// </summary>
        [Fact]
        public void TestLookupSymbolsGenericExtensionMethods()
        {
            var compilation = (Compilation)CreateCompilation(
@"class C
{
    static void M() { }
}
static class S
{
    internal static void E<T>(this System.Collections.Generic.IEnumerable<T> t) { }
    internal static void E<T, U>(this U u, T t) { }
    internal static void E<T, U>(this object o, T t, U u) { }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[0];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var methodStart = methodDecl.Body.OpenBraceToken.SpanStart;
 
            // All extension method overloads regardless of type.
            var symbols = model.LookupSymbols(methodStart, null, name: "E", includeReducedExtensionMethods: true);
            CheckSymbols(symbols);
 
            // All extension method overloads for IList<string>.
            var type = compilation.GetSpecialType(SpecialType.System_Collections_Generic_IList_T);
            type = type.Construct(compilation.GetSpecialType(SpecialType.System_String));
            Assert.NotNull(type);
            symbols = model.LookupSymbols(methodStart, type, name: "E", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "void IEnumerable<string>.E<string>()",
                "void IList<string>.E<T, IList<string>>(T t)",
                "void object.E<T, U>(T t, U u)");
 
            // All extension method overloads for double.
            type = compilation.GetSpecialType(SpecialType.System_Double);
            Assert.NotNull(type);
            symbols = model.LookupSymbols(methodStart, type, name: "E", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "void double.E<T, double>(T t)",
                "void object.E<T, U>(T t, U u)");
        }
 
        [WorkItem(541125, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541125")]
        [Fact]
        public void TestLookupSymbolsMoreGenericExtensionMethods()
        {
            var compilation = CreateCompilation(
@"using System;
class A<T> { }
class B<T> : A<T> { }
class C
{
    static void M(A<int> a, B<string> b) { }
}
static class S
{
    internal static void E0<T>() { }
    internal static void E1<T>(this B<T> b) { }
    internal static void E2<T>(this A<T> a, T t) { }
    internal static void E3<T>(this A<T> a, B<T> b, T t) { }
    internal static void E4<T>(this T t, A<T> a) { }
    internal static void E5<U, T>(this A<T> a, Func<T, U> f) { }
    internal static void E6<T, U>(this B<T> b, Func<T, U> f) { }
    internal static void E7<T>(this A<T> a, Action<A<T>> f) { }
    internal static void E8<T, U>(this B<string> b, Func<T, U> f) { }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[2];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var methodStart = methodDecl.Body.OpenBraceToken.SpanStart;
 
            // Get types for A<int> and B<string>.
            var symbols = model.LookupSymbols(methodStart, null, name: "a");
            CheckSymbolsUnordered(symbols, "A<int> a");
            var typeA = ((IParameterSymbol)symbols[0]).Type;
            Assert.NotNull(typeA);
            symbols = model.LookupSymbols(methodStart, null, name: "b");
            CheckSymbolsUnordered(symbols, "B<string> b");
            var typeB = ((IParameterSymbol)symbols[0]).Type;
            Assert.NotNull(typeB);
 
            Func<ISymbol, bool> isExtensionMethod = symbol =>
                symbol.Kind == SymbolKind.Method && (((IMethodSymbol)symbol).IsExtensionMethod || ((IMethodSymbol)symbol).MethodKind == MethodKind.ReducedExtension);
 
            // Extension methods for B<string>
            symbols = model.LookupSymbols(methodStart, typeB, name: null, includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void B<string>.E1<string>()",
                "void A<string>.E2<string>(string t)",
                "void A<string>.E3<string>(B<string> b, string t)",
                "void B<string>.E4<B<string>>(A<B<string>> a)",
                "void A<string>.E5<U, string>(Func<string, U> f)",
                "void B<string>.E6<string, U>(Func<string, U> f)",
                "void A<string>.E7<string>(Action<A<string>> f)",
                "void B<string>.E8<T, U>(Func<T, U> f)");
 
            // Extension methods for A<int>
            symbols = model.LookupSymbols(methodStart, typeA, name: null, includeReducedExtensionMethods: true).WhereAsArray(isExtensionMethod);
            CheckSymbolsUnordered(symbols,
                "void A<int>.E2<int>(int t)",
                "void A<int>.E3<int>(B<int> b, int t)",
                "void A<int>.E4<A<int>>(A<A<int>> a)",
                "void A<int>.E5<U, int>(Func<int, U> f)",
                "void A<int>.E7<int>(Action<A<int>> f)");
        }
 
        [WorkItem(544933, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544933")]
        [Fact]
        public void TestLookupSymbolsGenericExtensionMethodWithConstraints()
        {
            var source =
@"class A { }
class B { }
static class E
{
    static void M(A a, B b)
    {
        a.F();
        b.F();
    }
    internal static void F<T>(this T t) where T : A { }
}";
            var compilation = (Compilation)CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (8,11): error CS0311: The type 'B' cannot be used as type parameter 'T' in the generic type or method 'E.F<T>(T)'. There is no implicit reference conversion from 'B' to 'A'.
                //         b.F();
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "F").WithArguments("E.F<T>(T)", "A", "T", "B").WithLocation(8, 11)
);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var position = source.IndexOf("a.F()", StringComparison.Ordinal);
            var method = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("E").GetMember<IMethodSymbol>("M");
 
            // No type.
            var symbols = model.LookupSymbols(position, container: null, name: "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols, "void E.F<T>(T t)");
 
            // Type satisfying constraint.
            symbols = model.LookupSymbols(position, container: method.Parameters[0].Type, name: "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols, "void A.F<A>()");
 
            // Type not satisfying constraint.
            symbols = model.LookupSymbols(position, container: method.Parameters[1].Type, name: "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols);
 
            // Same tests as above but with position outside of
            // static class defining extension methods.
            source =
@"class A { }
class B { }
class C
{
    static void M(A a, B b)
    {
        a.F();
        b.F();
    }
}
static class E
{
    internal static void F<T>(this T t) where T : A { }
}";
            compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (8,11): error CS0311: The type 'B' cannot be used as type parameter 'T' in the generic type or method 'E.F<T>(T)'. There is no implicit reference conversion from 'B' to 'A'.
                //         b.F();
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "F").WithArguments("E.F<T>(T)", "A", "T", "B").WithLocation(8, 11));
 
            tree = compilation.SyntaxTrees.Single();
            model = compilation.GetSemanticModel(tree);
            position = source.IndexOf("a.F()", StringComparison.Ordinal);
            method = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("C").GetMember<IMethodSymbol>("M");
 
            // No type.
            symbols = model.LookupSymbols(position, container: null, name: "F", includeReducedExtensionMethods: true);
            CheckSymbols(symbols);
 
            // Type satisfying constraint.
            symbols = model.LookupSymbols(position, container: method.Parameters[0].Type, name: "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols, "void A.F<A>()");
 
            // Type not satisfying constraint.
            symbols = model.LookupSymbols(position, container: method.Parameters[1].Type, name: "F", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols);
        }
 
        [Fact]
        public void TestLookupSymbolsArrayExtensionMethods()
        {
            var compilation = CreateCompilation(
                source:
@"using System.Linq;
class C
{
    static void M(object[] o)
    {
    }
}");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDecl = (TypeDeclarationSyntax)cu.Members[0];
            var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
            var methodStart = methodDecl.Body.OpenBraceToken.SpanStart;
 
            // Get type for object[].
            var symbols = model.LookupSymbols(methodStart, null, name: "o");
            CheckSymbolsUnordered(symbols, "object[] o");
            var type = ((IParameterSymbol)symbols[0]).Type;
            Assert.NotNull(type);
 
            // Extension method overloads for o.First.
            symbols = model.LookupSymbols(methodStart, type, name: "First", includeReducedExtensionMethods: true);
            CheckSymbolsUnordered(symbols,
                "object IEnumerable<object>.First<object>()",
                "object IEnumerable<object>.First<object>(Func<object, bool> predicate)");
        }
 
        private static void CheckSymbols(ImmutableArray<ISymbol> symbols, params string[] descriptions)
        {
            CompilationUtils.CheckISymbols(symbols, descriptions);
        }
 
        private static void CheckSymbolsUnordered(ImmutableArray<ISymbol> symbols, params string[] descriptions)
        {
            CompilationUtils.CheckSymbolsUnordered(symbols, descriptions);
        }
 
        [Fact]
        public void TestLookupSymbolsWithEmptyStringForNameDoesNotAssert()
        {
            var compilation = CreateCompilation(@"
                class A
                {
                   public void M() 
                   { 
                      const
                   }
                }
            ");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclA = (TypeDeclarationSyntax)cu.Members[0];
            var methodM = (MethodDeclarationSyntax)typeDeclA.Members[0];
            var someStatementInM = methodM.Body.Statements[0];
 
            // check doesn't assert!
            var symbols = model.LookupNamespacesAndTypes(someStatementInM.SpanStart, name: "");
        }
 
        [Fact]
        public void TestLookupSymbolInCatch()
        {
            var text =
@"class C
{
    static void M()
    {
        try { }
        catch (System.Exception a) { }
    }
    static System.Action A = () =>
    {
        try { }
        catch (System.Exception b) { }
    };
}";
            var compilation = CreateCompilation(text);
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var position = text.IndexOf('{', text.IndexOf("a)", StringComparison.Ordinal));
            var symbols = model.LookupSymbols(position, name: "a");
            Assert.Equal(1, symbols.Length);
            position = text.IndexOf('{', text.IndexOf("b)", StringComparison.Ordinal));
            symbols = model.LookupSymbols(position, name: "b");
            Assert.Equal(1, symbols.Length);
        }
 
        [Fact]
        public void TestLookupSymbolAttributeType()
        {
            var text =
@"
using System;
using GooAttribute = System.ObsoleteAttribute;
 
namespace Blue
{
    public class DescriptionAttribute : Attribute
    {
        public DescriptionAttribute(string name) { }
    }
}
 
namespace Red
{
    public class DescriptionAttribute : Attribute
    {
        public DescriptionAttribute(string name) { }
    }
}
 
 
namespace Green
{
    using Blue;
    using Red;
 
    public class Test
    {
        [Description(null)]
        static void Main()
        {
        }
    }
}
 
[AttributeUsage(AttributeTargets.All)]
public class X : Attribute {}
 
[AttributeUsage(AttributeTargets.All)]
public class XAttribute : Attribute {}
 
[X()]
class Class1 {}
 
namespace InvalidWithoutSuffix
{
    public class Y
    {
        public Y(string name) { }
    }
}
 
namespace ValidWithSuffix
{
    public class YAttribute : System.Attribute
    {
        public YAttribute(string name) { }
    }
}
 
namespace TestNamespace_01
{
    using ValidWithSuffix;
    using InvalidWithoutSuffix;
 
    [Y(null)]
    public class Test { }
}
 
[Goo()]
class Bar { }
";
            var compilation = CreateCompilation(text);
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            Func<int, INamespaceOrTypeSymbol, string, bool, ImmutableArray<ISymbol>> lookupAttributeTypeWithQualifier = (pos, qualifierOpt, name, isVerbatim) =>
            {
                var options = isVerbatim ? LookupOptions.VerbatimNameAttributeTypeOnly : LookupOptions.AttributeTypeOnly;
 
                var binder = ((CSharpSemanticModel)model).GetEnclosingBinder(pos);
                Assert.NotNull(binder);
 
                var lookupResult = LookupResult.GetInstance();
                HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                binder.LookupSymbolsSimpleName(
                    lookupResult,
                    ((CSharp.Symbols.PublicModel.NamespaceOrTypeSymbol)qualifierOpt)?.UnderlyingNamespaceOrTypeSymbol,
                    plainName: name, arity: 0, basesBeingResolved: null, options: options, diagnose: false, useSiteDiagnostics: ref useSiteDiagnostics);
                Assert.Null(useSiteDiagnostics);
                var result = lookupResult.IsMultiViable ? lookupResult.Symbols.ToImmutable() : ImmutableArray.Create<Symbol>();
                lookupResult.Free();
                return result.SelectAsArray(s => s.GetPublicSymbol());
            };
 
            Func<int, string, bool, ImmutableArray<ISymbol>> lookupAttributeType = (pos, name, isVerbatim) =>
                lookupAttributeTypeWithQualifier(pos, null, name, isVerbatim);
 
            var position = text.IndexOf("Description(null)", 0, StringComparison.Ordinal);
            var symbols = lookupAttributeType(position, "Description", false);
            Assert.Equal(2, symbols.Length);
 
            symbols = lookupAttributeType(position, "Description", true);
            Assert.Equal(0, symbols.Length);
 
            position = text.IndexOf("X()", 0, StringComparison.Ordinal);
            symbols = lookupAttributeType(position, "X", false);
            Assert.Equal(2, symbols.Length);
 
            symbols = lookupAttributeType(position, "X", true);
            Assert.Equal(1, symbols.Length);
 
            position = text.IndexOf("Y(null)", 0, StringComparison.Ordinal);
            symbols = lookupAttributeType(position, "Y", false);
            Assert.Equal(1, symbols.Length);
 
            symbols = lookupAttributeType(position, "Y", true);
            Assert.Equal(0, symbols.Length);
 
            var position2 = text.IndexOf("namespace InvalidWithoutSuffix", 0, StringComparison.Ordinal);
            var qnSymbols = model.LookupNamespacesAndTypes(position2, name: "InvalidWithoutSuffix");
            Assert.Equal(1, qnSymbols.Length);
            var qnInvalidWithoutSuffix = (INamespaceOrTypeSymbol)qnSymbols[0];
 
            symbols = model.LookupNamespacesAndTypes(position, name: "Y", container: qnInvalidWithoutSuffix);
            Assert.Equal(1, symbols.Length);
 
            symbols = lookupAttributeTypeWithQualifier(position, qnInvalidWithoutSuffix, "Y", false);
            Assert.Equal(0, symbols.Length);
 
            symbols = lookupAttributeTypeWithQualifier(position, qnInvalidWithoutSuffix, "Y", true);
            Assert.Equal(0, symbols.Length);
 
            position = text.IndexOf("Goo()", 0, StringComparison.Ordinal);
            symbols = lookupAttributeType(position, "Goo", false);
            Assert.Equal(1, symbols.Length);
 
            symbols = lookupAttributeType(position, "Goo", true);
            Assert.Equal(0, symbols.Length);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfInvocation()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();     
  }
 
  string F()
  {
    return ""Hello"";
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)localDecl.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(invocation);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("String", info.Type.Name);
            Assert.NotNull(info.Symbol);
            Assert.Equal("F", info.Symbol.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfInvocationWithNoMatchingOverloads()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();     
  }
 
  string F(int x)
  {
    return ""Hello"";
  }
 
  string F(string x)
  {
    return x;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)localDecl.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(invocation);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("String", info.Type.Name);
            Assert.Null(info.Symbol);
            Assert.Equal(2, info.CandidateSymbols.Length);
            Assert.Equal("F", info.CandidateSymbols[0].Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfInvocationWithNoMatchingOverloadsAndNonMatchingReturnTypes()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();     
  }
 
  string F(int x)
  {
    return ""Hello"";
  }
 
  int F(string x)
  {
    return 0;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)localDecl.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(invocation);
            Assert.NotNull(info);
            Assert.Equal(TypeKind.Error, info.Type.TypeKind);
            Assert.Null(info.Symbol);
            Assert.Equal(2, info.CandidateSymbols.Length);
            Assert.Equal("F", info.CandidateSymbols[0].Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfIncompleteInvocation()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F(;
  }
 
  string F(int x)
  {
    return ""Hello"";
  }
 
  string F(string x)
  {
    return x;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)localDecl.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(invocation);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Null(info.Symbol);
            Assert.Equal(2, info.CandidateSymbols.Length);
            Assert.Equal("F", info.CandidateSymbols[0].Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfMethodGroupAccess()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();     
  }
 
  string F()
  { 
    return ""Hello"";
  }
 
  string F(int x)
  {
    return ""World"";
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)localDecl.Declaration.Variables[0].Initializer.Value;
            var methodGroup = invocation.Expression;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(methodGroup);
            Assert.NotNull(info);
            Assert.Null(info.Type);
            Assert.NotNull(info.Symbol);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfTypeName()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    C x = F();     
  }
 
  C F()
  { 
    return this;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var type = localDecl.Declaration.Type;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(type);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("C", info.Type.Name);
            Assert.NotNull(info.Symbol);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfTypeNameWithConflictingLocalName()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    int C = 10;
    C x = F();     
    int y = C;
  }
 
  C F()
  { 
    return this;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[1];
            var type = localDecl.Declaration.Type;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(type);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("C", info.Type.Name);
            Assert.NotNull(info.Symbol);
 
            // check that other references to 'C' in a non-type context bind to Int32
            localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[2];
            var init = localDecl.Declaration.Variables[0].Initializer.Value;
            info = model.GetSemanticInfoSummary(init);
            Assert.NotNull(info.Type);
            Assert.Equal("Int32", info.Type.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfNamespaceName()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    System.String x = F();
  }
 
  string F()
  { 
    return ""Hello"";
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var type = (QualifiedNameSyntax)localDecl.Declaration.Type;
            var ns = type.Left;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(ns);
            Assert.NotNull(info);
            Assert.Null(info.Type);
            Assert.NotNull(info.Symbol);
            Assert.Equal("System", info.Symbol.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfRightSideOfQualifiedName()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    N.D x = null;
  }
}
 
class D 
{
}
 
namespace N
{
  class D
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var type = (QualifiedNameSyntax)localDecl.Declaration.Type;
            var rightName = type.Right;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(rightName);
            Assert.NotNull(info.Type);
            // make sure that the model info for the name 'D' in this context tells us about the type 'N.D' not the type 'D'
            Assert.Equal("D", info.Type.Name);
            Assert.Equal("N", info.Type.ContainingNamespace.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfTypeInDeclaration()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();   
  }
 
  string F()
  { 
    return ""Hello"";
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[1];
            var type = methodDecl.ReturnType;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(type);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("String", info.Type.Name);
            Assert.NotNull(info.Symbol);
        }
 
        [Fact]
        public void TestGetSemanticInfoOfNamespaceInDeclaration()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    string x = F();
  }
 
  System.String F()
  { 
    return ""Hello"";
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[1];
            var type = (QualifiedNameSyntax)methodDecl.ReturnType;
            var ns = type.Left;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(ns);
            Assert.NotNull(info);
            Assert.Null(info.Type);
            Assert.NotNull(info.Symbol);
            Assert.Equal("System", info.Symbol.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoInParentInLocalInitializer()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    double x = 10;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var initializer = localDecl.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(initializer);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Double", info.ConvertedType.Name);
            Assert.Null(info.Symbol);
            Assert.Equal(0, info.CandidateSymbols.Length);
        }
 
        [Fact]
        public void TestGetSemanticInfoInParentInMultipleLocalInitializers()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    double x = 10, y = 20;
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var model = compilation.GetSemanticModel(tree);
 
            var info = model.GetSemanticInfoSummary(localDecl.Declaration.Variables[0].Initializer.Value);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Double", info.ConvertedType.Name);
 
            info = model.GetSemanticInfoSummary(localDecl.Declaration.Variables[1].Initializer.Value);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Double", info.ConvertedType.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoInParentInArgument()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    F(10);
  }
 
  void F(double p)
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var exprStmt = (ExpressionStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)exprStmt.Expression;
            var arg = invocation.ArgumentList.Arguments[0].Expression;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(arg);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Double", info.ConvertedType.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoInParentInMultipleArguments()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    F(10, 20);
  }
 
  void F(double p, long p2)
  {
  }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var exprStmt = (ExpressionStatementSyntax)methodDecl.Body.Statements[0];
            var invocation = (InvocationExpressionSyntax)exprStmt.Expression;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(invocation.ArgumentList.Arguments[0].Expression);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Double", info.ConvertedType.Name);
 
            info = model.GetSemanticInfoSummary(invocation.ArgumentList.Arguments[1].Expression);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Int64", info.ConvertedType.Name);
        }
 
        [Fact]
        public void UsingStaticClass()
        {
            string test = @"
public static class S1
{
    public static void goo(int a)
    {
    }
}
 
public static class S2
{
    public static void goo(string a)
    {
    }
}
 
namespace A
{
    using static S1;
 
    namespace B
    {
        using static S2;
 
        public static class Z
        {
            public static void M()
            {
                goo(""sss"");
                goo(1);
            }
        }
    }
}
";
            var tree = SyntaxFactory.ParseSyntaxTree(test, options: new CSharpParseOptions(languageVersion: LanguageVersion.CSharp6));
 
            var compilation = CSharpCompilation.Create(
                assemblyName: "Test",
                options: TestOptions.DebugExe.WithScriptClassName("Script"),
                syntaxTrees: new[] { tree },
                references: new[] { MscorlibRef });
 
            var expr = tree.FindNodeOrTokenByKind(SyntaxKind.StringLiteralToken).Parent.FirstAncestorOrSelf<ExpressionStatementSyntax>().Expression;
 
            var global = compilation.GlobalNamespace;
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(expr);
 
            Assert.NotNull(info.Symbol);
        }
 
        [WorkItem(537932, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537932")]
        [Fact]
        public void GetDeclaredSymbolDupAliasNameErr()
        {
            var compilation = (Compilation)CreateCompilation(@"
namespace NS {  class A {}  }
 
namespace NS {
    using System;
    using B = NS.A;
 
    class B {}
}
");
 
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var n1 = globalNS.GetMembers("NS").First() as INamespaceSymbol;
            var typeB = n1.GetTypeMembers("B").First() as INamedTypeSymbol;
            Assert.Equal(2, root.Members.Count);
            var nsSyntax = (root.Members[1] as NamespaceDeclarationSyntax);
            Assert.Equal(1, nsSyntax.Members.Count);
            var classB = model.GetDeclaredSymbol(nsSyntax.Members[0] as TypeDeclarationSyntax);
            // Reference equal
            Assert.Equal(typeB, classB);
        }
 
        [WorkItem(537624, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537624")]
        [Fact]
        public void GetDeclaredSymbolForUsingDirective()
        {
            var compilation = CreateCompilation(@"
namespace N1 {
};
 
namespace N2 {
  using N1;
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var n2 = (NamespaceDeclarationSyntax)root.Members[1];
            var u1 = (UsingDirectiveSyntax)n2.Usings[0];
 
            var info = model.GetSemanticInfoSummary(u1.Name);
            var n1 = info.Symbol;
 
            Assert.Equal("N1", n1.Name);
            Assert.Equal(SymbolKind.Namespace, n1.Kind);
        }
 
        [Fact]
        public void GetDeclaredSymbolForExplicitImplementations()
        {
            var compilation = CreateCompilation(@"
interface I
{
    void M();
    int P { get; set; }
}
class C : I
{
    void I.M() {}
    int I.P { get; set; }
}
");
 
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var root = tree.GetCompilationUnitRoot();
 
            var classNode = (TypeDeclarationSyntax)root.Members[1];
            Assert.Equal("C", classNode.Identifier.ValueText);
 
            var classMemberNodes = classNode.Members;
 
            var explicitMethodNode = (MethodDeclarationSyntax)classMemberNodes[0];
            Assert.Equal("M", explicitMethodNode.Identifier.ValueText);
 
            var explicitMethodSymbol = (IMethodSymbol)model.GetDeclaredSymbol(explicitMethodNode);
            Assert.NotNull(explicitMethodSymbol);
            Assert.Equal(MethodKind.ExplicitInterfaceImplementation, explicitMethodSymbol.MethodKind);
            Assert.Equal("I.M", explicitMethodSymbol.Name);
            Assert.Equal(1, explicitMethodSymbol.ExplicitInterfaceImplementations.Length);
 
            var explicitPropertyNode = (PropertyDeclarationSyntax)classMemberNodes[1];
            Assert.Equal("P", explicitPropertyNode.Identifier.ValueText);
 
            var explicitPropertySymbol = (IPropertySymbol)model.GetDeclaredSymbol(explicitPropertyNode);
            Assert.NotNull(explicitPropertySymbol);
            Assert.Equal("I.P", explicitPropertySymbol.Name);
            Assert.Equal(1, explicitPropertySymbol.ExplicitInterfaceImplementations.Length);
 
            var explicitPropertyAccessors = explicitPropertyNode.AccessorList.Accessors;
            Assert.Equal(2, explicitPropertyAccessors.Count);
 
            var explicitPropertyGetterNode = explicitPropertyAccessors[0];
            Assert.Equal("get", explicitPropertyGetterNode.Keyword.ValueText);
 
            var explicitPropertyGetterSymbol = (IMethodSymbol)model.GetDeclaredSymbol(explicitPropertyGetterNode);
            Assert.NotNull(explicitPropertyGetterSymbol);
            Assert.Equal(MethodKind.PropertyGet, explicitPropertyGetterSymbol.MethodKind);
            Assert.Equal("I.get_P", explicitPropertyGetterSymbol.Name);
            Assert.Equal(1, explicitPropertyGetterSymbol.ExplicitInterfaceImplementations.Length);
            Assert.Same(explicitPropertySymbol.GetMethod, explicitPropertyGetterSymbol);
 
            var explicitPropertySetterNode = explicitPropertyAccessors[1];
            Assert.Equal("set", explicitPropertySetterNode.Keyword.ValueText);
 
            var explicitPropertySetterSymbol = (IMethodSymbol)model.GetDeclaredSymbol(explicitPropertySetterNode);
            Assert.NotNull(explicitPropertySetterSymbol);
            Assert.Equal(MethodKind.PropertySet, explicitPropertySetterSymbol.MethodKind);
            Assert.Equal("I.set_P", explicitPropertySetterSymbol.Name);
            Assert.Equal(1, explicitPropertySetterSymbol.ExplicitInterfaceImplementations.Length);
            Assert.Same(explicitPropertySymbol.SetMethod, explicitPropertySetterSymbol);
        }
 
        [WorkItem(527284, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527284")]
        [Fact]
        public void GetDeclaredSymbolDottedNSAPI()
        {
            var compilation = (Compilation)CreateCompilation(@"
namespace N1 {
  namespace N2.N3
  {
    class C {}
  }
}
");
 
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var n1 = globalNS.GetMembers().First() as INamespaceSymbol;
            var n2 = n1.GetMembers().First() as INamespaceSymbol;
            var n3 = n2.GetMembers().First() as INamespaceSymbol;
 
            var nsSyntax = (root.Members[0] as NamespaceDeclarationSyntax);
            var dn1 = model.GetDeclaredSymbol(nsSyntax);
 
            var nsSyntax23 = (nsSyntax.Members[0] as NamespaceDeclarationSyntax);
            var dn23 = model.GetDeclaredSymbol(nsSyntax23);
 
            // Reference equal
            Assert.Equal(n1, dn1);
            Assert.Equal(n3, dn23);
        }
 
        [WorkItem(527285, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527285")]
        [Fact]
        public void GetDeclaredSymbolGlobalSystemNSErr()
        {
            var compilation = (Compilation)CreateCompilation(@"
namespace global::System {}
 
class Test { }
");
 
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var compSym = compilation.GlobalNamespace.GetMembers("System").First() as INamespaceSymbol;
 
            var nsSyntax = (root.Members[0] as NamespaceDeclarationSyntax);
            var declsym = model.GetDeclaredSymbol(nsSyntax);
            // Reference equal
            Assert.Equal(compSym, declsym);
        }
 
        [WorkItem(527286, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527286")]
        [Fact]
        public void GetDeclaredSymbolInvalidOverloadsErr()
        {
            var compilation = (Compilation)CreateCompilation(@"
class CGoo
{
    void M() {}
    int M() { return 0; }
 
    interface IGoo {}
    struct SGoo
    {
        void M(byte p) {}
        void M(ref byte p) {}
        void M(out byte p) {}
    }
}
");
 
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
 
            var sym1 = globalNS.GetMembers("CGoo").First() as INamedTypeSymbol;
            var mems = sym1.GetMembers("M");
            var node1 = (root.Members[0] as TypeDeclarationSyntax);
 
            var dsyma1 = model.GetDeclaredSymbol(node1.Members[0] as MethodDeclarationSyntax);
            var dsyma2 = model.GetDeclaredSymbol(node1.Members[1]);
            // By Design - conflicting overloads bind to distinct symbols
            Assert.NotEqual(dsyma1, dsyma2);
            // for CC?
            var sym2 = sym1.GetMembers("IGoo").First() as INamedTypeSymbol;
            var node2 = (node1.Members[2] as TypeDeclarationSyntax);
            var dsym2 = model.GetDeclaredSymbol(node2);
            Assert.Equal(TypeKind.Interface, dsym2.TypeKind);
 
            var sym3 = sym1.GetMembers("SGoo").First() as INamedTypeSymbol;
            var node3 = (node1.Members[3] as TypeDeclarationSyntax);
            // CC?
            var dsym3 = model.GetDeclaredSymbol(node3);
            Assert.Equal(TypeKind.Struct, dsym3.TypeKind);
 
            var mems2 = sym3.GetMembers("M");
 
            Assert.Equal(3, mems2.Length);
            var dsymc1 = model.GetDeclaredSymbol(node3.Members[0] as MethodDeclarationSyntax);
            var dsymc2 = model.GetDeclaredSymbol(node3.Members[1] as MethodDeclarationSyntax);
            var dsymc3 = model.GetDeclaredSymbol(node3.Members[2] as MethodDeclarationSyntax);
 
            Assert.Same(mems2[0], dsymc1);
            Assert.Same(mems2[1], dsymc2);
            Assert.Same(mems2[2], dsymc3);
        }
 
        [WorkItem(537953, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537953")]
        [Theory]
        [MemberData(nameof(FileScopedOrBracedNamespace))]
        public void GetDeclaredSymbolNoTypeSymbolWithErr(string ob, string cb)
        {
            var compilation = (Compilation)CreateCompilation(@"
namespace NS
" + ob + @"
  protected class A { }
" + cb + @"
");
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var ns1 = globalNS.GetMembers("NS").Single() as INamespaceSymbol;
            var srcSym = ns1.GetMembers("A").Single() as INamedTypeSymbol;
 
            var nsSyntax = (root.Members[0] as BaseNamespaceDeclarationSyntax);
            var declSym = model.GetDeclaredSymbol(nsSyntax.Members[0] as TypeDeclarationSyntax);
 
            Assert.Equal(srcSym, declSym);
        }
 
        [WorkItem(537954, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537954")]
        [Fact]
        public void GetDeclaredSymbolExtraForDupTypesErr()
        {
            var compilation = CreateCompilation(@"
namespace NS
{
    static class Test { }
 
    // CS0101
    class Test { }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var ns1 = globalNS.GetMembers("NS").Single() as NamespaceSymbol;
            var mems = ns1.GetMembers("Test");
            Assert.Equal(1, mems.Length);
 
            var nsSyntax = (root.Members[0] as NamespaceDeclarationSyntax);
            var dsym1 = model.GetDeclaredSymbol(nsSyntax.Members[0] as TypeDeclarationSyntax);
            var dsym2 = model.GetDeclaredSymbol(nsSyntax.Members[1] as TypeDeclarationSyntax);
 
            Assert.Equal(dsym1, dsym2);
        }
 
        [WorkItem(537955, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537955")]
        [Fact]
        public void GetDeclaredSymbolSameNameMethodsDiffNSs()
        {
            var compilation = (Compilation)CreateCompilation(@"
namespace Goo {
    class A { }
}
 
namespace NS {
    using Goo;
    class A { }
}
");
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var ns1 = globalNS.GetMembers("NS").Single() as INamespaceSymbol;
            var typeA = ns1.GetTypeMembers("A").First() as INamedTypeSymbol;
 
            var nsSyntax = (root.Members[1] as NamespaceDeclarationSyntax);
            var dsym1 = model.GetDeclaredSymbol(nsSyntax.Members[0] as TypeDeclarationSyntax);
 
            Assert.Equal(typeA, dsym1);
        }
 
        [Fact]
        public void GetDeclaredSymbolNSCrossComps()
        {
            var comp1 = CreateCompilation(@"
namespace NS1 {
    namespace NS2 {    class A { }    }
    namespace NS2 {    class B { }    }
}
");
            var text2 = @"
namespace NS1 {
    namespace NS2 {    class C { }    }
}
";
 
            var ref1 = new CSharpCompilationReference(comp1);
 
            var comp = (Compilation)CSharpCompilation.Create(
                "Repro",
                new[] { SyntaxFactory.ParseSyntaxTree(text2) },
                new[] { MscorlibRef, ref1 });
 
            var tree = comp.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = comp.GetSemanticModel(tree);
 
            var nsg = comp.GlobalNamespace;
            var ns1 = nsg.GetMembers("NS1").Single() as INamespaceSymbol;
            var ns2 = ns1.GetMembers("NS2").Single() as INamespaceSymbol;
 
            var nsSyntax1 = (root.Members[0] as NamespaceDeclarationSyntax);
            var nsSyntax2 = (nsSyntax1.Members[0] as NamespaceDeclarationSyntax);
            var dsym1 = model.GetDeclaredSymbol(nsSyntax1);
            var dsym2 = model.GetDeclaredSymbol(nsSyntax2);
 
            Assert.Equal(ns1, dsym1);
            Assert.Equal(ns2, dsym2);
        }
 
        [WorkItem(538953, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538953")]
        [Fact]
        public void GetDeclaredSymbolAccessorErrs1()
        {
            var text1 =
@"public sealed class ErrorProp
{
    public string Prop1 { get { return null; } protected } // CS1007
    public int Prop2 { protected get { return 1; } set { } protected get { return 1; } } // CS1014
}
";
 
            var compilation = (Compilation)CreateCompilation(text1);
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var model = compilation.GetSemanticModel(tree);
 
            var globalNS = compilation.SourceModule.GlobalNamespace;
            var typeA = globalNS.GetTypeMembers("ErrorProp").First() as INamedTypeSymbol;
 
            var prop = typeA.GetMembers("Prop1").FirstOrDefault() as IPropertySymbol;
            var synType = root.Members[0] as TypeDeclarationSyntax;
            var accessors = (synType.Members[0] as PropertyDeclarationSyntax).AccessorList;
            var dsym = model.GetDeclaredSymbol(accessors.Accessors[0]);
            Assert.Equal(prop.GetMethod, dsym);
            dsym = model.GetDeclaredSymbol(accessors.Accessors[1]);
            Assert.Null(dsym);
 
            prop = typeA.GetMembers("Prop2").FirstOrDefault() as IPropertySymbol;
            accessors = (synType.Members[1] as PropertyDeclarationSyntax).AccessorList;
            dsym = model.GetDeclaredSymbol(accessors.Accessors[0]);
            Assert.Equal(prop.GetMethod, dsym);
            dsym = model.GetDeclaredSymbol(accessors.Accessors[1]);
            Assert.Equal(prop.SetMethod, dsym);
            dsym = model.GetDeclaredSymbol(accessors.Accessors[2]);
            Assert.Null(dsym);
        }
 
        [WorkItem(538953, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538953")]
        [Fact]
        public void GetDeclaredSymbolAccessorErrs2()
        {
            var text =
@"
public sealed class ErrorProp
{
    public string Prop1 { goo { return null; } } // invalid accessor name
}
";
            var compilation = CreateCompilation(text);
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var accessorDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AccessorDeclarationSyntax>().Single();
            Assert.Equal(SyntaxKind.UnknownAccessorDeclaration, accessorDecl.Kind());
            Assert.Null(model.GetDeclaredSymbol(accessorDecl));
        }
 
        [WorkItem(538148, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538148")]
        [Fact]
        public void TestOverloadsInImplementedInterfaceMethods()
        {
            var compilation = CreateCompilation(@"
class WorksheetClass : IWorksheet
{
    public int M1()
    {
        return 0;
    }
}
interface IWorksheet
{
    int M1();
}
 
public class MainClass
{
    public static void Main ()
    {
        WorksheetClass w = new WorksheetClass();
        IWorksheet iw = w;
        
        int i = w.M1() + iw.M1();
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[2]).Members[0];
            var declStmt = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[2];
            var expr = (ExpressionSyntax)declStmt.Declaration.Variables[0].Initializer.Value;
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(expr);
            Assert.NotNull(info.ConvertedType);
            Assert.Equal("Int32", info.ConvertedType.Name);
        }
 
        [Fact]
        public void TestGetSemanticInfoBrokenDecl()
        {
            var compilation = (Compilation)CreateCompilation(@"
class C 
{
  void F()
  {
    strin g;
  }
}
");
            var tree = compilation.SyntaxTrees.First();
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
 
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSemanticInfoSummary(localDecl.Declaration.Type);
            Assert.NotNull(info);
            Assert.NotNull(info.Type);
            Assert.Equal("strin", info.Type.Name);
            Assert.Equal(compilation.Assembly.GlobalNamespace, info.Type.ContainingSymbol); //error type resides in global namespace
        }
 
        [Fact]
        public void TestGetSemanticInfoMethodGroupConversion()
        {
            var compilation = CreateCompilation(@"
class C 
{
  void M()
  {
    D1 x = N;
    P(N);
  }
  delegate void D1(int q);
  delegate void D2();
  static void N() {}
  static void N(int x) {}
  static void P(D2 d){}
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
 
            // The info for "N" in the initializer should be the specific method, N(int). 
 
            var localDecl = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
            var initializer = localDecl.Declaration.Variables[0].Initializer.Value;
 
            var initInfo = model.GetSemanticInfoSummary(initializer);
            Assert.Null(initInfo.Type);
            Assert.NotNull(initInfo.ConvertedType);
            Assert.Equal("D1", initInfo.ConvertedType.Name);
            Assert.NotNull(initInfo.Symbol);
            Assert.Equal("C.N(int)", initInfo.Symbol.ToDisplayString());
 
            // Similarly for P(N) -- N is a method, not a method group.
 
            var expressionStmt = (ExpressionStatementSyntax)methodDecl.Body.Statements[1];
            var invocation = (InvocationExpressionSyntax)expressionStmt.Expression;
            var argument = invocation.ArgumentList.Arguments[0].Expression;
 
            var argInfo = model.GetSemanticInfoSummary(argument);
            Assert.NotNull(argInfo.ConvertedType);
            Assert.Equal("D2", argInfo.ConvertedType.Name);
            Assert.Null(argInfo.Type);
            Assert.NotNull(argInfo.Symbol);
            Assert.Equal("C.N()", argInfo.Symbol.ToDisplayString());
        }
 
        // named and optional parameters
        [WorkItem(539346, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539346")]
        [WorkItem(540792, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540792")]
        [Fact]
        public void TestGetDeclaredSymbolForParamInLambdaExprPrecededByExplicitKeyword()
        {
            var compilation = CreateCompilation(@"
using System;
class Program
{
    static void Main(string[] args)
    {
        explicit
        Func<int, int> f1 = (param1) => 10;
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the parameter node from the SyntaxTree for the lambda parameter "param1"
            var paramNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("param1", StringComparison.Ordinal)).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(paramNode);
 
            Assert.NotNull(symbol);
        }
 
        //named and optional parameters
        [WorkItem(539346, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539346")]
        [WorkItem(540792, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540792")]
        [Fact]
        public void TestGetDeclaredSymbolForLambdaInDefaultValue1()
        {
            var compilation = CreateCompilation(@"
using System;
class Program
{
    void Goo(Func<int, int> f = x => 1)
    {
    }
}
");
            var tree = compilation.SyntaxTrees[0];
 
            // Get the parameter node from the SyntaxTree for the lambda parameter "param1"
            var root = tree.GetCompilationUnitRoot();
            var paramNode = root.FindToken(root.ToFullString().IndexOf('x')).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(paramNode);
 
            Assert.NotNull(symbol);
        }
 
        [WorkItem(540792, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540792")]
        [WorkItem(539346, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539346")]
        [Fact]
        public void TestGetDeclaredSymbolForLambdaInDefaultValue2()
        {
            var compilation = CreateCompilation(@"
using System;
class Program
{
    void Goo(Func<int, Func<int, int>> f = w => x => 1)
    {
    }
}
");
            var tree = compilation.SyntaxTrees[0];
 
            // Get the parameter node from the SyntaxTree for the lambda parameter "param1"
            var root = tree.GetCompilationUnitRoot();
            var paramNode = root.FindToken(root.ToFullString().IndexOf('x')).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(paramNode);
 
            Assert.NotNull(symbol);
        }
 
        [WorkItem(540834, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540834")]
        [Fact]
        public void TestGetDeclaredSymbolForIncompleteMemberNode()
        {
            var compilation = CreateCompilation(@"private");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the IncompleteMemberNode which is the first child node of the root of the tree.
            var node = root.ChildNodes().First();
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(node);
 
            Assert.Equal(SyntaxKind.IncompleteMember, node.Kind());
            Assert.Null(symbol);
        }
 
        [WorkItem(7358, "DevDiv_Projects/Roslyn")]
        [Fact]
        public void TestGetDeclaredSymbolForeachStmtWithPointerType()
        {
            var compilation = CreateCompilation(@"
class Test
{
    static void Main(string[] args)
    {
        foreach (var x in new int*
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the foreach syntax node from the SyntaxTree
            var foreachNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("foreach", StringComparison.Ordinal)).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(foreachNode);
 
            Assert.NotNull(symbol);
        }
 
        [WorkItem(541057, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541057")]
        [Fact]
        public void TestGetDeclaredSymbolConstDelegateDecl()
        {
            var compilation = CreateCompilation(@"
public class Test
{
    const delegate
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the delegate declaration syntax node from the SyntaxTree
            var delegateNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("delegate", StringComparison.Ordinal)).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(delegateNode);
 
            Assert.NotNull(symbol);
        }
 
        [WorkItem(541084, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541084")]
        [Fact]
        public void TestIncompleteUsingDirectiveSyntax()
        {
            var compilation = CreateCompilation(@"
using myType1 =
");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the using directive syntax node from the SyntaxTree
            var usingNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("using", StringComparison.Ordinal)).Parent;
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(usingNode);
 
            Assert.NotNull(symbol);
            Assert.Equal(SymbolKind.Alias, symbol.Kind);
        }
 
        [WorkItem(541225, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541225")]
        [Fact]
        public void TestGetDeclaredSymbolForeachStmt()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void Main(string[] args)
    {
        int x;
        foreach (var aaa in args)
        {
            int z;
        }
    }
}
");
            var tree = compilation.SyntaxTrees[0];
 
            // Get the foreach syntax node from the SyntaxTree
            var foreachNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("aaa", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.ForEachStatement, foreachNode.Kind());
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(foreachNode);
            Assert.Equal("aaa", symbol.Name);
        }
 
        [WorkItem(541225, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541225")]
        [Fact]
        public void TestGetDeclaredSymbolForeachStmtError1()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void Main(string[] args)
    {
        int x;
        foreach (var aaa in args)
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            // Get the foreach syntax node from the SyntaxTree
            var foreachNode = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("aaa", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.ForEachStatement, foreachNode.Kind());
 
            var symbol = model.GetDeclaredSymbol(foreachNode);
            Assert.Equal("aaa", symbol.Name);
        }
 
        [WorkItem(541225, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541225")]
        [Fact]
        public void TestGetDeclaredSymbolForeachStmtError2()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void Main(string[] args)
    {
        int x;
        foreach (var aaa in args)
            foreach (var bbb in args)
 
namespace N
{
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var foreachNode1 = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("aaa", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.ForEachStatement, foreachNode1.Kind());
 
            var symbol1 = model.GetDeclaredSymbol(foreachNode1);
            Assert.Equal("aaa", symbol1.Name);
 
            var foreachNode2 = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("bbb", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.ForEachStatement, foreachNode2.Kind());
 
            var symbol2 = model.GetDeclaredSymbol(foreachNode2);
            Assert.Equal("bbb", symbol2.Name);
        }
 
        [WorkItem(541225, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541225")]
        [Fact]
        public void TestGetDeclaredSymbolCatchClause()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void Main(string[] args)
    {
        int x;
        try
        {
            int y;
        }
        catch (System.Exception aaa)
        {
            int z;
        }
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var catchDeclaration = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("aaa", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.CatchDeclaration, catchDeclaration.Kind());
 
            var symbol = model.GetDeclaredSymbol(catchDeclaration);
            Assert.Equal("aaa", symbol.Name);
        }
 
        [WorkItem(541214, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541214")]
        [Fact]
        public void TestGetDeclaredSymbolTopLevelMethod()
        {
            var compilation = CreateCompilation(@"
using System;
class void Goo()
{
    int x;
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var methodDecl = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("Goo", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.LocalFunctionStatement, methodDecl.Kind());
 
            var symbol = model.GetDeclaredSymbol(methodDecl);
            Assert.Equal(SymbolKind.Method, symbol.Kind);
            Assert.Equal("Goo", symbol.Name);
        }
 
        [WorkItem(541214, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541214")]
        [Fact]
        public void TestGetDeclaredSymbolNamespaceLevelMethod()
        {
            var compilation = CreateCompilation(@"
using System;
namespace N
{
    class void Goo()
    {
        int x;
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var methodDecl = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("Goo", StringComparison.Ordinal)).Parent;
            Assert.Equal(SyntaxKind.MethodDeclaration, methodDecl.Kind());
 
            var symbol = model.GetDeclaredSymbol(methodDecl);
            Assert.Equal(SymbolKind.Method, symbol.Kind);
            Assert.Equal("Goo", symbol.Name);
        }
 
        [WorkItem(543238, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543238")]
        [Fact]
        public void TestGetDeclaredSymbolEnumMemberDeclarationSyntax()
        {
            var compilation = CreateCompilation(@"
using System;
enum EnumX
{
    FieldM = 0
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var enumDecl = (EnumDeclarationSyntax)cu.Members[0];
            MemberDeclarationSyntax enumMemberDecl = enumDecl.Members[0];
            Assert.Equal(SyntaxKind.EnumMemberDeclaration, enumMemberDecl.Kind());
 
            var enumTypeSymbol = model.GetDeclaredSymbol(enumDecl);
            Assert.Equal(SymbolKind.NamedType, enumTypeSymbol.Kind);
            Assert.Equal("EnumX", enumTypeSymbol.Name);
 
            var symbol = model.GetDeclaredSymbol(enumMemberDecl);
            Assert.Equal(SymbolKind.Field, symbol.Kind);
            Assert.Equal("FieldM", symbol.Name);
            Assert.Equal(enumTypeSymbol, symbol.ContainingType);
 
            var fSymbol = model.GetDeclaredSymbol((EnumMemberDeclarationSyntax)enumMemberDecl);
            Assert.Equal("FieldM", fSymbol.Name);
            Assert.Equal(enumTypeSymbol, fSymbol.ContainingType);
        }
 
        [Fact]
        public void TestLambdaParameterInLambda()
        {
            var compilation = CreateCompilation(@"
using System;
delegate int D(int x);
class Program
{
    public static void Main(string[] args)
    {
        D d = (int x) => x;
        Console.WriteLine(d(3));
    }
}");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            dynamic methodDecl = (MethodDeclarationSyntax)tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf("Main", StringComparison.Ordinal)).Parent;
            IdentifierNameSyntax x = methodDecl.Body.Statements[0].Declaration.Variables[0].Initializer.Value.Body;
            var info = model.GetSemanticInfoSummary(x);
            Assert.Equal(SymbolKind.Parameter, info.Symbol.Kind);
            var parameter = (IParameterSymbol)info.Symbol;
            Assert.Equal("x", parameter.Name);
            Assert.Equal(SpecialType.System_Int32, parameter.Type.SpecialType);
        }
 
        [WorkItem(541800, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541800")]
        [Fact]
        public void GetDeclaredSymbolOnGlobalStmtParseOptionScript()
        {
            var parseOptions = TestOptions.Script;
            var compilation = CreateCompilation(@"/", parseOptions: parseOptions);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var globalStmt = tree.GetCompilationUnitRoot().FindToken(tree.GetCompilationUnitRoot().ToFullString().IndexOf('/')).Parent.AncestorsAndSelf().Single(x => x.IsKind(SyntaxKind.GlobalStatement));
 
            var symbol = model.GetDeclaredSymbol(globalStmt);
 
            Assert.Null(symbol);
        }
 
        [WorkItem(542102, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542102")]
        [Fact]
        public void GetSymbolInGoto()
        {
            var compilation = CreateCompilation(@"
class Program
{
    static void Main()
    {
    Goo:
        int Goo;
        goto Goo;
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var methodDecl = (MethodDeclarationSyntax)((TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]).Members[0];
            var gotoStatement = (GotoStatementSyntax)methodDecl.Body.Statements[1];
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetSemanticInfoSummary(gotoStatement.Expression).Symbol;
            Assert.Equal(SymbolKind.Label, symbol.Kind);
        }
 
        [WorkItem(542342, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542342")]
        [Fact]
        public void SourceNamespaceSymbolMergeWithMetadata()
        {
            var compilation = (Compilation)CreateEmptyCompilation(new string[] {
@"namespace System {
    public partial class PartialClass 
    {
        public int Prop { get; set; }
    }
}",
@"namespace System
{
    public partial class PartialClass 
    {
        public int this[int i] { get { return i; } set {} }
    }
}"},
new[] { MscorlibRef });
 
            var tree = compilation.SyntaxTrees.First();
            var root = tree.GetCompilationUnitRoot();
            var decl = (NamespaceDeclarationSyntax)root.Members[0];
            var model = compilation.GetSemanticModel(tree);
            var declSymbol = model.GetDeclaredSymbol(decl);
            Assert.NotNull(declSymbol);
            Assert.Equal("System", declSymbol.Name);
            Assert.Equal(3, declSymbol.Locations.Length);
            Assert.IsType<MergedNamespaceSymbol>(declSymbol.GetSymbol());
            Assert.Equal(NamespaceKind.Compilation, declSymbol.NamespaceKind);
            Assert.Equal(2, declSymbol.ConstituentNamespaces.Length);
 
            var tree2 = compilation.SyntaxTrees.ElementAt(1);
            var root2 = tree.GetCompilationUnitRoot();
            var decl2 = (NamespaceDeclarationSyntax)root2.Members[0];
            var model2 = compilation.GetSemanticModel(tree2);
            var declSymbol2 = model.GetDeclaredSymbol(decl2);
            Assert.NotNull(declSymbol2);
            Assert.Equal(declSymbol, declSymbol2);
            // 
            var memSymbol = compilation.GlobalNamespace.GetMembers("System").Single();
            Assert.Same(declSymbol, memSymbol);
        }
 
        [WorkItem(542459, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542459")]
        [Fact]
        public void StructKeywordInsideSwitchWithScriptParseOption()
        {
            var compilation = CreateCompilation(@"
using System;
 
class Test
{
    public static void Main()
    {
        int i = 10;
        switch (i)
        {
            class case 0:
                break;
        }
        switch (i)
        {
            struct default:
                break;
        }
    }
}
", parseOptions: TestOptions.Script
 );
 
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var diagnostics = model.GetDiagnostics();
 
            Assert.NotEmpty(diagnostics);
        }
 
        [WorkItem(542459, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542459")]
        [Fact]
        public void Bug9728_SmallerReproCase()
        {
            var code = @"
using System;
struct break;
";
 
            var compilation = CreateCompilation(code, parseOptions: TestOptions.Script);
 
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var diagnostics = model.GetDiagnostics();
 
            Assert.NotEmpty(diagnostics);
        }
 
        [WorkItem(542483, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542483")]
        [Fact]
        public void IncompleteStructDeclWithSpace()
        {
            var compilation = CreateCompilation(@"
using System;
 
namespace N1
{
    struct Test
 ");
 
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var diagnostics = model.GetDiagnostics();
 
            Assert.NotEmpty(diagnostics);
        }
 
        [WorkItem(542583, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542583")]
        [Fact]
        public void LambdaExpressionInFieldInitReferencingAnotherFieldWithScriptParseOption()
        {
            string sourceCode = @"
using System.Linq;
using System.Collections;
 
class P
{
    double one = 1;
    public Func<int, int> z = (x => x + one);
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(sourceCode, parseOptions: TestOptions.Script);
            var tree = compilation.SyntaxTrees[0];
            var semanticModel = compilation.GetSemanticModel(tree);
            var queryExpr = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParenthesizedExpressionSyntax>().First();
            var symbolInfo = semanticModel.GetSemanticInfoSummary(queryExpr);
            Assert.Equal(SymbolKind.Method, symbolInfo.Symbol.Kind);
        }
 
        [WorkItem(542495, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542495")]
        [ClrOnlyFact(ClrOnlyReason.Unknown)]
        public void AliasSymbolEquality()
        {
            string text = @"
using Alias = System;
                               
class C
{
    private Alias.String s;
}
";
            var compilation = CreateCompilation(text);
            var tree = compilation.SyntaxTrees[0];
            var node = (IdentifierNameSyntax)tree.GetCompilationUnitRoot().DescendantTokens().Where(t => t.ToString() == "Alias").Last().Parent;
            var modelWeakReference = ObjectReference.CreateFromFactory(() => compilation.GetSemanticModel(tree));
            var alias1 = modelWeakReference.UseReference(sm => sm.GetAliasInfo(node));
 
            // We want the Compilation's WeakReference<BinderFactory> to be collected
            // so that the next semantic model will get a new one.
            modelWeakReference.AssertReleased();
 
            var model2 = compilation.GetSemanticModel(tree);
            var alias2 = model2.GetAliasInfo(node);
 
            Assert.Equal(alias1, alias2);
            Assert.Same(alias1, alias2);
        }
 
        [WorkItem(542475, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542475")]
        [Fact]
        public void PartialMethods()
        {
            string sourceCode = @" using System;
partial class program
{
    static void Main(string[] args)
    {
        //goo(gender: 1 > 2, name: "", age: 1);
    }
    static partial void goo(string name, int age, bool gender, int index1 = 1) { }
}
partial class program
{
    static partial void goo(string name, int age, bool gender, int index1 = 1);
}";
            var tree = Parse(sourceCode);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var param = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().Where(p => p.Identifier.ValueText == "name").First();
            var symbol = model.GetDeclaredSymbol(param);
            Assert.Equal(param.Identifier.Span, symbol.Locations[0].SourceSpan);
        }
 
        [WorkItem(542217, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542217")]
        [Fact]
        public void ConflictingAliases()
        {
            string sourceCode = @"
using S = System;
using S = System.IO;
 
class C
{
    static void Main() { }
}
";
            var tree = Parse(sourceCode);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var usingDirectives = tree.GetCompilationUnitRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().ToArray();
 
            Assert.Equal(2, usingDirectives.Length);
 
            var alias1 = model.GetDeclaredSymbol(usingDirectives[0]);
            Assert.NotNull(alias1);
            Assert.Equal("System", alias1.Target.ToDisplayString());
 
            var alias2 = model.GetDeclaredSymbol(usingDirectives[1]);
            Assert.NotNull(alias2);
            Assert.Equal("System.IO", alias2.Target.ToDisplayString());
 
            Assert.NotEqual(alias1.Locations.Single(), alias2.Locations.Single());
 
            // This symbol we re-use.
            var alias1b = model.GetDeclaredSymbol(usingDirectives[0]);
            Assert.Same(alias1, alias1b);
 
            // This symbol we generate on-demand.
            var alias2b = model.GetDeclaredSymbol(usingDirectives[1]);
            Assert.Same(alias2, alias2b);
            Assert.Equal(alias2, alias2b);
        }
 
        [WorkItem(542902, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542902")]
        [Fact]
        public void InaccessibleDefaultAttributeConstructor()
        {
            var c1 = CreateCompilation(@"
using System;
 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
internal class MyAttribute : Attribute { 
    internal MyAttribute() { }
}
");
 
            var tree2 = SyntaxFactory.ParseSyntaxTree(@"
[My]
public class X { }
");
 
            var c2 = CreateCompilation(tree2, references: new[] { new CSharpCompilationReference(c1) });
 
            var attr = (AttributeSyntax)((ClassDeclarationSyntax)((CompilationUnitSyntax)tree2.GetCompilationUnitRoot()).Members[0]).AttributeLists[0].Attributes[0];
            var model = c2.GetSemanticModel(tree2);
 
            var symbolInfo = model.GetSymbolInfo(attr);
            Assert.Equal(CandidateReason.NotAnAttributeType, symbolInfo.CandidateReason);
        }
 
        [WorkItem(543024, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543024")]
        [Fact]
        public void BindUnboundGenericType()
        {
            var source = @"
public class A<T>
{
    public class B<U>
    {
        void Goo(object o) 
        {
            Goo(typeof(T));
        }
    }
}
";
 
            var compilation = (Compilation)CreateCompilation(source);
            compilation.VerifyDiagnostics();
 
            var typeA = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("A");
            var typeB = typeA.GetMember<INamedTypeSymbol>("B");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var typeofSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TypeOfExpressionSyntax>().Single();
            var typeofArgSyntax = typeofSyntax.Type;
            var typeofArgPosition = typeofArgSyntax.SpanStart;
 
            ITypeSymbol boundType;
            SymbolInfo symbolInfo;
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<T>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.Equal(typeA, boundType);
            Assert.Equal(typeA, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<int>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeA, boundType);
            Assert.Equal(typeA, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeA, boundType);
            Assert.Equal(typeA, boundType.OriginalDefinition);
            Assert.True(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("B<U>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.Equal(typeB, boundType);
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("B<int>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeB, boundType);
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("B<>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeB, boundType);
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.True(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<>.B<>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeB, boundType);
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.True(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<>.B<U>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeB, boundType); // unbound generic type not constructed since illegal
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<T>.B<>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.NotEqual(typeB, boundType); // unbound generic type not constructed since illegal
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
 
            symbolInfo = model.GetSpeculativeSymbolInfo(typeofArgPosition, SyntaxFactory.ParseTypeName("A<T>.B<U>"), SpeculativeBindingOption.BindAsTypeOrNamespace);
            boundType = symbolInfo.Symbol as ITypeSymbol;
            Assert.Equal(typeB, boundType);
            Assert.Equal(typeB, boundType.OriginalDefinition);
            Assert.False(boundType.IsUnboundGenericType());
        }
 
        [Fact]
        public void BindAsExpressionVsBindAsType()
        {
            var source = @"
using System;
using B = System.Console;
 
class M {
    public int B;
    void M() {
        Console.WriteLine(""hi"");
    }
}
";
            var compilation = (Compilation)CreateCompilation(source);
 
            var classM = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("M");
            var fieldB = classM.GetMember<IFieldSymbol>("B");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var position1 = tree.GetText().ToString().IndexOf("WriteLine", StringComparison.Ordinal);
            var expression = SyntaxFactory.ParseExpression("B");
 
            var semanticInfoExpression = model.GetSpeculativeSemanticInfoSummary(position1, expression, SpeculativeBindingOption.BindAsExpression);
            Assert.Equal(fieldB, semanticInfoExpression.Symbol);
            Assert.Equal("System.Int32", semanticInfoExpression.Type.ToTestDisplayString());
            Assert.Null(semanticInfoExpression.Alias);
 
            semanticInfoExpression = model.GetSpeculativeSemanticInfoSummary(position1, expression, SpeculativeBindingOption.BindAsTypeOrNamespace);
            Assert.Equal("System.Console", semanticInfoExpression.Symbol.ToTestDisplayString());
            Assert.Equal("System.Console", semanticInfoExpression.Type.ToTestDisplayString());
            Assert.NotNull(semanticInfoExpression.Alias);
            Assert.Equal("B=System.Console", semanticInfoExpression.Alias.ToTestDisplayString());
        }
 
        // Parse an attribute. No such API, so use a bit of a workaround.
        private AttributeSyntax ParseAttributeSyntax(string source)
        {
            return SyntaxFactory.ParseCompilationUnit(source + " class X {}").Members.First().AsTypeDeclarationSyntax().AttributeLists.First().Attributes.First();
        }
 
        [WorkItem(653957, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/653957")]
        [Fact]
        public void MissingExtensionMethodNullDereference()
        {
            // This test fails during type argument inference
            var src = @"
static class S
{
    public static void Write<T>(this IWriter<T> writer, T value)
    {
        writer.Write(value);
    }
}";
            var comp = CreateCompilation(src);
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var call = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single();
            SymbolInfo info = new SymbolInfo();
            info = model.GetSymbolInfo(call);
 
            Assert.IsAssignableFrom<SourceOrdinaryMethodSymbol>(info.Symbol.GetSymbol());
 
            src = @"
static class S
{
    public static void Write(this IWriter writer, int value)
    {
        writer.Write(value);
    }
}";
            comp = CreateCompilation(src);
            tree = comp.SyntaxTrees.Single();
            model = comp.GetSemanticModel(tree);
 
            call = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single();
            info = model.GetSymbolInfo(call);
 
            Assert.IsType<ReducedExtensionMethodSymbol>(info.Symbol.GetSymbol());
        }
 
        [Fact]
        public void BindSpeculativeAttribute()
        {
            var source = @"
using System;
using O=System.ObsoleteAttribute;
 
class C {
    class DAttribute: Attribute {}
    C goo<O>() { return null; }
    [Serializable] int i;
}
";
            var compilation = CreateCompilation(source);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var position = tree.GetText().ToString().IndexOf("class C {", StringComparison.Ordinal);
            var attr1 = ParseAttributeSyntax("[Obsolete]");
 
            var symbolInfo = model.GetSpeculativeSymbolInfo(position, attr1);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor()", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr2 = ParseAttributeSyntax("[ObsoleteAttribute(4)]");
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position, attr2);
            Assert.Null(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason);
            Assert.Equal(3, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor()", symbolInfo.CandidateSymbols[0].ToTestDisplayString());
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.CandidateSymbols[1].ToTestDisplayString());
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message, System.Boolean error)", symbolInfo.CandidateSymbols[2].ToTestDisplayString());
 
            var attr3 = ParseAttributeSyntax(@"[O(""hello"")]");
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position, attr3);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr4 = ParseAttributeSyntax("[P]");
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position, attr4);
            Assert.Null(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
 
            var attr5 = ParseAttributeSyntax("[D]");
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position, attr5);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("C.DAttribute..ctor()", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr6 = ParseAttributeSyntax(@"[O(""hello"")]");
            var position2 = tree.GetText().ToString().IndexOf("C goo<O>", StringComparison.Ordinal);
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position2, attr6);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr7 = ParseAttributeSyntax(@"[O(""hello"")]");
            var position3 = tree.GetText().ToString().IndexOf("Serializable", StringComparison.Ordinal);
 
            symbolInfo = model.GetSpeculativeSymbolInfo(position3, attr7);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void TestGetSpeculativeSemanticModelForAttribute()
        {
            var source = @"
using System;
using O=System.ObsoleteAttribute;
 
class C {
    class DAttribute: Attribute {}
    C goo<O>() { return null; }
    [Serializable] int i;
}
";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees.Single();
            var parentModel = compilation.GetSemanticModel(tree);
 
            var position = tree.GetText().ToString().IndexOf("class C {", StringComparison.Ordinal);
 
            var attr1 = ParseAttributeSyntax("[Obsolete]");
 
            SemanticModel speculativeModel;
            var success = parentModel.TryGetSpeculativeSemanticModel(position, attr1, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            var symbolInfo = speculativeModel.GetSymbolInfo(attr1);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor()", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr2 = ParseAttributeSyntax("[ObsoleteAttribute(4)]");
            success = parentModel.TryGetSpeculativeSemanticModel(position, attr2, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr2);
            Assert.Null(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason);
            Assert.Equal(3, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor()", symbolInfo.CandidateSymbols[0].ToTestDisplayString());
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.CandidateSymbols[1].ToTestDisplayString());
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message, System.Boolean error)", symbolInfo.CandidateSymbols[2].ToTestDisplayString());
 
            var constantInfo = speculativeModel.GetConstantValue(attr2.ArgumentList.Arguments.First().Expression);
            Assert.True(constantInfo.HasValue, "must be constant");
            Assert.Equal(4, constantInfo.Value);
 
            var attr3 = ParseAttributeSyntax(@"[O(""hello"")]");
 
            success = parentModel.TryGetSpeculativeSemanticModel(position, attr3, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
            symbolInfo = speculativeModel.GetSymbolInfo(attr3);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            constantInfo = speculativeModel.GetConstantValue(attr3.ArgumentList.Arguments.First().Expression);
            Assert.True(constantInfo.HasValue, "must be constant");
            Assert.Equal("hello", constantInfo.Value);
 
            var aliasSymbol = speculativeModel.GetAliasInfo(attr3.Name as IdentifierNameSyntax);
            Assert.NotNull(aliasSymbol);
            Assert.Equal("O", aliasSymbol.Name);
            Assert.NotNull(aliasSymbol.Target);
            Assert.Equal("ObsoleteAttribute", aliasSymbol.Target.Name);
 
            var attr4 = ParseAttributeSyntax("[P]");
 
            success = parentModel.TryGetSpeculativeSemanticModel(position, attr4, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr4);
            Assert.Null(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
 
            var attr5 = ParseAttributeSyntax("[D]");
 
            success = parentModel.TryGetSpeculativeSemanticModel(position, attr5, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr5);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("C.DAttribute..ctor()", symbolInfo.Symbol.ToTestDisplayString());
 
            var attr6 = ParseAttributeSyntax(@"[O(""hello"")]");
            var position2 = tree.GetText().ToString().IndexOf("C goo<O>", StringComparison.Ordinal);
 
            success = parentModel.TryGetSpeculativeSemanticModel(position, attr6, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr6);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            constantInfo = speculativeModel.GetConstantValue(attr6.ArgumentList.Arguments.First().Expression);
            Assert.True(constantInfo.HasValue, "must be constant");
            Assert.Equal("hello", constantInfo.Value);
 
            aliasSymbol = speculativeModel.GetAliasInfo(attr6.Name as IdentifierNameSyntax);
            Assert.NotNull(aliasSymbol);
            Assert.Equal("O", aliasSymbol.Name);
            Assert.NotNull(aliasSymbol.Target);
            Assert.Equal("ObsoleteAttribute", aliasSymbol.Target.Name);
 
            var attr7 = ParseAttributeSyntax(@"[O(""hello"")]");
            var position3 = tree.GetText().ToString().IndexOf("Serializable", StringComparison.Ordinal);
 
            success = parentModel.TryGetSpeculativeSemanticModel(position3, attr7, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr7);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            constantInfo = speculativeModel.GetConstantValue(attr7.ArgumentList.Arguments.First().Expression);
            Assert.True(constantInfo.HasValue, "must be constant");
            Assert.Equal("hello", constantInfo.Value);
 
            aliasSymbol = speculativeModel.GetAliasInfo(attr7.Name as IdentifierNameSyntax);
            Assert.NotNull(aliasSymbol);
            Assert.Equal("O", aliasSymbol.Name);
            Assert.NotNull(aliasSymbol.Target);
            Assert.Equal("ObsoleteAttribute", aliasSymbol.Target.Name);
 
            var attr8 = SyntaxFactory.ParseCompilationUnit(@"[assembly: O(""hello"")]").AttributeLists.First().Attributes.First();
 
            success = parentModel.TryGetSpeculativeSemanticModel(position3, attr8, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            symbolInfo = speculativeModel.GetSymbolInfo(attr8);
            Assert.NotNull(symbolInfo.Symbol);
            Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
            Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
            Assert.Equal("System.ObsoleteAttribute..ctor(System.String message)", symbolInfo.Symbol.ToTestDisplayString());
 
            constantInfo = speculativeModel.GetConstantValue(attr8.ArgumentList.Arguments.First().Expression);
            Assert.True(constantInfo.HasValue, "must be constant");
            Assert.Equal("hello", constantInfo.Value);
 
            aliasSymbol = speculativeModel.GetAliasInfo(attr8.Name as IdentifierNameSyntax);
            Assert.NotNull(aliasSymbol);
            Assert.Equal("O", aliasSymbol.Name);
            Assert.NotNull(aliasSymbol.Target);
            Assert.Equal("ObsoleteAttribute", aliasSymbol.Target.Name);
        }
 
        [Fact]
        public void GetSymbolInfoSimpleLambda()
        {
            var compilation = CreateCompilation(@"
using System.Collections.Generic;
using System.Linq;
class Goo
{
  public string[] P { get; set; }
  public IEnumerable<Goo> Arguments { get; set; }
 
    static void M(IEnumerable<Goo> c)
    {
        var q = from e in c
                    select new Goo()
                    {
                        P = e.Arguments.Select(x => x)
                    };
    }
}
");
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var lambda = (SimpleLambdaExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().First(x => x is SimpleLambdaExpressionSyntax);
            model.GetSymbolInfo(lambda);
        }
 
        [Fact]
        public void ImplicitConversionOperatorDeclaration()
        {
            var source = @"
class C
{
    public static implicit operator C(string s)
    {
        return null;
    }
}
";
 
            var compilation = (Compilation)CreateCompilation(source);
 
            var conversion = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("C").GetMember<IMethodSymbol>(WellKnownMemberNames.ImplicitConversionName);
            Assert.Equal(MethodKind.Conversion, conversion.MethodKind);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var conversionDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConversionOperatorDeclarationSyntax>().Single();
 
            var declaredSymbol = model.GetDeclaredSymbol(conversionDecl);
            Assert.NotNull(declaredSymbol);
            Assert.Equal(conversion, declaredSymbol);
 
            var lookupSymbols = model.LookupSymbols(conversionDecl.DescendantNodes().OfType<ReturnStatementSyntax>().Single().SpanStart, name: WellKnownMemberNames.ImplicitConversionName);
            Assert.Equal(declaredSymbol, lookupSymbols.Single()); //conversions can't be referenced by name, but the user asked for it specifically
        }
 
        [Fact]
        public void ExplicitConversionOperatorDeclaration()
        {
            var source = @"
class C
{
    public static explicit operator C(string s)
    {
        return null;
    }
}
";
 
            var compilation = (Compilation)CreateCompilation(source);
 
            var conversion = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("C").GetMember<IMethodSymbol>(WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(MethodKind.Conversion, conversion.MethodKind);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var conversionDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConversionOperatorDeclarationSyntax>().Single();
 
            var declaredSymbol = model.GetDeclaredSymbol(conversionDecl);
            Assert.NotNull(declaredSymbol);
            Assert.Equal(conversion, declaredSymbol);
 
            var lookupSymbols = model.LookupSymbols(conversionDecl.DescendantNodes().OfType<ReturnStatementSyntax>().Single().SpanStart, name: WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(declaredSymbol, lookupSymbols.Single()); //conversions can't be referenced by name, but the user asked for it specifically
        }
 
        [Fact]
        public void OperatorDeclaration()
        {
            var source = @"
class C
{
    public static C operator+(C c1, C c2)
    {
        return c1 ?? c2;
    }
}
";
 
            var compilation = (Compilation)CreateCompilation(source);
 
            var @operator = compilation.GlobalNamespace.GetMember<INamedTypeSymbol>("C").GetMember<IMethodSymbol>(WellKnownMemberNames.AdditionOperatorName);
            Assert.Equal(MethodKind.UserDefinedOperator, @operator.MethodKind);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var operatorDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<OperatorDeclarationSyntax>().Single();
 
            var declaredSymbol = model.GetDeclaredSymbol(operatorDecl);
            Assert.NotNull(declaredSymbol);
            Assert.Equal(@operator, declaredSymbol);
 
            var lookupSymbols = model.LookupSymbols(operatorDecl.DescendantNodes().OfType<ReturnStatementSyntax>().Single().SpanStart, name: WellKnownMemberNames.AdditionOperatorName);
            Assert.Equal(declaredSymbol, lookupSymbols.Single()); //operators can't be referenced by name, but the user asked for it specifically
        }
 
        [WorkItem(543415, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543415")]
        [Fact]
        public void AliasRace1()
        {
            var text = @"
using Alias = Goo;
 
namespace Goo { }
 
[System.Obsolete]
class C { }
";
 
            var compilation = (Compilation)CreateCompilation(text);
            compilation.VerifyDiagnostics(
                // (2,1): info CS8019: Unnecessary using directive.
                // using Alias = Goo;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using Alias = Goo;"));
 
            var @namespace = compilation.GlobalNamespace.GetMember<INamespaceSymbol>("Goo");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            int position = text.IndexOf("Obsolete", StringComparison.Ordinal);
 
            var result = Parallel.For(0, 100, i =>
            {
                var symbols = model.LookupSymbols(position, name: "Alias");
                var alias = (IAliasSymbol)symbols.Single();
 
                Assert.Equal(@namespace, alias.Target);
            });
 
            Assert.True(result.IsCompleted);
        }
 
        [WorkItem(543415, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543415")]
        [Fact]
        public void AliasRace2()
        {
            var text = @"
using Alias = Goo;
 
namespace Goo { }
 
[System.Obsolete]
class C { }
";
 
            var compilation = (Compilation)CreateCompilation(text);
            compilation.VerifyDiagnostics(
                // (2,1): info CS8019: Unnecessary using directive.
                // using Alias = Goo;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using Alias = Goo;"));
 
            var @namespace = compilation.GlobalNamespace.GetMember<INamespaceSymbol>("Goo");
 
            var tree = compilation.SyntaxTrees.Single();
 
            int position = text.IndexOf("Obsolete", StringComparison.Ordinal);
 
            var result = Parallel.For(0, 100, i =>
            {
                var model = compilation.GetSemanticModel(tree);
                var symbols = model.LookupSymbols(position, name: "Alias");
                var alias = (IAliasSymbol)symbols.Single();
 
                Assert.Equal(@namespace, alias.Target);
            });
 
            Assert.True(result.IsCompleted);
        }
 
        [WorkItem(544100, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544100")]
        [Fact]
        public void NoLocalScopeBinder()
        {
            var text = @"
using S=System;
class C 
{ 
        void M(S.F x = default(S.F))
        {
        }
}
 
";
 
            var compilation = CreateCompilation(text);
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var node = (DefaultExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Where(i => i is DefaultExpressionSyntax).First();
            model.GetSemanticInfoSummary(node.Type);
        }
 
        [WorkItem(543868, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543868")]
        [Fact]
        public void IsEventUsableAsField()
        {
            var text = @"
class Enclosing
{
    void M()
    {
        //AAA
    }
 
    class Declaring
    {
        public event System.Action E;
        public event System.Action F { add { } remove { } }
        
        void M()
        {
            //BBB
        }
 
        class Nested
        {
            void M()
            {
                //CCC
            }
        }
    }
}
 
class Other
{
    void M()
    {
        //DDD
    }
}
 
";
 
            var compilation = (Compilation)CreateCompilation(text);
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            compilation.VerifyDiagnostics(
                // (11,36): warning CS0067: The event 'Enclosing.Declaring.E' is never used
                //         public event System.Action E;
                Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E").WithArguments("Enclosing.Declaring.E"));
 
            var declaringType = compilation.GlobalNamespace.GetMember<ITypeSymbol>("Enclosing").GetMember<ITypeSymbol>("Declaring");
            var fieldLikeEvent = declaringType.GetMember<IEventSymbol>("E");
            var customEvent = declaringType.GetMember<IEventSymbol>("F");
 
            int enclosingTypePosition = text.IndexOf("AAA", StringComparison.Ordinal);
            Assert.InRange(enclosingTypePosition, 0, text.Length);
            int declaringTypePosition = text.IndexOf("BBB", StringComparison.Ordinal);
            Assert.InRange(declaringTypePosition, 0, text.Length);
            int nestedTypePosition = text.IndexOf("CCC", StringComparison.Ordinal);
            Assert.InRange(nestedTypePosition, 0, text.Length);
            int otherTypePosition = text.IndexOf("DDD", StringComparison.Ordinal);
            Assert.InRange(otherTypePosition, 0, text.Length);
 
            Assert.False(model.IsEventUsableAsField(enclosingTypePosition, fieldLikeEvent));
            Assert.True(model.IsEventUsableAsField(declaringTypePosition, fieldLikeEvent));
            Assert.True(model.IsEventUsableAsField(nestedTypePosition, fieldLikeEvent));
            Assert.False(model.IsEventUsableAsField(otherTypePosition, fieldLikeEvent));
 
            Assert.False(model.IsEventUsableAsField(enclosingTypePosition, customEvent));
            Assert.False(model.IsEventUsableAsField(declaringTypePosition, customEvent));
            Assert.False(model.IsEventUsableAsField(nestedTypePosition, customEvent));
            Assert.False(model.IsEventUsableAsField(otherTypePosition, customEvent));
        }
 
        [Fact]
        public void UnboundNestedType()
        {
            var source =
@"class A<T> { }
class C : A<object>.B<> { }";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ClassDeclarationSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.ClassDeclaration));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            type = type.BaseType;
            Assert.Equal("A<object>.B<?>", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
        }
 
        [Fact]
        public void UnboundNestedType_2()
        {
            var source =
@"class A<T, U> { }
class C : A<,,>.B<object> { }";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ClassDeclarationSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.ClassDeclaration));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            type = type.BaseType;
            Assert.Equal("A<?, ?, ?>.B<object>", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
        }
 
        [Fact]
        public void UnboundNestedType_3()
        {
            var source =
@"class A { }
class C : A<>.B<> { }";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ClassDeclarationSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.ClassDeclaration));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            type = type.BaseType;
            Assert.Equal("A<?>.B<?>", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
        }
 
        [WorkItem(563572, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/563572")]
        [Fact]
        public void InvalidEnumDeclaration()
        {
            var source = @"
public class C
{
    public event enum
}
";
            var compilation = CreateCompilation(source);
 
            var tree = compilation.SyntaxTrees.Single();
            var enumDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<EnumDeclarationSyntax>().Single();
            var eventDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<EventDeclarationSyntax>().Single();
 
            var model = compilation.GetSemanticModel(tree);
 
            var enumSymbol = model.GetDeclaredSymbol(enumDecl); //Used to assert.
            Assert.Equal(SymbolKind.NamedType, enumSymbol.Kind);
            Assert.Equal(TypeKind.Enum, enumSymbol.TypeKind);
 
            var eventSymbol = model.GetDeclaredSymbol(eventDecl);
            Assert.Equal(SymbolKind.Event, eventSymbol.Kind);
        }
 
        [WorkItem(563572, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/563572")]
        [Fact]
        public void TypeMembersWithoutNames()
        {
            var source = @"
public class S
{
    struct interface
}
";
            var compilation = CreateCompilation(source);
 
            var tree = compilation.SyntaxTrees.Single();
            var structDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<StructDeclarationSyntax>().First();
            var interfaceDecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>().Last();
 
            var model = compilation.GetSemanticModel(tree);
 
            var structSymbol = model.GetDeclaredSymbol(structDecl);
            var interfaceSymbol = model.GetDeclaredSymbol(interfaceDecl);
 
            // The missing identifier of the struct declaration is contained in both declaration spans (since it has width zero).
            // We used to just pick the first matching span, but now we keep looking until we find a "good" match.
            Assert.NotEqual(structSymbol, interfaceSymbol);
            Assert.Equal(TypeKind.Struct, structSymbol.TypeKind);
            Assert.Equal(TypeKind.Interface, interfaceSymbol.TypeKind);
        }
 
        [Fact]
        public void TupleLiteral001()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        var t = (1, 2);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (TupleExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.TupleExpression));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(int, int)", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("(1, 2)", type.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(type.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteral002()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        var t = (Alice: 1, Bob: 2);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (TupleExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.TupleExpression));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(int Alice, int Bob)", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("(Alice: 1, Bob: 2)", type.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(type.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteral003()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (short Alice, int Bob) t = (1, 1);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (TupleExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.TupleExpression));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short, int)", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("(1, 1)", type.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(type.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteral004()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (short Alice, string Bob) t = (1, null);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (TupleExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.TupleExpression));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short, string)", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("(1, null)", type.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(type.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteral005()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (short, string) t = (Alice:1, Bob:null);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (TupleExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.TupleExpression));
            var model = compilation.GetSemanticModel(tree);
            var type = (INamedTypeSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short Alice, string Bob)", type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("(Alice:1, Bob:null)", type.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(type.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement001()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        var t = (Alice: 1, Bob: 2);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(int Alice, int Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement002()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (int X, short Y) t = (Alice: 1, Bob: 2);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(int Alice, short Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement003()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (short X, string Y) t = (Alice: 1, Bob: null);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short Alice, string Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement004_WithoutValueTuple()
        {
            var source =
@"
class C
{
    static void Main()
    {
        (short X, string Y) = (Alice: 1, Bob: null);
    }
}
";
 
            var compilation = CreateCompilationWithMscorlib46(source);
            compilation.VerifyDiagnostics(
                // (6,31): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (short X, string Y) = (Alice: 1, Bob: null);
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(Alice: 1, Bob: null)").WithArguments("System.ValueTuple`2").WithLocation(6, 31),
                // (6,32): warning CS8123: The tuple element name 'Alice' is ignored because a different name or no name is specified by the target type '(short, string)'.
                //         (short X, string Y) = (Alice: 1, Bob: null);
                Diagnostic(ErrorCode.WRN_TupleLiteralNameMismatch, "Alice: 1").WithArguments("Alice", "(short, string)").WithLocation(6, 32),
                // (6,42): warning CS8123: The tuple element name 'Bob' is ignored because a different name or no name is specified by the target type '(short, string)'.
                //         (short X, string Y) = (Alice: 1, Bob: null);
                Diagnostic(ErrorCode.WRN_TupleLiteralNameMismatch, "Bob: null").WithArguments("Bob", "(short, string)").WithLocation(6, 42)
                );
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short Alice, string Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement004()
        {
            var source =
@"
class C
{
    static void Main()
    {
        (short X, string Y) = (Alice: 1, Bob: null);
    }
}
namespace System
{
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
 
        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
    }
}
";
 
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (6,32): warning CS8123: The tuple element name 'Alice' is ignored because a different name or no name is specified by the target type '(short, string)'.
                //         (short X, string Y) = (Alice: 1, Bob: null);
                Diagnostic(ErrorCode.WRN_TupleLiteralNameMismatch, "Alice: 1").WithArguments("Alice", "(short, string)").WithLocation(6, 32),
                // (6,42): warning CS8123: The tuple element name 'Bob' is ignored because a different name or no name is specified by the target type '(short, string)'.
                //         (short X, string Y) = (Alice: 1, Bob: null);
                Diagnostic(ErrorCode.WRN_TupleLiteralNameMismatch, "Bob: null").WithArguments("Bob", "(short, string)").WithLocation(6, 42)
                );
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short Alice, string Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement005()
        {
            var source =
@"
 
using System;
 
class C
{
    static void Main() 
    { 
        ValueTuple<short, string> vt = (Alice: 1, Bob: null);
    }
}
 
namespace System
{
    // struct with two values
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
 
        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
 
        public override string ToString()
        {
            return '{' + Item1?.ToString() + "", "" + Item2?.ToString() + '}';
        }
    }
}
 
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short Alice, string Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TupleLiteralElement006()
        {
            var source = @"
class C
{
    static void Main() 
    { 
        (short X, string) t = (1, Bob: null);
    }
}
";
 
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var decl = (ArgumentSyntax)tree.GetCompilationUnitRoot().DescendantNodes().Last(n => n.IsKind(SyntaxKind.Argument));
            var model = compilation.GetSemanticModel(tree);
            var element = (IFieldSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal("(short, string Bob).Bob", element.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
            Assert.Equal("Bob", element.DeclaringSyntaxReferences.Single().GetSyntax().ToString());
            Assert.True(element.Locations.Single().IsInSource);
        }
 
        [Fact]
        public void TestIncompleteMemberNode_Visitor()
        {
            var compilation = CreateCompilation(@"private");
            var tree = compilation.SyntaxTrees[0];
            var root = tree.GetCompilationUnitRoot();
 
            // Get the IncompleteMemberNode which is the first child node of the root of the tree.
            var node = root.ChildNodes().First();
 
            var model = compilation.GetSemanticModel(tree);
            var symbol = model.GetDeclaredSymbol(node);
            Assert.Equal(SyntaxKind.IncompleteMember, node.Kind());
 
            var x = tree.FindNodeOrTokenByKind(SyntaxKind.IncompleteMember);
            Assert.Equal(SyntaxKind.IncompleteMember, x.Kind());
            Assert.Equal("C#", x.Language);
            Assert.Equal(7, x.Width);
 
            // This will call the Visitor Pattern Methods via the syntaxwalker
            var collector = new IncompleteSyntaxWalker();
            collector.Visit(root);
            int counter = collector.Incompletes.Count;
            Assert.Equal(1, counter);
        }
 
        private class IncompleteSyntaxWalker : CSharpSyntaxWalker
        {
            public readonly List<IncompleteMemberSyntax> Incompletes = new List<IncompleteMemberSyntax>();
 
            public override void VisitIncompleteMember(IncompleteMemberSyntax node)
            {
                this.Incompletes.Add(node);
                base.VisitIncompleteMember(node);
            }
        }
 
        [WorkItem(38074, "https://github.com/dotnet/roslyn/issues/38074")]
        [Fact]
        public void TestLookupStaticMembersLocalFunction()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void M()
    {
        void Local() {}
    }
}
");
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var cu = tree.GetCompilationUnitRoot();
            var typeDeclC = (TypeDeclarationSyntax)cu.Members.Single();
            var methodDeclM = (MethodDeclarationSyntax)typeDeclC.Members.Single();
 
            var symbols = model.LookupStaticMembers(methodDeclM.Body.SpanStart);
 
            Assert.Contains(symbols, s => s.Name == "Local");
        }
 
        [Fact]
        public void TestLookupStaticMembers_PositionNeedsAdjustment()
        {
            var source = @"
#nullable enable
 
class Program
{
    static void Main(string[] args)
    {
        void local1() { }
 
        b
 
        local1();
 
    }
}
";
            var comp = CreateCompilation(source);
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var node = tree.GetRoot().DescendantNodes().Single(node => node is IdentifierNameSyntax { Identifier: { ValueText: "b" } });
            var symbols = model.LookupStaticMembers(node.SpanStart);
            Assert.Contains(symbols, s => s.Name == "local1");
        }
 
        [Fact]
        public void InvalidParameterWithDefaultValue_Method()
        {
            var source =
@"class Program
{
    static void F(int x = 2, = 3) { }
}";
            var comp = CreateCompilation(source);
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().ToArray();
            var symbol1 = VerifyParameter(model, decls[0], 0, "[System.Int32 x = 2]", "System.Int32", 2);
            var symbol2 = VerifyParameter(model, decls[1], 1, "[? = null]", "System.Int32", 3);
            Assert.Same(symbol1.ContainingSymbol, symbol2.ContainingSymbol);
        }
 
        [Fact]
        [WorkItem(784401, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/784401")]
        public void InvalidParameterWithDefaultValue_LocalFunction_01()
        {
            var source =
@"class Program
{
    static void Main()
    {
        void F(int x, = 3) { }
    }
}";
            var comp = CreateCompilation(source);
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().ToArray();
            var symbol1 = VerifyParameter(model, decls[0], 0, "System.Int32 x", null, null);
            var symbol2 = VerifyParameter(model, decls[1], 1, "[? = null]", "System.Int32", 3);
            Assert.Same(symbol1.ContainingSymbol, symbol2.ContainingSymbol);
        }
 
        [Fact]
        [WorkItem(784401, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/784401")]
        public void InvalidParameterWithDefaultValue_LocalFunction_02()
        {
            var source =
@"class Program
{
    static void Main()
    {
        void F(int x = 2, = 3) { }
    }
}";
            var comp = CreateCompilation(source);
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().ToArray();
            var symbol1 = VerifyParameter(model, decls[0], 0, "[System.Int32 x = 2]", "System.Int32", 2);
            var symbol2 = VerifyParameter(model, decls[1], 1, "[? = null]", "System.Int32", 3);
            Assert.Same(symbol1.ContainingSymbol, symbol2.ContainingSymbol);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment01()
        {
            var source = """
                public class Thing
                {
                    public int Key { get; set; }
                    public string Value { get; set; }
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, string value)
                    {
                        return new()
                        {
                            Key = key,
                            Value,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (14,13): error CS0747: Invalid initializer member declarator
                //             Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(14, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[1]).Symbol;
            Assert.Equal("System.String Thing.Value { get; set; }", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment02()
        {
            var source = """
                public class Outer
                {
                    public Thing Thing { get; } = new();
                }
 
                public class Thing
                {
                    public int Key { get; set; }
                    public string Value { get; set; }
                }
 
                public class Using
                {
                    public static Outer CreateOuterThing(int key, string value)
                    {
                        return new()
                        {
                            Thing =
                            {
                                Key = key,
                                Value,
                            }
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (21,17): error CS0747: Invalid initializer member declarator
                //                 Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(21, 17)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var thingInitializer = root.DescendantNodes()
                .OfType<AssignmentExpressionSyntax>()
                .First(s => s.Left is IdentifierNameSyntax { Identifier.Text: "Thing" })
                .Right
                as InitializerExpressionSyntax;
            var valueInitializer = thingInitializer.Expressions[1];
            var initializedSymbol = model.GetSymbolInfo(valueInitializer).Symbol;
            Assert.Equal("System.String Thing.Value { get; set; }", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment03()
        {
            var source = """
                public class Thing
                {
                    public int Key;
                    public string Value;
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, string value)
                    {
                        return new()
                        {
                            Key = key,
                            Value,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (14,13): error CS0747: Invalid initializer member declarator
                //             Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(14, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[1]).Symbol;
            Assert.Equal("System.String Thing.Value", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment04()
        {
            var source = """
                #pragma warning disable CS0067
 
                public class Thing
                {
                    public int Key;
                    public event System.Action Handler;
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, System.Action handler)
                    {
                        return new()
                        {
                            Key = key,
                            Handler,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (16,13): error CS0747: Invalid initializer member declarator
                //             Handler,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Handler").WithLocation(16, 13),
                // (16,13): error CS0070: The event 'Thing.Handler' can only appear on the left hand side of += or -= (except when used from within the type 'Thing')
                //             Handler,
                Diagnostic(ErrorCode.ERR_BadEventUsage, "Handler").WithArguments("Thing.Handler", "Thing").WithLocation(16, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[1]).Symbol;
            Assert.Null(initializedSymbol);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment05()
        {
            var source = """
                public class Thing
                {
                    public int Key { get; set; }
                    public string Value { get; set; }
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, string value)
                    {
                        return new()
                        {
                            Value,
                            Key = key,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (13,13): error CS0747: Invalid initializer member declarator
                //             Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(13, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[0]).Symbol;
            Assert.Equal("System.String Thing.Value { get; set; }", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment06()
        {
            var source = """
                public class Outer
                {
                    public Thing Thing { get; } = new();
                }
 
                public class Thing
                {
                    public int Key { get; set; }
                    public string Value { get; set; }
                }
 
                public class Using
                {
                    public static Outer CreateOuterThing(int key, string value)
                    {
                        return new()
                        {
                            Thing =
                            {
                                Value,
                                Key = key,
                            }
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (20,17): error CS0747: Invalid initializer member declarator
                //                 Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(20, 17)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var thingInitializer = root.DescendantNodes()
                .OfType<AssignmentExpressionSyntax>()
                .First(s => s.Left is IdentifierNameSyntax { Identifier.Text: "Thing" })
                .Right
                as InitializerExpressionSyntax;
            var valueInitializer = thingInitializer.Expressions[0];
            var initializedSymbol = model.GetSymbolInfo(valueInitializer).Symbol;
            Assert.Equal("System.String Thing.Value { get; set; }", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment07()
        {
            var source = """
                public class Thing
                {
                    public int Key;
                    public string Value;
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, string value)
                    {
                        return new()
                        {
                            Value,
                            Key = key,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (13,13): error CS0747: Invalid initializer member declarator
                //             Value,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Value").WithLocation(13, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[0]).Symbol;
            Assert.Equal("System.String Thing.Value", initializedSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74348")]
        public void ObjectInitializerIncompleteMemberValueAssignment08()
        {
            var source = """
                #pragma warning disable CS0067
                
                public class Thing
                {
                    public int Key;
                    public event System.Action Handler;
                }
 
                public class Using
                {
                    public static Thing CreateThing(int key, System.Action handler)
                    {
                        return new()
                        {
                            Handler,
                            Key = key,
                        };
                    }
                }
                """;
            var comp = CreateCompilation(source);
 
            comp.VerifyDiagnostics(
                // (15,13): error CS0747: Invalid initializer member declarator
                //             Handler,
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "Handler").WithLocation(15, 13),
                // (15,13): error CS0070: The event 'Thing.Handler' can only appear on the left hand side of += or -= (except when used from within the type 'Thing')
                //             Handler,
                Diagnostic(ErrorCode.ERR_BadEventUsage, "Handler").WithArguments("Thing.Handler", "Thing").WithLocation(15, 13)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
 
            var initializers = root.DescendantNodes()
                .OfType<InitializerExpressionSyntax>()
                .First()
                .ChildNodes()
                .ToArray();
            var initializedSymbol = model.GetSymbolInfo(initializers[0]).Symbol;
            Assert.Null(initializedSymbol);
        }
 
        private static IParameterSymbol VerifyParameter(
            SemanticModel model,
            ParameterSyntax decl,
            int expectedOrdinal,
            string expectedSymbol,
            string expectedType,
            object expectedConstant)
        {
            var symbol = (IParameterSymbol)model.GetDeclaredSymbol(decl);
            Assert.Equal(expectedOrdinal, symbol.Ordinal);
            Assert.Equal(expectedSymbol, symbol.ToTestDisplayString());
 
            var valueSyntax = decl.Default?.Value;
            if (valueSyntax == null)
            {
                Assert.Null(expectedType);
                Assert.Null(expectedConstant);
            }
            else
            {
                var type = model.GetTypeInfo(valueSyntax);
                Assert.Equal(expectedType, type.Type.ToTestDisplayString());
                Optional<object> actualConstant = model.GetConstantValue(valueSyntax);
                Assert.Equal(expectedConstant, actualConstant.Value);
            }
 
            return symbol;
        }
    }
}