MethodInfoTest.cs 29 KB

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