PageRenderTime 778ms CodeModel.GetById 101ms app.highlight 528ms RepoModel.GetById 109ms app.codeStats 1ms

/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs

https://bitbucket.org/danipen/mono
C# | 802 lines | 640 code | 109 blank | 53 comment | 10 complexity | bf343d9df26fa70d6808d7d72da98a4d MD5 | raw file
  1//
  2// System.Reflection.MethodInfo Test Cases
  3//
  4// Authors:
  5//  Zoltan Varga (vargaz@gmail.com)
  6//
  7// (c) 2003 Ximian, Inc. (http://www.ximian.com)
  8// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  9//
 10// Permission is hereby granted, free of charge, to any person obtaining
 11// a copy of this software and associated documentation files (the
 12// "Software"), to deal in the Software without restriction, including
 13// without limitation the rights to use, copy, modify, merge, publish,
 14// distribute, sublicense, and/or sell copies of the Software, and to
 15// permit persons to whom the Software is furnished to do so, subject to
 16// the following conditions:
 17// 
 18// The above copyright notice and this permission notice shall be
 19// included in all copies or substantial portions of the Software.
 20// 
 21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 22// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 23// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 24// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 25// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 26// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 27// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 28//
 29
 30using NUnit.Framework;
 31using System;
 32using System.Threading;
 33using System.Reflection;
 34#if !MONOTOUCH
 35using System.Reflection.Emit;
 36#endif
 37using System.Runtime.InteropServices;
 38using System.Runtime.CompilerServices;
 39
 40#if NET_2_0
 41using System.Collections.Generic;
 42#endif
 43
 44namespace A.B.C {
 45	public struct MethodInfoTestStruct {
 46		int p;
 47	}
 48}
 49namespace MonoTests.System.Reflection
 50{
 51	[TestFixture]
 52	public class MethodInfoTest
 53	{
 54#if !TARGET_JVM
 55		[DllImport ("libfoo", EntryPoint="foo", CharSet=CharSet.Unicode, ExactSpelling=false, PreserveSig=true, SetLastError=true, BestFitMapping=true, ThrowOnUnmappableChar=true)]
 56		public static extern void dllImportMethod ();
 57#endif
 58		[MethodImplAttribute(MethodImplOptions.PreserveSig)]
 59		public void preserveSigMethod ()
 60		{
 61		}
 62
 63		[MethodImplAttribute(MethodImplOptions.Synchronized)]
 64		public void synchronizedMethod ()
 65		{
 66		}
 67
 68		[Test]
 69		public void IsDefined_AttributeType_Null ()
 70		{
 71			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("foo");
 72
 73			try {
 74				mi.IsDefined ((Type) null, false);
 75				Assert.Fail ("#1");
 76			} catch (ArgumentNullException ex) {
 77				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
 78				Assert.IsNull (ex.InnerException, "#3");
 79				Assert.IsNotNull (ex.Message, "#4");
 80				Assert.IsNotNull (ex.ParamName, "#5");
 81				Assert.AreEqual ("attributeType", ex.ParamName, "#6");
 82			}
 83		}
 84
 85		[Test]
 86		public void TestInvokeByRefReturnMethod ()
 87		{
 88			try {
 89				MethodInfo m = typeof (int[]).GetMethod ("Address");
 90				m.Invoke (new int[1], new object[] { 0 });
 91				Assert.Fail ("#1");
 92			} catch (NotSupportedException e) {
 93				Assert.AreEqual (typeof (NotSupportedException), e.GetType (), "#2");
 94				Assert.IsNull (e.InnerException, "#3");
 95				Assert.IsNotNull (e.Message, "#4");
 96			}
 97		}
 98
 99#if NET_2_0
100		[Test]
101		public void PseudoCustomAttributes ()
102		{
103			Type t = typeof (MethodInfoTest);
104
105			DllImportAttribute attr = (DllImportAttribute)((t.GetMethod ("dllImportMethod").GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
106
107			Assert.AreEqual (CallingConvention.Winapi, attr.CallingConvention, "#1");
108			Assert.AreEqual ("foo", attr.EntryPoint, "#2");
109			Assert.AreEqual ("libfoo", attr.Value, "#3");
110			Assert.AreEqual (CharSet.Unicode, attr.CharSet, "#4");
111			Assert.AreEqual (false, attr.ExactSpelling, "#5");
112			Assert.AreEqual (true, attr.PreserveSig, "#6");
113			Assert.AreEqual (true, attr.SetLastError, "#7");
114			Assert.AreEqual (true, attr.BestFitMapping, "#8");
115			Assert.AreEqual (true, attr.ThrowOnUnmappableChar, "#9");
116
117			PreserveSigAttribute attr2 = (PreserveSigAttribute)((t.GetMethod ("preserveSigMethod").GetCustomAttributes (true)) [0]);
118
119			// This doesn't work under MS.NET
120			/*
121			  MethodImplAttribute attr3 = (MethodImplAttribute)((t.GetMethod ("synchronizedMethod").GetCustomAttributes (true)) [0]);
122			*/
123		}
124
125		[return: MarshalAs (UnmanagedType.Interface)]
126		public void ReturnTypeMarshalAs ()
127		{
128		}
129
130		[Test]
131		[Category ("TargetJvmNotWorking")]
132		public void ReturnTypePseudoCustomAttributes ()
133		{
134			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("ReturnTypeMarshalAs");
135
136			Assert.IsTrue (mi.ReturnTypeCustomAttributes.GetCustomAttributes (typeof (MarshalAsAttribute), true).Length == 1);
137		}
138#endif
139
140		public static int foo (int i, int j)
141		{
142			return i + j;
143		}
144
145		[Test]
146		public void StaticInvokeWithObject ()
147		{
148			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("foo");
149			
150			mi.Invoke (new Object (), new object [] { 1, 2 });
151		}
152
153		[Test]
154		public void ByRefInvoke ()
155		{
156			MethodInfo met = typeof(MethodInfoTest).GetMethod ("ByRefTest");
157			object[] parms = new object[] {1};
158			met.Invoke (null, parms);
159			Assert.AreEqual (2, parms[0]);
160		}
161
162		public static void ByRefTest (ref int a1)
163		{
164			if (a1 == 1)
165				a1 = 2;
166		}
167
168		static int byref_arg;
169
170		public static void ByrefVtype (ref int i) {
171			byref_arg = i;
172			i = 5;
173		}
174
175		[Test]
176#if ONLY_1_1
177		[Category ("NotDotNet")] // #A2 fails on MS.NET 1.x
178#endif
179		public void ByrefVtypeInvoke ()
180		{
181			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("ByrefVtype");
182
183			object o = 1;
184			object[] args = new object [] { o };
185			mi.Invoke (null, args);
186			Assert.AreEqual (1, byref_arg, "#A1");
187			Assert.AreEqual (1, o, "#A2");
188			Assert.AreEqual (5, args[0], "#A3");
189
190			args [0] = null;
191			mi.Invoke (null, args);
192			Assert.AreEqual (0, byref_arg, "#B1");
193			Assert.AreEqual (5, args[0], "#B2");
194		}
195
196		public void HeyHey (out string out1, ref string ref1)
197		{
198			out1 = null;
199		}
200
201		public void SignatureTest (__arglist)
202		{
203		}
204		
205		public static unsafe int* PtrFunc (int* a)
206		{
207			return (int*) 0;
208		}
209
210		[Test] // bug #81538
211		public void InvokeThreadAbort ()
212		{
213			MethodInfo method = typeof (MethodInfoTest).GetMethod ("AbortIt");
214			try {
215				method.Invoke (null, new object [0]);
216				Assert.Fail ("#1");
217			}
218#if NET_2_0
219			catch (ThreadAbortException ex) {
220				Thread.ResetAbort ();
221				Assert.IsNull (ex.InnerException, "#2");
222			}
223#else
224			catch (TargetInvocationException ex) {
225				Thread.ResetAbort ();
226				Assert.IsNotNull (ex.InnerException, "#2");
227				Assert.AreEqual (typeof (ThreadAbortException), ex.InnerException.GetType (), "#3");
228			}
229#endif
230		}
231
232		public static void AbortIt ()
233		{
234			Thread.CurrentThread.Abort ();
235		}
236
237		[Test] // bug #76541
238		public void ToStringByRef ()
239		{
240			Assert.AreEqual ("Void HeyHey(System.String ByRef, System.String ByRef)",
241				this.GetType ().GetMethod ("HeyHey").ToString ());
242		}
243		
244		[Test]
245		public void ToStringArgList ()
246		{
247			Assert.AreEqual ("Void SignatureTest(...)",
248				this.GetType ().GetMethod ("SignatureTest").ToString ());
249		}
250
251		[Test]
252		public void ToStringWithPointerSignatures () //bug #409583
253		{
254			Assert.AreEqual ("Int32* PtrFunc(Int32*)", this.GetType ().GetMethod ("PtrFunc").ToString ());
255		}
256
257
258#if NET_2_0
259		public struct SimpleStruct
260		{
261			int a;
262		}
263
264		public static unsafe SimpleStruct* PtrFunc2 (SimpleStruct* a, A.B.C.MethodInfoTestStruct *b)
265		{
266			return (SimpleStruct*) 0;
267		}
268
269		[Test]
270		public void ToStringWithPointerSignaturesToNonPrimitiveType ()
271		{
272			Assert.AreEqual ("SimpleStruct* PtrFunc2(SimpleStruct*, A.B.C.MethodInfoTestStruct*)", 
273				this.GetType ().GetMethod ("PtrFunc2").ToString ());
274		}	
275		[Test]
276		public void ToStringGenericMethod ()
277		{
278			Assert.AreEqual ("System.Collections.ObjectModel.ReadOnlyCollection`1[T] AsReadOnly[T](T[])",
279				typeof (Array).GetMethod ("AsReadOnly").ToString ());
280		}
281#endif
282
283		class GBD_A         { public virtual     void f () {} }
284		class GBD_B : GBD_A { public override    void f () {} }
285		class GBD_C : GBD_B { public override    void f () {} }
286		class GBD_D : GBD_C { public new virtual void f () {} }
287		class GBD_E : GBD_D { public override    void f () {} }
288
289		[Test]
290		public void GetBaseDefinition ()
291		{
292			Assert.AreEqual (typeof (GBD_A), typeof (GBD_C).GetMethod ("f").GetBaseDefinition ().DeclaringType);
293			Assert.AreEqual (typeof (GBD_D), typeof (GBD_D).GetMethod ("f").GetBaseDefinition ().DeclaringType);
294			Assert.AreEqual (typeof (GBD_D), typeof (GBD_E).GetMethod ("f").GetBaseDefinition ().DeclaringType);
295		}
296
297		class TestInheritedMethodA {
298			private void TestMethod ()
299			{
300			}
301
302			public void TestMethod2 ()
303			{
304			}
305		}
306
307		class TestInheritedMethodB : TestInheritedMethodA {
308		}
309
310		[Test]
311		public void InheritanceTestGetMethodTest ()
312		{
313			MethodInfo inheritedMethod = typeof(TestInheritedMethodB).GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
314			MethodInfo baseMethod = typeof(TestInheritedMethodB).GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
315			Assert.AreSame (inheritedMethod, baseMethod);
316
317			MethodInfo inheritedMethod2 = typeof(TestInheritedMethodB).GetMethod("TestMethod2", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
318			MethodInfo baseMethod2 = typeof(TestInheritedMethodB).GetMethod("TestMethod2", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
319			Assert.AreSame (inheritedMethod, baseMethod);
320		}
321
322#if NET_2_0
323#if !TARGET_JVM // MethodBody is not supported for TARGET_JVM
324		[Test]
325		public void GetMethodBody_Abstract ()
326		{
327			MethodBody mb = typeof (ICloneable).GetMethod ("Clone").GetMethodBody ();
328			Assert.IsNull (mb);
329		}
330
331		[Test]
332		public void GetMethodBody_Runtime ()
333		{
334			MethodBody mb = typeof (AsyncCallback).GetMethod ("Invoke").GetMethodBody ();
335			Assert.IsNull (mb);
336		}
337
338		[Test]
339		public void GetMethodBody_Pinvoke ()
340		{
341			MethodBody mb = typeof (MethodInfoTest).GetMethod ("dllImportMethod").GetMethodBody ();
342			Assert.IsNull (mb);
343		}
344
345		[Test]
346		public void GetMethodBody_Icall ()
347		{
348			foreach (MethodInfo mi in typeof (object).GetMethods (BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance))
349				if ((mi.GetMethodImplementationFlags () & MethodImplAttributes.InternalCall) != 0) {
350					MethodBody mb = mi.GetMethodBody ();
351					Assert.IsNull (mb);
352				}
353		}
354
355		public static void locals_method ()
356		{
357			byte[] b = new byte [10];
358
359			unsafe {
360				/* This generates a pinned local */
361				fixed (byte *p = &b [0]) {
362				}
363			}
364		}
365
366		[Test]
367		public void GetMethodBody ()
368		{
369			MethodBody mb = typeof (MethodInfoTest).GetMethod ("locals_method").GetMethodBody ();
370
371			Assert.IsTrue (mb.InitLocals, "#1");
372			Assert.IsTrue (mb.LocalSignatureMetadataToken > 0, "#2");
373
374			IList<LocalVariableInfo> locals = mb.LocalVariables;
375
376			// This might break with different compilers etc.
377			Assert.AreEqual (2, locals.Count, "#3");
378
379			Assert.IsTrue ((locals [0].LocalType == typeof (byte[])) || (locals [1].LocalType == typeof (byte[])), "#4");
380			if (locals [0].LocalType == typeof (byte[]))
381				Assert.AreEqual (false, locals [0].IsPinned, "#5");
382			else
383				Assert.AreEqual (false, locals [1].IsPinned, "#6");
384		}
385#endif // TARGET_JVM
386
387		public int return_parameter_test ()
388		{
389			return 0;
390		}
391
392		[Test]
393		public void GetMethodFromHandle_Generic ()
394		{
395			MethodHandleTest<int> test = new MethodHandleTest<int> ();
396			RuntimeMethodHandle mh = test.GetType ().GetProperty ("MyList")
397				.GetGetMethod ().MethodHandle;
398			MethodBase mb = MethodInfo.GetMethodFromHandle (mh,
399				typeof (MethodHandleTest<int>).TypeHandle);
400			Assert.IsNotNull (mb, "#1");
401			List<int> list = (List<int>) mb.Invoke (test, null);
402			Assert.IsNotNull (list, "#2");
403			Assert.AreEqual (1, list.Count, "#3");
404		}
405
406		[Test]
407		public void ReturnParameter ()
408		{
409			ParameterInfo pi = typeof (MethodInfoTest).GetMethod ("return_parameter_test").ReturnParameter;
410			Assert.AreEqual (typeof (int), pi.ParameterType, "#1");
411			Assert.AreEqual (-1, pi.Position, "#2");
412			// MS always return false here
413			//Assert.IsTrue (pi.IsRetval, "#3");
414		}
415
416#if !TARGET_JVM // ReflectionOnly is not supported yet on TARGET_JVM
417		[Test]
418			public void InvokeOnRefOnlyAssembly ()
419		{
420			Assembly a = Assembly.ReflectionOnlyLoad (typeof (MethodInfoTest).Assembly.FullName);
421			Type t = a.GetType (typeof (RefOnlyMethodClass).FullName);
422			MethodInfo m = t.GetMethod ("RefOnlyMethod", BindingFlags.Static | BindingFlags.NonPublic);
423			try {
424				m.Invoke (null, new object [0]);
425				Assert.Fail ("#1");
426			} catch (InvalidOperationException ex) {
427				// The requested operation is invalid in the
428				// ReflectionOnly context
429				Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
430				Assert.IsNull (ex.InnerException, "#3");
431				Assert.IsNotNull (ex.Message, "#4");
432			}
433		}
434#endif // TARGET_JVM
435
436		[Test]
437		[ExpectedException (typeof (TargetInvocationException))]
438		public void InvokeInvalidOpExceptionThrow () {
439			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("ThrowMethod");
440			mi.Invoke(null, null);
441		}
442
443		public static void ThrowMethod () {
444			throw new InvalidOperationException ();
445		}
446
447		[Test]
448		public void InvokeGenericVtype ()
449		{
450			KeyValuePair<string, uint> kvp = new KeyValuePair<string, uint> ("a", 21);
451			Type type = kvp.GetType ();
452			Type [] arguments = type.GetGenericArguments ();
453			MethodInfo method = typeof (MethodInfoTest).GetMethod ("Go");
454			MethodInfo generic_method = method.MakeGenericMethod (arguments);
455			kvp = (KeyValuePair<string, uint>)generic_method.Invoke (null, new object [] { kvp });
456
457			Assert.AreEqual ("a", kvp.Key, "#1");
458			Assert.AreEqual (21, kvp.Value, "#2");
459		}
460
461		public static KeyValuePair<T1, T2> Go <T1, T2> (KeyValuePair <T1, T2> kvp)
462		{
463			return kvp;
464		}
465
466		[Test] // bug #81997
467		public void InvokeGenericInst ()
468		{
469			List<string> str = null;
470
471			object [] methodArgs = new object [] { str };
472			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("GenericRefMethod");
473			mi.Invoke (null, methodArgs);
474			Assert.IsNotNull (methodArgs [0], "#A1");
475			Assert.IsNull (str, "#A2");
476			Assert.IsTrue (methodArgs [0] is List<string>, "#A3");
477
478			List<string> refStr = methodArgs [0] as List<string>;
479			Assert.IsNotNull (refStr, "#B1");
480			Assert.AreEqual (1, refStr.Count, "#B2");
481			Assert.AreEqual ("test", refStr [0], "#B3");
482		}
483
484		public static void GenericRefMethod (ref List<string> strArg)
485		{
486			strArg = new List<string> ();
487			strArg.Add ("test");
488		}
489
490		public void MakeGenericMethodArgsMismatchFoo<T> ()
491		{
492		}
493
494		[Test]
495		public void MakeGenericMethodArgsMismatch ()
496		{
497			MethodInfo gmi = this.GetType ().GetMethod (
498				"MakeGenericMethodArgsMismatchFoo");
499			try {
500				gmi.MakeGenericMethod ();
501				Assert.Fail ("#1");
502			} catch (ArgumentException ex) {
503				// The type or method has 1 generic parameter(s),
504				// but 0 generic argument(s) were provided. A
505				// generic argument must be provided for each
506				// generic parameter
507				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
508				Assert.IsNull (ex.InnerException, "#3");
509				Assert.IsNotNull (ex.Message, "#4");
510				Assert.IsNull (ex.ParamName, "#5");
511			}
512		}
513
514		public void SimpleGenericMethod<TFoo, TBar> () {}
515
516		[Test]
517		public void MakeGenericMethodWithNullArray ()
518		{
519			MethodInfo gmi = this.GetType ().GetMethod ("SimpleGenericMethod");
520			try {
521				gmi.MakeGenericMethod ((Type []) null);
522				Assert.Fail ("#1");
523			} catch (ArgumentNullException ex) {
524				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
525				Assert.IsNull (ex.InnerException, "#3");
526				Assert.IsNotNull (ex.Message, "#4");
527				Assert.AreEqual ("methodInstantiation", ex.ParamName, "#5");
528			}
529		}
530
531		[Test]
532		public void MakeGenericMethodWithNullValueInTypesArray ()
533		{
534			MethodInfo gmi = this.GetType ().GetMethod ("SimpleGenericMethod");
535			try {
536				gmi.MakeGenericMethod (new Type [] { typeof (int), null });
537				Assert.Fail ("#1");
538			} catch (ArgumentNullException ex) {
539				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
540				Assert.IsNull (ex.InnerException, "#3");
541				Assert.IsNotNull (ex.Message, "#4");
542				Assert.IsNull (ex.ParamName, "#5");
543			}
544		}
545
546		[Test]
547		public void MakeGenericMethodWithNonGenericMethodDefinitionMethod ()
548		{
549			MethodInfo gmi = this.GetType ().GetMethod ("SimpleGenericMethod");
550			MethodInfo inst = gmi.MakeGenericMethod (typeof (int), typeof (double));
551			try {
552				inst.MakeGenericMethod (typeof (int), typeof (double));
553				Assert.Fail ("#1");
554			} catch (InvalidOperationException ex) {
555			}
556		}
557#if !MONOTOUCH
558		public TFoo SimpleGenericMethod2<TFoo, TBar> () { return default (TFoo); }
559		/*Test for the uggly broken behavior of SRE.*/
560		[Test]
561		public void MakeGenericMethodWithSreTypeResultsInStupidMethodInfo ()
562		{
563			AssemblyName assemblyName = new AssemblyName ();
564			assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodInfoTest";
565			AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.RunAndSave, ".");
566			ModuleBuilder module = assembly.DefineDynamicModule ("module1", "tst.dll");
567			TypeBuilder tb = module.DefineType ("Test", TypeAttributes.Public);
568
569			MethodInfo gmi = this.GetType ().GetMethod ("SimpleGenericMethod2");
570			MethodInfo ins = gmi.MakeGenericMethod (typeof (int), tb);
571
572			Assert.AreSame (tb, ins.GetGenericArguments () [1], "#1");
573			/*broken ReturnType*/
574			Assert.AreSame (gmi.GetGenericArguments () [0], ins.ReturnType, "#2");
575		}
576#endif
577		public static int? pass_nullable (int? i)
578		{
579			return i;
580		}
581
582		[Test]
583		[Category ("MobileNotWorking")] // bug #10266
584		public void NullableTests ()
585		{
586			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("pass_nullable");
587			Assert.AreEqual (102, mi.Invoke (null, new object [] { 102 }), "#1");
588			Assert.AreEqual (null, mi.Invoke (null, new object [] { null }), "#2");
589
590			// Test conversion of vtype to a nullable type for the this argument
591			PropertyInfo pi = typeof (Nullable <int>).GetProperty ("HasValue");
592			Assert.AreEqual (true, pi.GetGetMethod ().Invoke (10, null));
593			PropertyInfo pi2 = typeof (Nullable <int>).GetProperty ("Value");
594			Assert.AreEqual (10, pi2.GetGetMethod ().Invoke (10, null));
595		}
596
597		public static void foo_generic<T> ()
598		{
599		}
600
601		[Test]
602		public void IsGenericMethod ()
603		{
604			MethodInfo mi = typeof (MethodInfoTest).GetMethod ("foo_generic");
605			Assert.AreEqual (true, mi.IsGenericMethod, "#1");
606			MethodInfo mi2 = mi.MakeGenericMethod (new Type[] { typeof (int) });
607			Assert.AreEqual (true, mi2.IsGenericMethod, "#2");
608			MethodInfo mi3 = typeof (GenericHelper<int>).GetMethod ("Test");
609			Assert.AreEqual (false, mi3.IsGenericMethod, "#3");
610		}
611
612		class A<T>
613		{
614			public static void Foo<T2> (T2 i)
615			{
616			}
617
618			public static void Bar ()
619			{
620			}
621
622			public class B
623			{
624				public static void Baz ()
625				{
626				}
627			}
628		}
629
630		[Test]
631		public void ContainsGenericParameters ()
632		{
633			// Non-generic method in open generic type
634			Assert.IsTrue (typeof (A<int>).GetGenericTypeDefinition ().GetMethod ("Bar").ContainsGenericParameters);
635			// open generic method in closed generic type
636			Assert.IsTrue (typeof (A<int>).GetMethod ("Foo").ContainsGenericParameters);
637			// non-generic method in closed generic type
638			Assert.IsFalse (typeof (A<int>).GetMethod ("Bar").ContainsGenericParameters);
639			// closed generic method in closed generic type
640			Assert.IsFalse (typeof (A<int>).GetMethod ("Foo").MakeGenericMethod (new Type [] { typeof (int) }).ContainsGenericParameters);
641			// non-generic method in non-generic nested type of closed generic type
642			Assert.IsFalse (typeof (A<int>.B).GetMethod ("Baz").ContainsGenericParameters);
643			// non-generic method in non-generic nested type of open generic type
644			Assert.IsTrue (typeof (A<int>.B).GetGenericTypeDefinition ().GetMethod ("Baz").ContainsGenericParameters);
645		}
646
647		[Test]
648		public void IsGenericMethodDefinition ()
649		{
650			MethodInfo m1 = typeof (A<>).GetMethod ("Foo");
651			Assert.IsTrue (m1.IsGenericMethod, "#A1");
652			Assert.IsTrue (m1.IsGenericMethodDefinition, "#A2");
653
654			MethodInfo m2 = typeof (A<int>).GetMethod ("Foo");
655			Assert.IsTrue (m2.IsGenericMethod, "#B1");
656			Assert.IsTrue (m2.IsGenericMethodDefinition, "#B2");
657
658			MethodInfo m3 = m2.MakeGenericMethod (typeof (int));
659			Assert.IsTrue (m3.IsGenericMethod, "#C1");
660			Assert.IsFalse (m3.IsGenericMethodDefinition, "#C2");
661		}
662
663		[Test]
664		public void GetGenericMethodDefinition ()
665		{
666			MethodInfo mi1 = typeof (MyList<>).GetMethod ("ConvertAll");
667			MethodInfo mi2 = typeof (MyList<int>).GetMethod ("ConvertAll");
668
669			Assert.AreEqual ("MonoTests.System.Reflection.MethodInfoTest+Foo`2[T,TOutput]",
670					 mi1.GetParameters () [0].ParameterType.ToString (), "#A1");
671			Assert.AreEqual ("MonoTests.System.Reflection.MethodInfoTest+Foo`2[System.Int32,TOutput]",
672					 mi2.GetParameters () [0].ParameterType.ToString (), "#A2");
673			Assert.IsTrue (mi1.IsGenericMethod, "#A3");
674			Assert.IsTrue (mi1.IsGenericMethodDefinition, "#A4");
675			Assert.IsTrue (mi2.IsGenericMethod, "#A5");
676			Assert.IsTrue (mi2.IsGenericMethodDefinition, "#A6");
677
678			MethodInfo mi3 = mi2.GetGenericMethodDefinition ();
679
680			Assert.IsTrue (mi3.IsGenericMethod, "#B1");
681			Assert.IsTrue (mi3.IsGenericMethodDefinition, "#B2");
682			Assert.AreSame (mi2, mi3, "#B3");
683
684			MethodInfo mi4 = mi2.MakeGenericMethod (typeof (short));
685			Assert.IsTrue (mi4.IsGenericMethod, "#C1");
686			Assert.IsFalse (mi4.IsGenericMethodDefinition, "#C2");
687			Assert.AreSame (mi2, mi4.GetGenericMethodDefinition (), "#C3");
688		}
689
690		public void TestMethod123(int a, int b) {}
691
692		[Test]
693		public void GetParametersDontReturnInternedArray ()
694		{
695			var method = typeof (MethodInfoTest).GetMethod ("TestMethod123");
696			var parms = method.GetParameters ();
697			Assert.AreNotSame (parms, method.GetParameters (), "#1");
698
699			parms [0] = null;
700			Assert.IsNotNull (method.GetParameters () [0], "#2");
701		}
702
703		[Test]
704		public void Bug354757 ()
705		{
706			MethodInfo gmd = (typeof (MyList <int>)).GetMethod ("ConvertAll");
707			MethodInfo oi = gmd.MakeGenericMethod (gmd.GetGenericArguments ());
708			Assert.AreSame (gmd, oi);
709		}
710
711		[Test]
712		[ExpectedException (typeof (ArgumentException))]
713#if MOBILE
714		[Category ("NotWorking")] // #10552
715#endif
716		public void MakeGenericMethodRespectConstraints ()
717		{
718			var m = typeof (MethodInfoTest).GetMethod ("TestMethod");
719			m.MakeGenericMethod (typeof (Type));
720		}
721
722		public void TestMethod <T> () where T : Exception
723		{
724		}
725
726		public class MyList<T>
727		{
728			public TOutput ConvertAll<TOutput> (Foo<T,TOutput> arg)
729			{
730				return default (TOutput);
731			}
732			public T ConvertAll2 (MyList<T> arg)
733			{
734				return default (T);
735			}
736		}
737
738		public class Foo<T,TOutput>
739		{
740		}
741
742		class GenericHelper<T>
743		{
744			public void Test (T t)
745			{
746			}
747		}
748#endif
749#if NET_4_0
750		interface IMethodInvoke<out T>
751		{
752		    T Test ();
753		}
754
755		class MethodInvoke : IMethodInvoke<string>
756		{
757		    public string Test ()
758		    {
759		        return "MethodInvoke";
760		    }
761		}
762
763		[Test]
764		public void GetInterfaceMapWorksWithVariantIfaces ()
765		{
766			var m0 = typeof (IMethodInvoke<object>).GetMethod ("Test");
767			var m1 = typeof (IMethodInvoke<string>).GetMethod ("Test");
768			var obj = new MethodInvoke ();
769
770			Assert.AreEqual ("MethodInvoke", m0.Invoke (obj, new Object [0]));
771			Assert.AreEqual ("MethodInvoke", m1.Invoke (obj, new Object [0]));
772		}
773#endif
774
775	}
776	
777#if NET_2_0
778	// Helper class
779	class RefOnlyMethodClass 
780	{
781		// Helper static method
782		static void RefOnlyMethod ()
783		{
784		}
785	}
786
787	public class MethodHandleTest<T>
788	{
789		private List<T> _myList = new List<T> ();
790
791		public MethodHandleTest ()
792		{
793			_myList.Add (default (T));
794		}
795
796		public List<T> MyList {
797			get { return _myList; }
798			set { _myList = value; }
799		}
800	}
801#endif
802}