/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/LookupTests.cs
2 144 строки
69 KB
Jared Parsons
Move net451 test assets to net461 (#74766)
17 авг 2024, 19:21
Не верифицирован
17 авг 2024, 19:21
75b26a2
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Generic; using System.Linq; using System.Threading; 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 class GetSemanticInfoTests : SemanticModelTestBase { #region helpers internal List<string> GetLookupNames(string testSrc) { var parseOptions = TestOptions.Regular; var compilation = CreateCompilationWithMscorlib461(testSrc, parseOptions: parseOptions); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var position = testSrc.Contains("/*<bind>*/") ? GetPositionForBinding(tree) : GetPositionForBinding(testSrc); return model.LookupNames(position); } internal List<ISymbol> GetLookupSymbols(string testSrc, NamespaceOrTypeSymbol container = null, string name = null, int? arity = null, bool isScript = false, IEnumerable<string> globalUsings = null) { var tree = Parse(testSrc, options: isScript ? TestOptions.Script : TestOptions.Regular); var compilation = CreateCompilationWithMscorlib461(new[] { tree }, options: TestOptions.ReleaseDll.WithUsings(globalUsings)); var model = compilation.GetSemanticModel(tree); var position = testSrc.Contains("/*<bind>*/") ? GetPositionForBinding(tree) : GetPositionForBinding(testSrc); return model.LookupSymbols(position, container.GetPublicSymbol(), name).Where(s => !arity.HasValue || arity == s.GetSymbol().GetMemberArity()).ToList(); } #endregion helpers #region tests [Fact] public void LookupExpressionBodyProp01() { var text = @" class C { public int P => /*<bind>*/10/*</bind>*/; }"; var actual = GetLookupNames(text).ListToSortedString(); var expected_lookupNames = new List<string> { "C", "Equals", "Finalize", "GetHashCode", "GetType", "MemberwiseClone", "Microsoft", "P", "ReferenceEquals", "System", "ToString" }; Assert.Equal(expected_lookupNames.ListToSortedString(), actual); } [Fact] public void LookupExpressionBodiedMethod01() { var text = @" class C { public int M() => /*<bind>*/10/*</bind>*/; }"; var actual = GetLookupNames(text).ListToSortedString(); var expected_lookupNames = new List<string> { "C", "Equals", "Finalize", "GetHashCode", "GetType", "MemberwiseClone", "Microsoft", "M", "ReferenceEquals", "System", "ToString" }; Assert.Equal(expected_lookupNames.ListToSortedString(), actual); } [WorkItem(538262, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538262")] [Fact] public void LookupCompilationUnitSyntax() { var testSrc = @" /*<bind>*/ class Test { } /*</bind>*/ "; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupSymbols(testSrc); } [WorkItem(527476, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527476")] [Fact] public void LookupConstrAndDestr() { var testSrc = @" class Test { Test() { } Test(int i) { } ~Test() { } static /*<bind>*/void/*</bind>*/Main() { } } "; List<string> expected_lookupNames = new List<string> { "Equals", "Finalize", "GetHashCode", "GetType", "Main", "MemberwiseClone", "Microsoft", "ReferenceEquals", "System", "Test", "ToString" }; List<string> expected_lookupSymbols = new List<string> { "Microsoft", "System", "System.Boolean System.Object.Equals(System.Object obj)", "System.Boolean System.Object.Equals(System.Object objA, System.Object objB)", "System.Boolean System.Object.ReferenceEquals(System.Object objA, System.Object objB)", "System.Int32 System.Object.GetHashCode()", "System.Object System.Object.MemberwiseClone()", "void System.Object.Finalize()", "System.String System.Object.ToString()", "System.Type System.Object.GetType()", "void Test.Finalize()", "void Test.Main()", "Test" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc); Assert.Equal(expected_lookupNames.ListToSortedString(), actual_lookupNames.ListToSortedString()); Assert.Equal(expected_lookupSymbols.ListToSortedString(), actual_lookupSymbols.ListToSortedString()); } [WorkItem(527477, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527477")] [Fact] public void LookupNotYetDeclLocalVar() { var testSrc = @" class Test { static void Main() { int j = /*<bind>*/9/*</bind>*/ ; int k = 45; } } "; List<string> expected_in_lookupNames = new List<string> { "j", "k" }; List<string> expected_in_lookupSymbols = new List<string> { "j", "k" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); } [WorkItem(538301, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538301")] [Fact] public void LookupByNameIncorrectArity() { var testSrc = @" class Test { public static void Main() { int i = /*<bind>*/10/*</bind>*/; } } "; // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupSymbols(testSrc, name: "i", arity: 1); var actual_lookupSymbols = GetLookupSymbols(testSrc, name: "i", arity: 1); Assert.Empty(actual_lookupSymbols); } [WorkItem(538310, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538310")] [Fact] public void LookupInProtectedNonNestedType() { var testSrc = @" protected class MyClass { /*<bind>*/public static void Main()/*</bind>*/ {} } "; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupSymbols(testSrc); } [WorkItem(538311, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538311")] [Fact] public void LookupClassContainsVolatileEnumField() { var testSrc = @" enum E{} class Test { static volatile E x; static /*<bind>*/int/*</bind>*/ Main() { return 1; } } "; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags GetLookupSymbols(testSrc); } [WorkItem(538312, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538312")] [Fact] public void LookupUsingAlias() { var testSrc = @" using T2 = System.IO; namespace T1 { class Test { static /*<bind>*/void/*</bind>*/ Main() { } } } "; List<string> expected_in_lookupNames = new List<string> { "T1", "T2" }; List<string> expected_in_lookupSymbols = new List<string> { "T1", "T2" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); } [WorkItem(538313, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538313")] [Fact] public void LookupUsingNameSpaceContSameTypeNames() { var testSrc = @" namespace T1 { using T2; public class Test { static /*<bind>*/int/*</bind>*/ Main() { return 1; } } } namespace T2 { public class Test { } } "; List<string> expected_in_lookupNames = new List<string> { "T1", "T2", "Test" }; List<string> expected_in_lookupSymbols = new List<string> { "T1", "T2", "T1.Test", //"T2.Test" this is hidden by T1.Test }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupNames[2], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[2], actual_lookupSymbols_as_string); } [WorkItem(527489, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527489")] [Fact] public void LookupMustNotBeNonInvocableMember() { var testSrc = @" class Test { public void TestMeth(int i, int j) { int m = /*<bind>*/10/*</bind>*/; } } "; List<string> expected_in_lookupNames = new List<string> { "TestMeth", "i", "j", "m", "System", "Microsoft", "Test" }; List<string> expected_in_lookupSymbols = new List<string> { "void Test.TestMeth(System.Int32 i, System.Int32 j)", "System.Int32 i", "System.Int32 j", "System.Int32 m", "System", "Microsoft", "Test" }; var comp = CreateCompilation(testSrc); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var position = GetPositionForBinding(tree); var binder = ((CSharpSemanticModel)model).GetEnclosingBinder(position); // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var info = LookupSymbolsInfo.GetInstance(); binder.AddLookupSymbolsInfo(info, LookupOptions.MustBeInvocableIfMember); var actual_lookupNames = info.Names; // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = actual_lookupNames.SelectMany(name => { var lookupResult = LookupResult.GetInstance(); HashSet<DiagnosticInfo> useSiteDiagnostics = null; binder.LookupSymbolsSimpleName( lookupResult, qualifierOpt: null, plainName: name, arity: 0, basesBeingResolved: null, options: LookupOptions.MustBeInvocableIfMember, diagnose: false, useSiteDiagnostics: ref useSiteDiagnostics); Assert.Null(useSiteDiagnostics); Assert.True(lookupResult.IsMultiViable || lookupResult.Kind == LookupResultKind.NotReferencable); var result = lookupResult.Symbols.ToArray(); lookupResult.Free(); return result; }); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupNames[2], actual_lookupNames); Assert.Contains(expected_in_lookupNames[3], actual_lookupNames); Assert.Contains(expected_in_lookupNames[4], actual_lookupNames); Assert.Contains(expected_in_lookupNames[5], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[2], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[3], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[4], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[5], actual_lookupSymbols_as_string); info.Free(); } [WorkItem(538365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538365")] [Fact] public void LookupWithNameZeroArity() { var testSrc = @" class Test { private void F<T>(T i) { } private void F<T, U>(T i, U j) { } private void F(int i) { } private void F(int i, int j) { } public static /*<bind>*/void/*</bind>*/ Main() { } } "; List<string> expected_in_lookupNames = new List<string> { "F" }; List<string> expected_in_lookupSymbols = new List<string> { "void Test.F(System.Int32 i)", "void Test.F(System.Int32 i, System.Int32 j)" }; List<string> not_expected_in_lookupSymbols = new List<string> { "void Test.F<T>(T i)", "void Test.F<T, U>(T i, U j)" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc, name: "F", arity: 0); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Equal(2, actual_lookupSymbols.Count); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.DoesNotContain(not_expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.DoesNotContain(not_expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); } [WorkItem(538365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538365")] [Fact] public void LookupWithNameZeroArityAndLookupOptionsAllMethods() { var testSrc = @" class Test { public void F<T>(T i) { } public void F<T, U>(T i, U j) { } public void F(int i) { } public void F(int i, int j) { } public void Main() { return; } } "; List<string> expected_in_lookupNames = new List<string> { "F" }; List<string> expected_in_lookupSymbols = new List<string> { "void Test.F(System.Int32 i)", "void Test.F(System.Int32 i, System.Int32 j)", "void Test.F<T>(T i)", "void Test.F<T, U>(T i, U j)" }; // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var comp = CreateCompilation(testSrc); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var position = testSrc.IndexOf("return", StringComparison.Ordinal); var binder = ((CSharpSemanticModel)model).GetEnclosingBinder(position); var lookupResult = LookupResult.GetInstance(); HashSet<DiagnosticInfo> useSiteDiagnostics = null; binder.LookupSymbolsSimpleName(lookupResult, qualifierOpt: null, plainName: "F", arity: 0, basesBeingResolved: null, options: LookupOptions.AllMethodsOnArityZero, diagnose: false, useSiteDiagnostics: ref useSiteDiagnostics); Assert.Null(useSiteDiagnostics); Assert.True(lookupResult.IsMultiViable); var actual_lookupSymbols_as_string = lookupResult.Symbols.Select(e => e.ToTestDisplayString()).ToArray(); lookupResult.Free(); // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = model.LookupNames(position); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Equal(4, actual_lookupSymbols_as_string.Length); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[2], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[3], actual_lookupSymbols_as_string); } [WorkItem(539160, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539160")] [Fact] public void LookupExcludeInAppropriateNS() { var testSrc = @" class Test { public static /*<bind>*/void/*</bind>*/ Main() { } } "; var srcTrees = new SyntaxTree[] { Parse(testSrc) }; var refs = new MetadataReference[] { SystemDataRef }; CSharpCompilation compilation = CSharpCompilation.Create("Test.dll", srcTrees, refs); var tree = srcTrees[0]; var model = compilation.GetSemanticModel(tree); List<string> not_expected_in_lookup = new List<string> { "<CrtImplementationDetails>", "<CppImplementationDetails>" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = model.LookupNames(GetPositionForBinding(tree), null).ToList(); var actual_lookupNames_ignoreAcc = model.LookupNames(GetPositionForBinding(tree), null).ToList(); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = model.LookupSymbols(GetPositionForBinding(tree)); var actual_lookupSymbols_ignoreAcc = model.LookupSymbols(GetPositionForBinding(tree)); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); var actual_lookupSymbols_ignoreAcc_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.DoesNotContain(not_expected_in_lookup[0], actual_lookupNames); Assert.DoesNotContain(not_expected_in_lookup[1], actual_lookupNames); Assert.DoesNotContain(not_expected_in_lookup[0], actual_lookupNames_ignoreAcc); Assert.DoesNotContain(not_expected_in_lookup[1], actual_lookupNames_ignoreAcc); Assert.DoesNotContain(not_expected_in_lookup[0], actual_lookupSymbols_as_string); Assert.DoesNotContain(not_expected_in_lookup[1], actual_lookupSymbols_as_string); Assert.DoesNotContain(not_expected_in_lookup[0], actual_lookupSymbols_ignoreAcc_as_string); Assert.DoesNotContain(not_expected_in_lookup[1], actual_lookupSymbols_ignoreAcc_as_string); } /// <summary> /// Verify that there's a way to look up only the members of the base type that are visible /// from the current type. /// </summary> [Fact] [WorkItem(539814, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539814")] public void LookupProtectedInBase() { var testSrc = @" class A { private void Hidden() { } protected void Goo() { } } class B : A { void Bar() { /*<bind>*/base/*</bind>*/.Goo(); } } "; var srcTrees = new SyntaxTree[] { Parse(testSrc) }; var refs = new MetadataReference[] { SystemDataRef }; CSharpCompilation compilation = CSharpCompilation.Create("Test.dll", srcTrees, refs); var tree = srcTrees[0]; var model = compilation.GetSemanticModel(tree); var baseExprNode = GetSyntaxNodeForBinding(GetSyntaxNodeList(tree)); Assert.Equal("base", baseExprNode.ToString()); var baseExprLocation = baseExprNode.SpanStart; Assert.NotEqual(0, baseExprLocation); var baseExprInfo = model.GetTypeInfo((ExpressionSyntax)baseExprNode); Assert.NotEqual(default, baseExprInfo); var baseExprType = (INamedTypeSymbol)baseExprInfo.Type; Assert.NotNull(baseExprType); Assert.Equal("A", baseExprType.Name); var symbols = model.LookupBaseMembers(baseExprLocation); Assert.Equal("void A.Goo()", symbols.Single().ToTestDisplayString()); var names = model.LookupNames(baseExprLocation, useBaseReferenceAccessibility: true); Assert.Equal("Goo", names.Single()); } [WorkItem(528263, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528263")] [Fact] public void LookupStartOfScopeMethodBody() { var testSrc = @"public class start { static public void Main() /*pos*/{ int num=10; } "; List<string> expected_in_lookupNames = new List<string> { "Main", "start", "num" }; List<string> expected_in_lookupSymbols = new List<string> { "void start.Main()", "start", "System.Int32 num" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Equal('{', testSrc[GetPositionForBinding(testSrc)]); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupNames[2], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[2], actual_lookupSymbols_as_string); } [WorkItem(528263, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528263")] [Fact] public void LookupEndOfScopeMethodBody() { var testSrc = @"public class start { static public void Main() { int num=10; /*pos*/} "; List<string> expected_in_lookupNames = new List<string> { "Main", "start" }; List<string> expected_in_lookupSymbols = new List<string> { "void start.Main()", "start" }; List<string> not_expected_in_lookupNames = new List<string> { "num" }; List<string> not_expected_in_lookupSymbols = new List<string> { "System.Int32 num" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Equal('}', testSrc[GetPositionForBinding(testSrc)]); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.DoesNotContain(not_expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.DoesNotContain(not_expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(540888, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540888")] [Fact] public void LookupLambdaParamInConstructorInitializer() { var testSrc = @" using System; class MyClass { public MyClass(Func<int, int> x) { } public MyClass(int j, int k) : this(lambdaParam => /*pos*/lambdaParam) { } } "; List<string> expected_in_lookupNames = new List<string> { "j", "k", "lambdaParam" }; List<string> expected_in_lookupSymbols = new List<string> { "System.Int32 j", "System.Int32 k", "System.Int32 lambdaParam" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupNames[2], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[2], actual_lookupSymbols_as_string); } [WorkItem(540893, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540893")] [Fact] public void TestForLocalVarDeclLookupAtForKeywordInForStmt() { var testSrc = @" class MyClass { static void Main() { /*pos*/for (int forVar = 10; forVar < 10; forVar++) { } } } "; List<string> not_expected_in_lookupNames = new List<string> { "forVar" }; List<string> not_expected_in_lookupSymbols = new List<string> { "System.Int32 forVar", }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.DoesNotContain(not_expected_in_lookupNames[0], actual_lookupNames); Assert.DoesNotContain(not_expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(540894, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540894")] [Fact] public void TestForeachIterVarLookupAtForeachKeyword() { var testSrc = @" class MyClass { static void Main() { System.Collections.Generic.List<int> listOfNumbers = new System.Collections.Generic.List<int>(); /*pos*/foreach (int number in listOfNumbers) { } } } "; List<string> not_expected_in_lookupNames = new List<string> { "number" }; List<string> not_expected_in_lookupSymbols = new List<string> { "System.Int32 number", }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.DoesNotContain(not_expected_in_lookupNames[0], actual_lookupNames); Assert.DoesNotContain(not_expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(540912, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540912")] [Fact] public void TestLookupInConstrInitIncompleteConstrDecl() { var testSrc = @" class MyClass { public MyClass(int x) { } public MyClass(int j, int k) :this(/*pos*/k) "; List<string> expected_in_lookupNames = new List<string> { "j", "k" }; List<string> expected_in_lookupSymbols = new List<string> { "System.Int32 j", "System.Int32 k", }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupNames[1], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); Assert.Contains(expected_in_lookupSymbols[1], actual_lookupSymbols_as_string); } [WorkItem(541060, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541060")] [Fact] public void TestLookupInsideIncompleteNestedLambdaBody() { var testSrc = @" class C { C() { D(() => { D(() => { }/*pos*/ "; List<string> expected_in_lookupNames = new List<string> { "C" }; List<string> expected_in_lookupSymbols = new List<string> { "C" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.NotEmpty(actual_lookupNames); Assert.NotEmpty(actual_lookupSymbols); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(541611, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541611")] [Fact] public void LookupLambdaInsideAttributeUsage() { var testSrc = @" using System; class Program { [ObsoleteAttribute(x=>x/*pos*/ static void Main(string[] args) { } } "; List<string> expected_in_lookupNames = new List<string> { "x" }; List<string> expected_in_lookupSymbols = new List<string> { "? x" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [Fact] public void LookupInsideLocalFunctionAttribute() { var testSrc = @" using System; class Program { const int w = 0451; void M() { int x = 42; const int y = 123; [ObsoleteAttribute(/*pos*/ static void local1(int z) { } } } "; var lookupNames = GetLookupNames(testSrc); var lookupSymbols = GetLookupSymbols(testSrc).Select(e => e.ToTestDisplayString()).ToList(); Assert.Contains("w", lookupNames); Assert.Contains("y", lookupNames); Assert.Contains("System.Int32 Program.w", lookupSymbols); Assert.Contains("System.Int32 y", lookupSymbols); } [Fact] public void LookupInsideLambdaAttribute() { var testSrc = @" using System; class Program { const int w = 0451; void M() { int x = 42; const int y = 123; Action<int> a = [ObsoleteAttribute(/*pos*/ (int z) => { }; } } "; var lookupNames = GetLookupNames(testSrc); var lookupSymbols = GetLookupSymbols(testSrc).Select(e => e.ToTestDisplayString()).ToList(); Assert.Contains("w", lookupNames); Assert.Contains("y", lookupNames); Assert.Contains("System.Int32 Program.w", lookupSymbols); Assert.Contains("System.Int32 y", lookupSymbols); } [Fact] public void LookupInsideIncompleteStatementAttribute() { var testSrc = @" using System; class Program { const int w = 0451; void M() { int x = 42; const int y = 123; [ObsoleteAttribute(/*pos*/ int } } "; var lookupNames = GetLookupNames(testSrc); var lookupSymbols = GetLookupSymbols(testSrc).Select(e => e.ToTestDisplayString()).ToList(); Assert.Contains("w", lookupNames); Assert.Contains("y", lookupNames); Assert.Contains("System.Int32 Program.w", lookupSymbols); Assert.Contains("System.Int32 y", lookupSymbols); } [WorkItem(541909, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541909")] [Fact] public void LookupFromRangeVariableAfterFromClause() { var testSrc = @" class Program { static void Main(string[] args) { var q = from i in new int[] { 4, 5 } where /*pos*/ } } "; List<string> expected_in_lookupNames = new List<string> { "i" }; List<string> expected_in_lookupSymbols = new List<string> { "? i" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(541921, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541921")] [Fact] public void LookupFromRangeVariableInsideNestedFromClause() { var testSrc = @" class Program { static void Main(string[] args) { string[] strings = { }; var query = from s in strings from s1 in /*pos*/ } } "; List<string> expected_in_lookupNames = new List<string> { "s" }; List<string> expected_in_lookupSymbols = new List<string> { "? s" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(541919, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541919")] [Fact] public void LookupLambdaVariableInQueryExpr() { var testSrc = @" class Program { static void Main(string[] args) { Func<int, IEnumerable<int>> f1 = (x) => from n in /*pos*/ } } "; List<string> expected_in_lookupNames = new List<string> { "x" }; List<string> expected_in_lookupSymbols = new List<string> { "x" }; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.Name); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [WorkItem(541910, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541910")] [Fact] public void LookupInsideQueryExprOutsideTypeDecl() { var testSrc = @"var q = from i in/*pos*/ f"; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.NotEmpty(actual_lookupNames); Assert.NotEmpty(actual_lookupSymbols_as_string); } [WorkItem(542203, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542203")] [Fact] public void LookupInsideQueryExprInMalformedFromClause() { var testSrc = @" using System; using System.Linq; class Program { static void Main(string[] args) { int[] numbers = new int[] { 4, 5 }; var q1 = from I<x/*pos*/ in numbers.Where(x1 => x1 > 2) select x; } } "; // Get the list of LookupNames at the location at the end of the /*pos*/ tag var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location at the end of the /*pos*/ tag var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToTestDisplayString()); Assert.NotEmpty(actual_lookupNames); Assert.NotEmpty(actual_lookupSymbols_as_string); } [WorkItem(543295, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543295")] [Fact] public void MultipleOverlappingInterfaceConstraints() { var testSrc = @"public interface IEntity { object Key { get; } } public interface INumberedProjectChild : IEntity { } public interface IAggregateRoot : IEntity { } public interface ISpecification<TCandidate> { void IsSatisfiedBy(TCandidate candidate); } public abstract class Specification<TCandidate> : ISpecification<TCandidate> { public abstract void IsSatisfiedBy(TCandidate candidate); } public class NumberSpecification<TCandidate> : Specification<TCandidate> where TCandidate : IAggregateRoot, INumberedProjectChild { public override void IsSatisfiedBy(TCandidate candidate) { var key = candidate.Key; } }"; CreateCompilation(testSrc).VerifyDiagnostics(); } [WorkItem(529406, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529406")] [Fact] public void FixedPointerInitializer() { var testSrc = @" class Program { static int num = 0; unsafe static void Main(string[] args) { fixed(int* p1 = /*pos*/&num, p2 = &num) { } } } "; List<string> expected_in_lookupNames = new List<string> { "p2" }; List<string> expected_in_lookupSymbols = new List<string> { "p2" }; // Get the list of LookupNames at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupNames = GetLookupNames(testSrc); // Get the list of LookupSymbols at the location of the CSharpSyntaxNode enclosed within the <bind> </bind> tags var actual_lookupSymbols = GetLookupSymbols(testSrc); var actual_lookupSymbols_as_string = actual_lookupSymbols.Select(e => e.ToString()).ToList(); Assert.Contains(expected_in_lookupNames[0], actual_lookupNames); Assert.Contains(expected_in_lookupSymbols[0], actual_lookupSymbols_as_string); } [Fact] public void LookupSymbolsAtEOF() { var source = @"class { }"; var tree = Parse(source); var comp = CreateCompilationWithMscorlib40(new[] { tree }); var model = comp.GetSemanticModel(tree); var eof = tree.GetCompilationUnitRoot().FullSpan.End; Assert.NotEqual(0, eof); var symbols = model.LookupSymbols(eof); CompilationUtils.CheckISymbols(symbols, "System", "Microsoft"); } [Fact, WorkItem(546523, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546523")] public void TestLookupSymbolsNestedNamespacesNotImportedByUsings_01() { var source = @" using System; class Program { static void Main(string[] args) { /*pos*/ } } "; // Get the list of LookupSymbols at the location of the CSharpSyntaxNode var actual_lookupSymbols = GetLookupSymbols(source); // Verify nested namespaces *are not* imported. var systemNS = (INamespaceSymbol)actual_lookupSymbols.Where((sym) => sym.Name.Equals("System") && sym.Kind == SymbolKind.Namespace).Single(); INamespaceSymbol systemXmlNS = systemNS.GetNestedNamespace("Xml"); Assert.DoesNotContain(systemXmlNS, actual_lookupSymbols); } [Fact, WorkItem(546523, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546523")] public void TestLookupSymbolsNestedNamespacesNotImportedByUsings_02() { var usings = "using X;"; var source = @" using aliasY = X.Y; namespace X { namespace Y { public class InnerZ { } } public class Z { } public static class StaticZ { } } public class A { public class B { } } class Program { public static void Main() { /*pos*/ } } "; // Get the list of LookupSymbols at the location of the CSharpSyntaxNode var actual_lookupSymbols = GetLookupSymbols(usings + source, isScript: false); TestLookupSymbolsNestedNamespaces(actual_lookupSymbols); actual_lookupSymbols = GetLookupSymbols(source, isScript: true, globalUsings: new[] { usings }); TestLookupSymbolsNestedNamespaces(actual_lookupSymbols); Action<ModuleSymbol> validator = (module) => { NamespaceSymbol globalNS = module.GlobalNamespace; Assert.Equal(1, globalNS.GetMembers("X").Length); Assert.Equal(1, globalNS.GetMembers("A").Length); Assert.Equal(1, globalNS.GetMembers("Program").Length); Assert.Empty(globalNS.GetMembers("Y")); Assert.Empty(globalNS.GetMembers("Z")); Assert.Empty(globalNS.GetMembers("StaticZ")); Assert.Empty(globalNS.GetMembers("B")); }; CompileAndVerify(source, sourceSymbolValidator: validator, symbolValidator: validator); } [Fact] [WorkItem(530826, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530826")] public void TestAmbiguousInterfaceLookup() { var source = @"delegate void D(); interface I1 { void M(); } interface I2 { event D M; } interface I3 : I1, I2 { } public class P : I3 { event D I2.M { add { } remove { } } void I1.M() { } } class Q : P { static int Main(string[] args) { Q p = new Q(); I3 m = p; if (m.M is object) {} return 0; } }"; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ExpressionSyntax>().Where(n => n.ToString() == "m.M").Single(); var symbolInfo = model.GetSymbolInfo(node); Assert.Equal("void I1.M()", symbolInfo.CandidateSymbols.Single().ToTestDisplayString()); Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); var node2 = (ExpressionSyntax)SyntaxFactory.SyntaxTree(node).GetRoot(); symbolInfo = model.GetSpeculativeSymbolInfo(node.Position, node2, SpeculativeBindingOption.BindAsExpression); Assert.Equal("void I1.M()", symbolInfo.CandidateSymbols.Single().ToTestDisplayString()); Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); } [Fact] public void TestLookupVerbatimVar() { var source = "class C { public static void Main() { @var v = 1; } }"; CreateCompilation(source).VerifyDiagnostics( // (1,39): error CS0246: The type or namespace name 'var' could not be found (are you missing a using directive or an assembly reference?) // class C { public static void Main() { @var v = 1; } } Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "@var").WithArguments("var").WithLocation(1, 39) ); } private void TestLookupSymbolsNestedNamespaces(List<ISymbol> actual_lookupSymbols) { var namespaceX = (INamespaceSymbol)actual_lookupSymbols.Where((sym) => sym.Name.Equals("X") && sym.Kind == SymbolKind.Namespace).Single(); // Verify nested namespaces within namespace X *are not* present in lookup symbols. INamespaceSymbol namespaceY = namespaceX.GetNestedNamespace("Y"); Assert.DoesNotContain(namespaceY, actual_lookupSymbols); INamedTypeSymbol typeInnerZ = namespaceY.GetTypeMembers("InnerZ").Single(); Assert.DoesNotContain(typeInnerZ, actual_lookupSymbols); // Verify nested types *are not* present in lookup symbols. var typeA = (INamedTypeSymbol)actual_lookupSymbols.Where((sym) => sym.Name.Equals("A") && sym.Kind == SymbolKind.NamedType).Single(); INamedTypeSymbol typeB = typeA.GetTypeMembers("B").Single(); Assert.DoesNotContain(typeB, actual_lookupSymbols); // Verify aliases to nested namespaces within namespace X *are* present in lookup symbols. var aliasY = (IAliasSymbol)actual_lookupSymbols.Where((sym) => sym.Name.Equals("aliasY") && sym.Kind == SymbolKind.Alias).Single(); Assert.Contains(aliasY, actual_lookupSymbols); } [Fact] public void ExtensionMethodCall() { var source = @"static class E { internal static void F(this object o) { } } class C { void M() { /*<bind>*/this.F/*</bind>*/(); } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); compilation.VerifyDiagnostics(); var exprs = GetExprSyntaxList(tree); var expr = GetExprSyntaxForBinding(exprs); var method = (IMethodSymbol)model.GetSymbolInfo(expr).Symbol; Assert.Equal("object.F()", method.ToDisplayString()); var reducedFrom = method.ReducedFrom; Assert.NotNull(reducedFrom); Assert.Equal("E.F(object)", reducedFrom.ToDisplayString()); } [WorkItem(3651, "https://github.com/dotnet/roslyn/issues/3651")] [Fact] public void ExtensionMethodDelegateCreation() { var source = @"static class E { internal static void F(this object o) { } } class C { void M() { (new System.Action<object>(/*<bind>*/E.F/*</bind>*/))(this); (new System.Action(/*<bind1>*/this.F/*</bind1>*/))(); } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); compilation.VerifyDiagnostics(); var exprs = GetExprSyntaxList(tree); var expr = GetExprSyntaxForBinding(exprs, index: 0); var method = (IMethodSymbol)model.GetSymbolInfo(expr).Symbol; Assert.Null(method.ReducedFrom); Assert.Equal("E.F(object)", method.ToDisplayString()); expr = GetExprSyntaxForBinding(exprs, index: 1); method = (IMethodSymbol)model.GetSymbolInfo(expr).Symbol; Assert.Equal("object.F()", method.ToDisplayString()); var reducedFrom = method.ReducedFrom; Assert.NotNull(reducedFrom); Assert.Equal("E.F(object)", reducedFrom.ToDisplayString()); } [WorkItem(7493, "https://github.com/dotnet/roslyn/issues/7493")] [Fact] public void GenericNameLookup() { var source = @"using A = List<int>;"; var compilation = CreateCompilation(source).VerifyDiagnostics( // (1,11): error CS0246: The type or namespace name 'List<>' could not be found (are you missing a using directive or an assembly reference?) // using A = List<int>; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "List<int>").WithArguments("List<>").WithLocation(1, 11), // (1,1): hidden CS8019: Unnecessary using directive. // using A = List<int>; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using A = List<int>;").WithLocation(1, 1)); } #endregion tests #region regressions [Fact] [WorkItem(552472, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/552472")] public void BrokenCode01() { var source = @"Dele<Str> d3 = delegate (Dele<Str> d2 = delegate () { returne<double> d1 = delegate () { return 1; }; { int result = 0; Dels Test : Base"; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); SemanticModel imodel = model; var node = tree.GetRoot().DescendantNodes().Where(n => n.ToString() == "returne<double>").First(); imodel.GetSymbolInfo(node, default(CancellationToken)); } [Fact] [WorkItem(552472, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/552472")] public void BrokenCode02() { var source = @"public delegate D D(D d); class Program { public D d3 = delegate(D d2 = delegate { System.Object x = 3; return null; }) {}; public static void Main(string[] args) { } } "; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); SemanticModel imodel = model; var node = tree.GetRoot().DescendantNodes().Where(n => n.ToString() == "System.Object").First(); imodel.GetSymbolInfo(node, default(CancellationToken)); } [Fact] public void InterfaceDiamondHiding() { var source = @" interface T { int P { get; set; } int Q { get; set; } } interface L : T { new int P { get; set; } } interface R : T { new int Q { get; set; } } interface B : L, R { } class Test { int M(B b) { return b.P + b.Q; } } "; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var global = comp.GlobalNamespace; var interfaceT = global.GetMember<NamedTypeSymbol>("T"); var interfaceL = global.GetMember<NamedTypeSymbol>("L"); var interfaceR = global.GetMember<NamedTypeSymbol>("R"); var interfaceB = global.GetMember<NamedTypeSymbol>("B"); var propertyTP = interfaceT.GetMember<PropertySymbol>("P"); var propertyTQ = interfaceT.GetMember<PropertySymbol>("Q"); var propertyLP = interfaceL.GetMember<PropertySymbol>("P"); var propertyRQ = interfaceR.GetMember<PropertySymbol>("Q"); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var syntaxes = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().ToArray(); Assert.Equal(2, syntaxes.Length); // The properties in T are hidden - we bind to the properties on more-derived interfaces Assert.Equal(propertyLP.GetPublicSymbol(), model.GetSymbolInfo(syntaxes[0]).Symbol); Assert.Equal(propertyRQ.GetPublicSymbol(), model.GetSymbolInfo(syntaxes[1]).Symbol); int position = source.IndexOf("return", StringComparison.Ordinal); // We do the right thing with diamond inheritance (i.e. member is hidden along all paths // if it is hidden along any path) because we visit base interfaces in topological order. Assert.Equal(propertyLP.GetPublicSymbol(), model.LookupSymbols(position, interfaceB.GetPublicSymbol(), "P").Single()); Assert.Equal(propertyRQ.GetPublicSymbol(), model.LookupSymbols(position, interfaceB.GetPublicSymbol(), "Q").Single()); } [Fact] public void SemanticModel_OnlyInvalid() { var source = @" public class C { void M() { return; } } "; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); int position = source.IndexOf("return", StringComparison.Ordinal); var symbols = model.LookupNamespacesAndTypes(position, name: "M"); Assert.Equal(0, symbols.Length); } [Fact] public void SemanticModel_InvalidHidingValid() { var source = @" public class C<T> { public class Inner { void T() { return; } } } "; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var classC = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C"); var methodT = classC.GetMember<NamedTypeSymbol>("Inner").GetMember<MethodSymbol>("T"); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); int position = source.IndexOf("return", StringComparison.Ordinal); var symbols = model.LookupSymbols(position, name: "T"); Assert.Equal(methodT.GetPublicSymbol(), symbols.Single()); // Hides type parameter. symbols = model.LookupNamespacesAndTypes(position, name: "T"); Assert.Equal(classC.TypeParameters.Single().GetPublicSymbol(), symbols.Single()); // Ignore intervening method. } [Fact] public void SemanticModel_MultipleValid() { var source = @" public class Outer { void M(int x) { } void M() { return; } } "; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); int position = source.IndexOf("return", StringComparison.Ordinal); var symbols = model.LookupSymbols(position, name: "M"); Assert.Equal(2, symbols.Length); } [Fact, WorkItem(1078958, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078958")] public void Bug1078958() { const string source = @" class C { static void Goo<T>() { /*<bind>*/T/*</bind>*/(); } static void T() { } }"; var symbols = GetLookupSymbols(source); Assert.True(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961() { const string source = @" class C { const int T = 42; static void Goo<T>(int x = /*<bind>*/T/*</bind>*/) { System.Console.Write(x); } static void Main() { Goo<object>(); } }"; var symbols = GetLookupSymbols(source); Assert.False(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961_2() { const string source = @" class A : System.Attribute { public A(int i) { } } class C { const int T = 42; static void Goo<T>([A(/*<bind>*/T/*</bind>*/)] int x) { } }"; var symbols = GetLookupSymbols(source); Assert.False(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961_3() { const string source = @" class A : System.Attribute { public A(int i) { } } class C { const int T = 42; [A(/*<bind>*/T/*</bind>*/)] static void Goo<T>(int x) { } }"; var symbols = GetLookupSymbols(source); Assert.False(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961_4() { const string source = @" class A : System.Attribute { public A(int i) { } } class C { const int T = 42; static void Goo<[A(/*<bind>*/T/*</bind>*/)] T>(int x) { } }"; var symbols = GetLookupSymbols(source); Assert.False(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961_5() { const string source = @" class C { class T { } static void Goo<T>(T x = default(/*<bind>*/T/*</bind>*/)) { System.Console.Write((object)x == null); } static void Main() { Goo<object>(); } }"; var symbols = GetLookupSymbols(source); Assert.True(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1078961, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1078961")] public void Bug1078961_6() { const string source = @" class C { class T { } static void Goo<T>(T x = default(/*<bind>*/T/*</bind>*/)) { System.Console.Write((object)x == null); } static void Main() { Goo<object>(); } }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var position = GetPositionForBinding(tree); var symbols = model.LookupNamespacesAndTypes(position); Assert.True(symbols.Any(s => s.Kind == SymbolKind.TypeParameter)); } [Fact, WorkItem(1091936, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1091936")] public void Bug1091936_1() { const string source = @" class Program { static object M(long l) { return null; } static object M(int i) { return null; } static void Main(string[] args) { (M(0))?.ToString(); } } "; var comp = CreateCompilationWithMscorlib40AndSystemCore(source); comp.VerifyDiagnostics(); var ms = comp.GlobalNamespace.GetTypeMembers("Program").Single().GetMembers("M").OfType<MethodSymbol>(); var m = ms.Where(mm => mm.Parameters[0].Type.SpecialType == SpecialType.System_Int32).Single(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First(); var symbolInfo = model.GetSymbolInfo(call.Expression); Assert.NotEqual(default, symbolInfo); Assert.Equal(symbolInfo.Symbol.GetSymbol(), m); } [Fact, WorkItem(1091936, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1091936")] public void Bug1091936_2() { const string source = @" class Program { static object M = null; static void Main(string[] args) { M?.ToString(); } } "; var comp = CreateCompilationWithMscorlib40AndSystemCore(source); comp.VerifyDiagnostics(); var m = comp.GlobalNamespace.GetTypeMembers("Program").Single().GetMembers("M").Single(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ConditionalAccessExpressionSyntax>().Single().Expression; var symbolInfo = model.GetSymbolInfo(node); Assert.NotEqual(default, symbolInfo); Assert.Equal(symbolInfo.Symbol.GetSymbol(), m); } [Fact, WorkItem(1091936, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1091936")] public void Bug1091936_3() { const string source = @" class Program { object M = null; static void Main(string[] args) { (new Program()).M?.ToString(); } } "; var comp = CreateCompilationWithMscorlib40AndSystemCore(source); comp.VerifyDiagnostics(); var m = comp.GlobalNamespace.GetTypeMembers("Program").Single().GetMembers("M").Single(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ConditionalAccessExpressionSyntax>().Single().Expression; var symbolInfo = model.GetSymbolInfo(node); Assert.NotEqual(default, symbolInfo); Assert.Equal(symbolInfo.Symbol.GetSymbol(), m); } [Fact, WorkItem(1091936, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1091936")] public void Bug1091936_4() { const string source = @" class Program { static void Main(string[] args) { var y = (System.Linq.Enumerable.Select<string, int>(args, s => int.Parse(s)))?.ToString(); } } "; var comp = CreateCompilationWithMscorlib40AndSystemCore(source); comp.VerifyDiagnostics(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<GenericNameSyntax>().Single(); var symbolInfo = model.GetSymbolInfo(node); Assert.NotEqual(default, symbolInfo); Assert.NotNull(symbolInfo.Symbol); } [Fact] public void GenericAttribute_LookupSymbols_01() { var source = @" using System; class Attr1<T> : Attribute { public Attr1(T t) { } } [Attr1<string>(""a"")] class C { }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<AttributeSyntax>().Single(); var symbol = model.GetSymbolInfo(node); Assert.Equal("Attr1<System.String>..ctor(System.String t)", symbol.Symbol.ToTestDisplayString()); } [Fact] public void GenericAttribute_LookupSymbols_02() { var source = @" using System; class Attr1<T> : Attribute { public Attr1(T t) { } } [Attr1</*<bind>*/string/*</bind>*/>] class C { }"; var names = GetLookupNames(source); Assert.Contains("C", names); Assert.Contains("Attr1", names); } #endregion } }