a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
419 lines
12 KiB
C#
419 lines
12 KiB
C#
//
|
|
// System.Reflection.MethodBase Test Cases
|
|
//
|
|
// Authors:
|
|
// Gert Driesen (drieseng@users.sourceforge.net)
|
|
//
|
|
// Copyright (C) 2008 Gert Driesen
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
|
|
using NUnit.Framework;
|
|
|
|
namespace MonoTests.System.Reflection
|
|
{
|
|
public class Generic<T> {
|
|
public void Foo () {
|
|
}
|
|
|
|
public void GenericFoo<K> () {
|
|
|
|
}
|
|
}
|
|
|
|
public class AnotherGeneric<T> {
|
|
public void Foo () {
|
|
}
|
|
}
|
|
|
|
public class SimpleClass {
|
|
public void GenericFoo<K> () {
|
|
|
|
}
|
|
}
|
|
|
|
class MethodBaseOverloadTestDoesNotCauseCompilerError : MethodBase
|
|
{
|
|
public override MethodAttributes Attributes
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
|
|
public override MethodImplAttributes GetMethodImplementationFlags ()
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override ParameterInfo[] GetParameters ()
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, global::System.Globalization.CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override RuntimeMethodHandle MethodHandle
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
|
|
public override Type DeclaringType
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
|
|
public override object[] GetCustomAttributes (Type attributeType, bool inherit)
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override object[] GetCustomAttributes (bool inherit)
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override bool IsDefined (Type attributeType, bool inherit)
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public override MemberTypes MemberType
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
|
|
public override string Name
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
|
|
public override Type ReflectedType
|
|
{
|
|
get { throw new NotImplementedException (); }
|
|
}
|
|
}
|
|
|
|
[TestFixture]
|
|
public class MethodBaseTest
|
|
{
|
|
public static MethodInfo Where<T> (T a) {
|
|
return (MethodInfo) MethodBase.GetCurrentMethod ();
|
|
}
|
|
|
|
public class Foo<K>
|
|
{
|
|
public static MethodInfo Where<T> (T a, K b) {
|
|
return (MethodInfo) MethodBase.GetCurrentMethod ();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetCurrentMethodDropsAllGenericArguments ()
|
|
{
|
|
MethodInfo a = Where<int> (10);
|
|
MethodInfo b = Foo<int>.Where <double> (10, 10);
|
|
|
|
Assert.IsTrue (a.IsGenericMethodDefinition, "#1");
|
|
Assert.IsTrue (b.IsGenericMethodDefinition, "#2");
|
|
|
|
Assert.IsTrue (b.DeclaringType.IsGenericTypeDefinition, "#3");
|
|
|
|
Assert.AreSame (a, typeof (MethodBaseTest).GetMethod ("Where"), "#4");
|
|
Assert.AreSame (b, typeof (Foo<>).GetMethod ("Where"), "#5");
|
|
}
|
|
|
|
[Test] // GetMethodFromHandle (RuntimeMethodHandle)
|
|
public void GetMethodFromHandle1_Handle_Generic ()
|
|
{
|
|
G<string> instance = new G<string> ();
|
|
Type t = instance.GetType ();
|
|
MethodBase mb1 = t.GetMethod ("M");
|
|
RuntimeMethodHandle mh = mb1.MethodHandle;
|
|
RuntimeTypeHandle th = t.TypeHandle;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (mh);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
// Cannot resolve method Void M(System.__Canon)
|
|
// because the declaring type of the method
|
|
// handle MonoTests.System.Reflection.MethodBaseTest+G`1[T]
|
|
// is generic. Explicitly provide the declaring type to
|
|
// GetMethodFromHandle
|
|
}
|
|
}
|
|
|
|
[Test] // GetMethodFromHandle (RuntimeMethodHandle)
|
|
public void GetMethodFromHandle1_Handle_Zero ()
|
|
{
|
|
RuntimeMethodHandle mh = new RuntimeMethodHandle ();
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (mh);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
// Handle is not initialized
|
|
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
|
|
Assert.IsNull (ex.InnerException, "#3");
|
|
Assert.IsNotNull (ex.Message, "#4");
|
|
Assert.IsNull (ex.ParamName, "#5");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle ()
|
|
{
|
|
Type t = typeof (object);
|
|
RuntimeMethodHandle rmh = t.GetConstructor (Type.EmptyTypes).MethodHandle;
|
|
MethodBase mb = MethodBase.GetMethodFromHandle (rmh);
|
|
Assert.IsNotNull (mb, "#1");
|
|
Assert.AreEqual (t, mb.DeclaringType, "#2");
|
|
Assert.AreEqual (".ctor", mb.Name, "#3");
|
|
ParameterInfo [] parameters = mb.GetParameters ();
|
|
Assert.IsNotNull (parameters, "#4");
|
|
Assert.AreEqual (0, parameters.Length, "#5");
|
|
}
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle_NonGenericType_DeclaringTypeZero ()
|
|
{
|
|
Type t = typeof (object);
|
|
RuntimeMethodHandle rmh = t.GetConstructor (Type.EmptyTypes).MethodHandle;
|
|
MethodBase mb = MethodBase.GetMethodFromHandle (rmh, new RuntimeTypeHandle ());
|
|
Assert.IsNotNull (mb, "#1");
|
|
Assert.AreEqual (t, mb.DeclaringType, "#2");
|
|
Assert.AreEqual (".ctor", mb.Name, "#3");
|
|
ParameterInfo [] parameters = mb.GetParameters ();
|
|
Assert.IsNotNull (parameters, "#4");
|
|
Assert.AreEqual (0, parameters.Length, "#5");
|
|
}
|
|
|
|
[Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
|
|
public void GetMethodFromHandle2_DeclaringType_Zero ()
|
|
{
|
|
RuntimeTypeHandle th = new RuntimeTypeHandle ();
|
|
Type t = typeof (G<>);
|
|
RuntimeMethodHandle mh = t.GetMethod ("M").MethodHandle;
|
|
|
|
MethodBase mb = MethodBase.GetMethodFromHandle (mh, th);
|
|
Assert.IsNotNull (mb, "#1");
|
|
Assert.AreEqual (t, mb.DeclaringType, "#2");
|
|
Assert.AreEqual ("M", mb.Name, "#3");
|
|
ParameterInfo [] parameters = mb.GetParameters ();
|
|
Assert.IsNotNull (parameters, "#4");
|
|
Assert.AreEqual (1, parameters.Length, "#5");
|
|
Assert.AreEqual (t.GetGenericArguments () [0] , parameters [0].ParameterType, "#6");
|
|
}
|
|
|
|
[Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
|
|
public void GetMethodFromHandle2_Handle_Generic ()
|
|
{
|
|
G<string> instance = new G<string> ();
|
|
Type t = instance.GetType ();
|
|
MethodBase mb1 = t.GetMethod ("M");
|
|
RuntimeMethodHandle mh = mb1.MethodHandle;
|
|
RuntimeTypeHandle th = t.TypeHandle;
|
|
|
|
MethodBase mb2 = MethodBase.GetMethodFromHandle (mh, th);
|
|
Assert.IsNotNull (mb2, "#1");
|
|
Assert.AreEqual (t, mb2.DeclaringType, "#2");
|
|
Assert.AreEqual ("M", mb2.Name, "#3");
|
|
ParameterInfo [] parameters = mb2.GetParameters ();
|
|
Assert.IsNotNull (parameters, "#4");
|
|
Assert.AreEqual (1, parameters.Length, "#5");
|
|
Assert.AreEqual (typeof (string), parameters [0].ParameterType, "#6");
|
|
}
|
|
|
|
[Test] // GetMethodFromHandle (RuntimeMethodHandle, RuntimeTypeHandle)
|
|
public void GetMethodFromHandle2_Handle_Zero ()
|
|
{
|
|
RuntimeTypeHandle th = typeof (G<>).TypeHandle;
|
|
RuntimeMethodHandle mh = new RuntimeMethodHandle ();
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (mh, th);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
// Handle is not initialized
|
|
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
|
|
Assert.IsNull (ex.InnerException, "#3");
|
|
Assert.IsNotNull (ex.Message, "#4");
|
|
Assert.IsNull (ex.ParamName, "#5");
|
|
}
|
|
}
|
|
|
|
public class G<T>
|
|
{
|
|
public void M (T t)
|
|
{
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle_Handle_Generic_Method ()
|
|
{
|
|
MethodInfo mi = typeof (SimpleClass).GetMethod ("GenericFoo");
|
|
RuntimeMethodHandle handle = mi.MethodHandle;
|
|
|
|
MethodBase res = MethodBase.GetMethodFromHandle (handle);
|
|
Assert.AreEqual (mi, res, "#1");
|
|
|
|
res = MethodBase.GetMethodFromHandle (handle, typeof (SimpleClass).TypeHandle);
|
|
Assert.AreEqual (mi, res, "#2");
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle_Handle_Generic_Method_Instance ()
|
|
{
|
|
MethodInfo mi = typeof (SimpleClass).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
|
|
RuntimeMethodHandle handle = mi.MethodHandle;
|
|
|
|
MethodBase res = MethodBase.GetMethodFromHandle (handle);
|
|
Assert.AreEqual (mi, res, "#1");
|
|
|
|
res = MethodBase.GetMethodFromHandle (handle, typeof (SimpleClass).TypeHandle);
|
|
Assert.AreEqual (mi, res, "#2");
|
|
}
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle_Handle_Generic_Method_On_Generic_Class ()
|
|
{
|
|
MethodInfo mi = typeof (Generic<>).GetMethod ("GenericFoo");
|
|
RuntimeMethodHandle handle = mi.MethodHandle;
|
|
MethodBase res;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (handle);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException) {
|
|
}
|
|
|
|
mi = typeof (Generic<int>).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
|
|
handle = mi.MethodHandle;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (handle);
|
|
Assert.Fail ("#2");
|
|
} catch (ArgumentException) {
|
|
}
|
|
|
|
|
|
mi = typeof (Generic<>).GetMethod ("GenericFoo").MakeGenericMethod (typeof (int));
|
|
handle = mi.MethodHandle;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle (handle);
|
|
Assert.Fail ("#3");
|
|
} catch (ArgumentException) {
|
|
}
|
|
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<int>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<int>), res.DeclaringType, "#4");
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<double>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<double>), res.DeclaringType, "#5");
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<>), res.DeclaringType, "#6");
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle(handle, typeof (AnotherGeneric<double>).TypeHandle);
|
|
Assert.Fail ("#7");
|
|
} catch (ArgumentException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetMethodFromHandle_Handle_Method_On_Generic_Class ()
|
|
{
|
|
MethodInfo mi = typeof (Generic<>).GetMethod ("Foo");
|
|
RuntimeMethodHandle handle = mi.MethodHandle;
|
|
MethodBase res;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle(handle);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException) {
|
|
}
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
|
|
Assert.AreEqual (res, mi, "#2");
|
|
|
|
mi = typeof (Generic<int>).GetMethod ("Foo");
|
|
handle = mi.MethodHandle;
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle(handle);
|
|
Assert.Fail ("#3");
|
|
} catch (ArgumentException) {
|
|
}
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<int>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<int>), res.DeclaringType, "#4");
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<double>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<double>), res.DeclaringType, "#5");
|
|
|
|
res = MethodBase.GetMethodFromHandle(handle, typeof (Generic<>).TypeHandle);
|
|
Assert.AreEqual (typeof (Generic<>), res.DeclaringType, "#6");
|
|
|
|
try {
|
|
MethodBase.GetMethodFromHandle(handle, typeof (AnotherGeneric<double>).TypeHandle);
|
|
Assert.Fail ("#7");
|
|
} catch (ArgumentException) {
|
|
}
|
|
}
|
|
|
|
// test case adapted from http://www.chrishowie.com/2010/11/24/mutable-strings-in-mono/
|
|
public class FakeString {
|
|
public int length;
|
|
public char start_char;
|
|
}
|
|
|
|
private static FakeString UnsafeConversion<T> (T thing) where T : FakeString
|
|
{
|
|
return thing;
|
|
}
|
|
|
|
[Test]
|
|
#if MOBILE
|
|
[Category ("NotWorking")] // #10552
|
|
#endif
|
|
public void MutableString ()
|
|
{
|
|
var m = typeof (MethodBaseTest).GetMethod ("UnsafeConversion", BindingFlags.NonPublic | BindingFlags.Static);
|
|
try {
|
|
var m2 = m.MakeGenericMethod (typeof (string));
|
|
Assert.Fail ("MakeGenericMethod");
|
|
}
|
|
catch (ArgumentException) {
|
|
}
|
|
}
|
|
}
|
|
}
|