/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Symbol/Symbols/MethodEqualityTests.cs
264 строки
10 KB
Jared Parsons
generated move
28 сен 2020, 19:36
28 сен 2020, 19:36
1cca63b
Код
Авторство
О чём код?
// 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.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class MethodEqualityTests : CSharpTestBase { [Fact] public void NoGenerics() { var text = @" class Class1 { void Method1() { } void Method2() { } } class Class2 { void Method1() { } } "; var comp = CreateCompilation(text); var global = comp.GlobalNamespace; var class1 = global.GetTypeMembers("Class1").Single(); var class1Method1 = (MethodSymbol)class1.GetMembers("Method1").Single(); var class1Method2 = (MethodSymbol)class1.GetMembers("Method2").Single(); var class2 = global.GetTypeMembers("Class2").Single(); var class2Method1 = (MethodSymbol)class2.GetMembers("Method1").Single(); Assert.Equal(class1Method1, class1Method1); //null Assert.NotNull(class1Method1); Assert.NotNull(class1Method1); //different type Assert.NotEqual<Symbol>(class1, class1Method1); Assert.NotEqual<Symbol>(class1Method1, class1); //different original definition Assert.NotEqual(class1Method1, class1Method2); Assert.NotEqual(class1Method2, class1Method1); //different containing type Assert.NotEqual(class1Method1, class2Method1); Assert.NotEqual(class2Method1, class1Method1); } [Fact] public void GenericsTypes() { var text = @" class Base<T> { void Method(T t) { } void Method(int i) { } } class Derived1<S> : Base<S> { } class Derived2 : Base<int> { } "; var comp = CreateCompilation(text); var global = comp.GlobalNamespace; var baseClass = global.GetTypeMembers("Base").Single(); var baseClassMethod1 = (MethodSymbol)baseClass.GetMembers("Method").First(); var baseClassMethod2 = (MethodSymbol)baseClass.GetMembers("Method").Last(); var derivedClass1 = global.GetTypeMembers("Derived1").Single(); var substitutedBaseClass = derivedClass1.BaseType(); var substitutedBaseClassMethod1 = (MethodSymbol)substitutedBaseClass.GetMembers("Method").First(); var substitutedBaseClassMethod2 = (MethodSymbol)substitutedBaseClass.GetMembers("Method").Last(); var derivedClass2 = global.GetTypeMembers("Derived2").Single(); var constructedBaseClass = derivedClass2.BaseType(); var constructedBaseClassMethod1 = (MethodSymbol)constructedBaseClass.GetMembers("Method").First(); var constructedBaseClassMethod2 = (MethodSymbol)constructedBaseClass.GetMembers("Method").Last(); //different type args Assert.NotEqual(baseClassMethod1, substitutedBaseClassMethod1); Assert.NotEqual(substitutedBaseClassMethod1, baseClassMethod1); //different type args Assert.NotEqual(baseClassMethod1, constructedBaseClassMethod1); Assert.NotEqual(constructedBaseClassMethod1, baseClassMethod1); //different type args Assert.NotEqual(substitutedBaseClassMethod1, constructedBaseClassMethod1); Assert.NotEqual(constructedBaseClassMethod1, substitutedBaseClassMethod1); //different original definitions Assert.NotEqual(baseClassMethod1, baseClassMethod2); Assert.NotEqual(baseClassMethod2, baseClassMethod1); //different original definitions Assert.NotEqual(substitutedBaseClassMethod1, substitutedBaseClassMethod2); Assert.NotEqual(substitutedBaseClassMethod2, substitutedBaseClassMethod1); //different original definitions (though signatures and bodies now match) Assert.NotEqual(constructedBaseClassMethod1, constructedBaseClassMethod2); Assert.NotEqual(constructedBaseClassMethod2, constructedBaseClassMethod1); } [Fact] public void GenericsTypesAndMethods() { var text = @" class Base<T> { U Method<U>(T t) { } V Method<V>(int i) { } } class Derived1<S> : Base<S> { } class Derived2 : Base<int> { } "; var comp = CreateCompilation(text); var global = comp.GlobalNamespace; var baseClass = global.GetTypeMembers("Base").Single(); var baseClassMethod1 = (MethodSymbol)baseClass.GetMembers("Method").First(); var baseClassMethod2 = (MethodSymbol)baseClass.GetMembers("Method").Last(); var derivedClass1 = global.GetTypeMembers("Derived1").Single(); var substitutedBaseClass = derivedClass1.BaseType(); var substitutedBaseClassMethod1 = (MethodSymbol)substitutedBaseClass.GetMembers("Method").First(); var substitutedBaseClassMethod2 = (MethodSymbol)substitutedBaseClass.GetMembers("Method").Last(); var derivedClass2 = global.GetTypeMembers("Derived2").Single(); var constructedBaseClass = derivedClass2.BaseType(); var constructedBaseClassMethod1 = (MethodSymbol)constructedBaseClass.GetMembers("Method").First(); var constructedBaseClassMethod2 = (MethodSymbol)constructedBaseClass.GetMembers("Method").Last(); //different type args Assert.NotEqual(baseClassMethod1, substitutedBaseClassMethod1); Assert.NotEqual(substitutedBaseClassMethod1, baseClassMethod1); //different type args Assert.NotEqual(baseClassMethod1, constructedBaseClassMethod1); Assert.NotEqual(constructedBaseClassMethod1, baseClassMethod1); //different type args Assert.NotEqual(substitutedBaseClassMethod1, constructedBaseClassMethod1); Assert.NotEqual(constructedBaseClassMethod1, substitutedBaseClassMethod1); //different original definitions Assert.NotEqual(baseClassMethod1, baseClassMethod2); Assert.NotEqual(baseClassMethod2, baseClassMethod1); //different original definitions Assert.NotEqual(substitutedBaseClassMethod1, substitutedBaseClassMethod2); Assert.NotEqual(substitutedBaseClassMethod2, substitutedBaseClassMethod1); //different original definitions (though signatures and bodies now match) Assert.NotEqual(constructedBaseClassMethod1, constructedBaseClassMethod2); Assert.NotEqual(constructedBaseClassMethod2, constructedBaseClassMethod1); } [Fact] public void SubstitutedGenericMethods() { var text = @" class Class { void Method<U, V>(U u, V v) { Method<char, int>('a', 1); //0 Method<char, int>('b', 2); //1 Method<int, char>(1, 'a'); //2 Method<U, V>(u, v); //3 Method<U, V>(u, v); //4 Method<V, U>(v, u); //5 } } "; var comp = (Compilation)CreateCompilation(text); var global = comp.GlobalNamespace; var @class = global.GetTypeMembers("Class").Single(); var classMethodDeclaration = (IMethodSymbol)@class.GetMembers("Method").Single(); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var root = tree.GetCompilationUnitRoot(); var cDecl = (TypeDeclarationSyntax)root.Members[0]; var mDecl = (MethodDeclarationSyntax)cDecl.Members[0]; var stmts = mDecl.Body.Statements; var invokedMethods = stmts.Select(stmt => { var exprStmt = (ExpressionStatementSyntax)stmt; var semanticInfo = model.GetSymbolInfo(exprStmt.Expression); return (IMethodSymbol)semanticInfo.Symbol; }).ToArray(); Assert.Equal(6, invokedMethods.Length); //invocations are equal to themselves Assert.True(invokedMethods.All(m => m.Equals(m))); //invocations may be equal to declarations if type arguments are the same Assert.NotEqual(invokedMethods[0], classMethodDeclaration); Assert.NotEqual(invokedMethods[1], classMethodDeclaration); Assert.NotEqual(invokedMethods[2], classMethodDeclaration); Assert.Equal(invokedMethods[3], classMethodDeclaration); Assert.Equal(invokedMethods[4], classMethodDeclaration); Assert.NotEqual(invokedMethods[5], classMethodDeclaration); //invocations are equal to other invocations with the same substitutions Assert.Equal(invokedMethods[0], invokedMethods[1]); Assert.Equal(invokedMethods[1], invokedMethods[0]); Assert.Equal(invokedMethods[3], invokedMethods[4]); Assert.Equal(invokedMethods[4], invokedMethods[3]); //invocations with different type args are not equal var pairWiseNotEqual = new IMethodSymbol[] { invokedMethods[0], invokedMethods[2], invokedMethods[3], invokedMethods[5], }; foreach (var method1 in pairWiseNotEqual) { foreach (var method2 in pairWiseNotEqual) { if (ReferenceEquals(method1, method2)) { continue; } Assert.NotEqual(method1, method2); Assert.NotEqual(method2, method1); } } } } }