public void GetMethodId_Explicit_Interface_Implementations() { const string code = @" using System; using System.Collections.Generic; namespace Namespace { public class Bar : IBar { void IBar.Foo(string s) { } public void Foo(string s) { } } public interface IBar { void Foo(string s); } } "; var(syntaxTree, semanticModel) = TestHelper.Compile(code); MethodId("Foo").Should().Be("Namespace.IBar.Foo(string)"); MethodId("Foo", skip: 1).Should().Be("Namespace.Bar.Foo(string)"); string MethodId(string methodName, int skip = 0) => UniversalControlFlowGraphBuilder.GetMethodId(semanticModel.GetDeclaredSymbol(syntaxTree.GetMethod(methodName, skip))); }
public void GetMethodId_Constructors() { const string code = @" using System; namespace Namespace { public class Class1 { public Class1() { } public Class1(string s) { } } } "; var(syntaxTree, semanticModel) = TestHelper.Compile(code); CtorId("Class1").Should().Be("Namespace.Class1.Class1()"); CtorId("Class1", skip: 1).Should().Be("Namespace.Class1.Class1(string)"); string CtorId(string className, int skip = 0) => UniversalControlFlowGraphBuilder.GetMethodId(semanticModel.GetDeclaredSymbol(syntaxTree.GetConstructor(className, skip))); }
public void GetMethodId_Methods() { const string code = @" using System; using System.Collections.Generic; namespace Namespace { public class Class1 { public void PrimitiveTypes1(string s) { } public void PrimitiveTypes2(String s) { } public void PrimitiveTypes3(System.String s) { } public void ArrayTypes1(string[] s) { } public void ArrayTypes2(string[,] s) { } public void ArrayTypes3(string[][] s) { } public void UserType(Class1 s) { } public void SystemType(Uri uri) { } public void GenericMethod1<T1,T2>(T1 x) { } public void Nullables(int? x, Nullable<int> y) { } public void GenericArgument(IEnumerable<string> strings) { } public void Overload1(string s) { } public void Overload1(string s, string s) { } public void NestedMethods() { void Foo() { } // We don't really support nested, but we should not throw } public class Class2 { public void InnerClass(Class2 s) { } } } public class GenericClass<T1> { public void GenericMethod2(T1 x) { } public void GenericMethod3<T2>(T1 x, T2 y) { } } public class BaseClass<T1> { public virtual void Method1(T1 x) { } public virtual void Method2(T1 x) { } } public class Descendant : BaseClass<string> { public override void Method1(string x) { } } namespace Inner { public class Class2 { public string InnerNamespace() { } } } } public class Class3 { public void NoNamespace(Class3 s) { } } public static class Extensions { public static void Extension(this string s, int x) { } }"; var(syntaxTree, semanticModel) = TestHelper.Compile(code); MethodId("PrimitiveTypes1").Should().Be("Namespace.Class1.PrimitiveTypes1(string)"); MethodId("PrimitiveTypes2").Should().Be("Namespace.Class1.PrimitiveTypes2(string)"); MethodId("PrimitiveTypes3").Should().Be("Namespace.Class1.PrimitiveTypes3(string)"); MethodId("ArrayTypes1").Should().Be("Namespace.Class1.ArrayTypes1(string[])"); MethodId("ArrayTypes2").Should().Be("Namespace.Class1.ArrayTypes2(string[*,*])"); MethodId("ArrayTypes3").Should().Be("Namespace.Class1.ArrayTypes3(string[][])"); MethodId("UserType").Should().Be("Namespace.Class1.UserType(Namespace.Class1)"); MethodId("SystemType").Should().Be("Namespace.Class1.SystemType(System.Uri)"); MethodId("GenericMethod1").Should().Be("Namespace.Class1.GenericMethod1<T1, T2>(T1)"); MethodId("Nullables").Should().Be("Namespace.Class1.Nullables(int?, int?)"); MethodId("GenericArgument").Should().Be("Namespace.Class1.GenericArgument(System.Collections.Generic.IEnumerable<string>)"); MethodId("Overload1").Should().Be("Namespace.Class1.Overload1(string)"); MethodId("Overload1", skip: 1).Should().Be("Namespace.Class1.Overload1(string, string)"); MethodId("GenericMethod2").Should().Be("Namespace.GenericClass<T1>.GenericMethod2(T1)"); MethodId("GenericMethod3").Should().Be("Namespace.GenericClass<T1>.GenericMethod3<T2>(T1, T2)"); MethodId("InnerClass").Should().Be("Namespace.Class1.Class2.InnerClass(Namespace.Class1.Class2)"); MethodId("Method1").Should().Be("Namespace.BaseClass<T1>.Method1(T1)"); MethodId("Method1", skip: 1).Should().Be("Namespace.Descendant.Method1(string)"); MethodId("InnerNamespace").Should().Be("Namespace.Inner.Class2.InnerNamespace()"); MethodId("NoNamespace").Should().Be("Class3.NoNamespace(Class3)"); MethodId("Extension").Should().Be("Extensions.Extension(string, int)"); string MethodId(string methodName, int skip = 0) => UniversalControlFlowGraphBuilder.GetMethodId(semanticModel.GetDeclaredSymbol(syntaxTree.GetMethod(methodName, skip))); }
public void GetMethodId_Properties() { const string code = @" using System; namespace Namespace { public class Class1 { public string Property1 { get { return null; } set { } } public string Property2 => null; } public class GenericClass<T1> { public T1 Property3 { get; set; } } public class BaseClass<T1> { public virtual T1 Property4 { get { return default(T1); } set { } } } public class Descendant : BaseClass<string> { public override string Property4 { get { return null; } set { } } } namespace Inner { public class Class2 { public string Property5 { get; set; } } } } public class Class3 { public string Property6 { get; set; } }"; var(syntaxTree, semanticModel) = TestHelper.Compile(code); PropertyGetId("Property1").Should().Be("Namespace.Class1.Property1.get"); PropertySetId("Property1").Should().Be("Namespace.Class1.Property1.set"); PropertyGetId("Property2").Should().Be("Namespace.Class1.Property2.get"); PropertySetId("Property2").Should().Be(KnownMethodId.Unknown); PropertyGetId("Property3").Should().Be("Namespace.GenericClass<T1>.Property3.get"); PropertySetId("Property3").Should().Be("Namespace.GenericClass<T1>.Property3.set"); PropertyGetId("Property4").Should().Be("Namespace.BaseClass<T1>.Property4.get"); PropertySetId("Property4").Should().Be("Namespace.BaseClass<T1>.Property4.set"); PropertyGetId("Property4", 1).Should().Be("Namespace.Descendant.Property4.get"); PropertySetId("Property4", 1).Should().Be("Namespace.Descendant.Property4.set"); PropertyGetId("Property5").Should().Be("Namespace.Inner.Class2.Property5.get"); PropertySetId("Property5").Should().Be("Namespace.Inner.Class2.Property5.set"); PropertyGetId("Property6").Should().Be("Class3.Property6.get"); PropertySetId("Property6").Should().Be("Class3.Property6.set"); string PropertyGetId(string propertyName, int skip = 0) => UniversalControlFlowGraphBuilder.GetMethodId(semanticModel.GetDeclaredSymbol(syntaxTree.GetProperty(propertyName, skip)).GetMethod); string PropertySetId(string propertyName, int skip = 0) => UniversalControlFlowGraphBuilder.GetMethodId(semanticModel.GetDeclaredSymbol(syntaxTree.GetProperty(propertyName, skip)).SetMethod); }