2 // MethodOnTypeBuilderInstTest - NUnit Test Cases for MethodOnTypeBuilderInst
5 // Gert Driesen (drieseng@users.sourceforge.net)
7 // Copyright (C) 2008 Gert Driesen
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
34 using System.Reflection;
35 using System.Reflection.Emit;
37 using NUnit.Framework;
39 namespace MonoTests.System.Reflection.Emit
42 public class MethodOnTypeBuilderInstTest
44 private static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.MethodOnTypeBuilderInstTest";
46 private AssemblyBuilder assembly;
47 private ModuleBuilder module;
48 private MethodBuilder mb_create;
49 private MethodBuilder mb_edit;
50 private Type typeBarOfT;
51 private Type typeBarOfInt32;
52 private MethodInfo method_create;
53 private MethodInfo method_edit;
54 private TypeBuilder typeBuilder;
55 private GenericTypeParameterBuilder[] typeParams;
61 SetUp (AssemblyBuilderAccess.RunAndSave);
64 void SetUp (AssemblyBuilderAccess access)
66 AssemblyName assemblyName = new AssemblyName ();
67 assemblyName.Name = ASSEMBLY_NAME;
69 assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (
73 module = assembly.DefineDynamicModule ("module1");
75 TypeBuilder tb = typeBuilder = module.DefineType ("Bar");
76 typeParams = tb.DefineGenericParameters ("T");
78 ConstructorBuilder cb = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
79 ILGenerator ig = cb.GetILGenerator ();
80 ig.Emit (OpCodes.Ret);
82 typeBarOfT = tb.MakeGenericType (typeParams [0]);
84 mb_create = tb.DefineMethod ("create",
85 MethodAttributes.Public | MethodAttributes.Static,
86 typeBarOfT, Type.EmptyTypes);
87 ig = mb_create.GetILGenerator ();
88 ig.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (
90 ig.Emit (OpCodes.Ret);
92 mb_edit = tb.DefineMethod ("edit",
93 MethodAttributes.Public | MethodAttributes.Static,
94 typeBarOfT, Type.EmptyTypes);
95 ig = mb_edit.GetILGenerator ();
96 ig.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (
98 ig.Emit (OpCodes.Ret);
99 mb_edit.SetParameters (mb_edit.DefineGenericParameters ("X"));
101 typeBarOfInt32 = tb.MakeGenericType (typeof (int));
103 method_create = TypeBuilder.GetMethod (typeBarOfInt32, mb_create);
104 method_edit = TypeBuilder.GetMethod (typeBarOfInt32, mb_edit);
108 public void Attributes ()
110 MethodAttributes attrs;
112 attrs = method_create.Attributes;
113 Assert.AreEqual (MethodAttributes.PrivateScope |
114 MethodAttributes.Public | MethodAttributes.Static,
116 attrs = method_edit.Attributes;
117 Assert.AreEqual (MethodAttributes.PrivateScope |
118 MethodAttributes.Public | MethodAttributes.Static,
123 public void CallingConvention ()
125 CallingConventions conv;
127 conv = method_create.CallingConvention;
128 Assert.AreEqual (CallingConventions.Standard, conv, "#1");
129 conv = method_edit.CallingConvention;
130 Assert.AreEqual (CallingConventions.Standard, conv, "#2");
134 [Category ("NotWorking")]
135 public void ContainsGenericParameters ()
138 bool genparam = method_create.ContainsGenericParameters;
139 Assert.Fail ("#A1:" + genparam);
140 } catch (NotSupportedException ex) {
141 // Specified method is not supported
142 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
143 Assert.IsNull (ex.InnerException, "#A3");
144 Assert.IsNotNull (ex.Message, "#A4");
148 bool genparam = method_edit.ContainsGenericParameters;
149 Assert.Fail ("#B1:" + genparam);
150 } catch (NotSupportedException ex) {
151 // Specified method is not supported
152 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
153 Assert.IsNull (ex.InnerException, "#B3");
154 Assert.IsNotNull (ex.Message, "#B4");
159 public void DeclaringType ()
161 Assert.AreSame (typeBarOfInt32, method_create.DeclaringType, "#1");
162 Assert.AreSame (typeBarOfInt32, method_edit.DeclaringType, "#2");
166 [Category ("NotWorking")]
167 public void GetBaseDefinition ()
170 method_create.GetBaseDefinition ();
172 } catch (NotSupportedException ex) {
173 // Specified method is not supported
174 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
175 Assert.IsNull (ex.InnerException, "#A3");
176 Assert.IsNotNull (ex.Message, "#A4");
180 method_edit.GetBaseDefinition ();
182 } catch (NotSupportedException ex) {
183 // Specified method is not supported
184 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
185 Assert.IsNull (ex.InnerException, "#B3");
186 Assert.IsNotNull (ex.Message, "#B4");
190 [Test] // GetCustomAttributes (Boolean)
191 [Category ("NotWorking")]
192 public void GetCustomAttributes1 ()
195 method_create.GetCustomAttributes (false);
197 } catch (NotSupportedException ex) {
198 // The invoked member is not supported in a dynamic module
199 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
200 Assert.IsNull (ex.InnerException, "#A3");
201 Assert.IsNotNull (ex.Message, "#A4");
205 method_edit.GetCustomAttributes (false);
207 } catch (NotSupportedException ex) {
208 // The invoked member is not supported in a dynamic module
209 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
210 Assert.IsNull (ex.InnerException, "#B3");
211 Assert.IsNotNull (ex.Message, "#B4");
215 [Test] // GetCustomAttributes (Type, Boolean)
216 [Category ("NotWorking")]
217 public void GetCustomAttributes2 ()
220 method_create.GetCustomAttributes (typeof (FlagsAttribute), false);
222 } catch (NotSupportedException ex) {
223 // The invoked member is not supported in a dynamic module
224 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
225 Assert.IsNull (ex.InnerException, "#A3");
226 Assert.IsNotNull (ex.Message, "#A4");
230 method_edit.GetCustomAttributes (typeof (FlagsAttribute), false);
232 } catch (NotSupportedException ex) {
233 // The invoked member is not supported in a dynamic module
234 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
235 Assert.IsNull (ex.InnerException, "#B3");
236 Assert.IsNotNull (ex.Message, "#B4");
241 [Category ("NotWorking")]
242 public void GetGenericArguments ()
246 args = method_create.GetGenericArguments ();
247 Assert.IsNull (args, "#A");
249 args = method_edit.GetGenericArguments ();
250 Assert.IsNotNull (args, "#B1");
251 Assert.AreEqual (1, args.Length, "#B2");
252 Assert.AreEqual ("X", args [0].Name, "#B3");
256 [Category ("NotWorking")]
257 public void GetGenericMethodDefinition ()
259 MethodInfo method_def;
261 method_def = method_create.GetGenericMethodDefinition ();
262 Assert.IsNotNull (method_def, "#A1");
263 Assert.AreSame (mb_create, method_def, "#A2");
265 method_def = method_edit.GetGenericMethodDefinition ();
266 Assert.IsNotNull (method_def, "#B1");
267 Assert.AreSame (mb_edit, method_def, "#B2");
271 public void GetMethodImplementationFlags ()
273 MethodImplAttributes flags;
275 flags = method_create.GetMethodImplementationFlags ();
276 Assert.AreEqual (MethodImplAttributes.Managed, flags, "#1");
277 flags = method_edit.GetMethodImplementationFlags ();
278 Assert.AreEqual (MethodImplAttributes.Managed, flags, "#2");
282 [Category ("NotWorking")]
283 public void GetParameters ()
286 method_create.GetParameters ();
288 } catch (NotSupportedException ex) {
289 // Type has not been created
290 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
291 Assert.IsNull (ex.InnerException, "#A3");
292 Assert.IsNotNull (ex.Message, "#A4");
296 method_edit.GetParameters ();
298 } catch (NotSupportedException ex) {
299 // Type has not been created
300 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
301 Assert.IsNull (ex.InnerException, "#B3");
302 Assert.IsNotNull (ex.Message, "#B4");
307 [Category ("NotWorking")]
308 public void Invoke ()
311 method_create.Invoke (null, BindingFlags.Default, null,
312 new object [0], CultureInfo.InvariantCulture);
314 } catch (NotSupportedException ex) {
315 // Specified method is not supported
316 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
317 Assert.IsNull (ex.InnerException, "#A3");
318 Assert.IsNotNull (ex.Message, "#A4");
322 method_edit.Invoke (null, BindingFlags.Default, null,
323 new object [0], CultureInfo.InvariantCulture);
325 } catch (NotSupportedException ex) {
326 // Specified method is not supported
327 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
328 Assert.IsNull (ex.InnerException, "#B3");
329 Assert.IsNotNull (ex.Message, "#B4");
334 [Category ("NotWorking")]
335 public void IsDefined ()
338 method_create.IsDefined (typeof (FlagsAttribute), false);
340 } catch (NotSupportedException ex) {
341 // The invoked member is not supported in a dynamic module
342 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
343 Assert.IsNull (ex.InnerException, "#A3");
344 Assert.IsNotNull (ex.Message, "#A4");
348 method_edit.IsDefined (typeof (FlagsAttribute), false);
350 } catch (NotSupportedException ex) {
351 // The invoked member is not supported in a dynamic module
352 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
353 Assert.IsNull (ex.InnerException, "#B3");
354 Assert.IsNotNull (ex.Message, "#B4");
359 public void IsGenericMethodDefinition ()
361 Assert.IsFalse (method_create.IsGenericMethodDefinition, "#1");
362 Assert.IsTrue (method_edit.IsGenericMethodDefinition, "#2");
366 public void IsGenericMethod ()
368 Assert.IsFalse (method_create.IsGenericMethod, "#1");
369 Assert.IsTrue (method_edit.IsGenericMethod, "#2");
373 [Category ("NotWorking")]
374 public void MakeGenericMethod ()
377 method_create.MakeGenericMethod (typeof (int));
379 } catch (InvalidOperationException ex) {
380 // create is not a GenericMethodDefinition.
381 // MakeGenericMethod may only be called on a
382 // method for which MethodBase.IsGenericMethodDefinition
384 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
385 Assert.IsNull (ex.InnerException, "#A3");
386 Assert.IsNotNull (ex.Message, "#A4");
389 MethodInfo genEdit = method_edit.MakeGenericMethod (typeof (int));
390 Assert.IsFalse (genEdit.ContainsGenericParameters, "#B1");
391 Assert.IsTrue (genEdit.IsGenericMethod, "#B2");
392 Assert.IsFalse (genEdit.IsGenericMethodDefinition, "#B3");
396 public void MemberType ()
398 Assert.AreEqual (MemberTypes.Method, method_create.MemberType, "#1");
399 Assert.AreEqual (MemberTypes.Method, method_edit.MemberType, "#2");
403 [Category ("NotWorking")]
404 public void MethodHandle ()
407 RuntimeMethodHandle handle = method_create.MethodHandle;
408 Assert.Fail ("#A1:" + handle);
409 } catch (NotSupportedException ex) {
410 // The invoked member is not supported in a dynamic module
411 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
412 Assert.IsNull (ex.InnerException, "#A3");
413 Assert.IsNotNull (ex.Message, "#A4");
417 RuntimeMethodHandle handle = method_edit.MethodHandle;
418 Assert.Fail ("#B1:" + handle);
419 } catch (NotSupportedException ex) {
420 // The invoked member is not supported in a dynamic module
421 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
422 Assert.IsNull (ex.InnerException, "#B3");
423 Assert.IsNotNull (ex.Message, "#B4");
428 public void Module ()
430 Assert.AreSame (module, method_create.Module, "#1");
431 Assert.AreSame (module, method_edit.Module, "#2");
437 Assert.AreEqual ("create", method_create.Name, "#1");
438 Assert.AreEqual ("edit", method_edit.Name, "#2");
442 public void ReflectedType ()
444 Assert.AreSame (typeBarOfInt32, method_create.ReflectedType, "#1");
445 Assert.AreSame (typeBarOfInt32, method_edit.ReflectedType, "#2");
449 public void ReturnParameter ()
452 ParameterInfo ret = method_create.ReturnParameter;
453 Assert.Fail ("#A1:" + (ret != null));
454 } catch (NotSupportedException ex) {
455 // Specified method is not supported
456 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
457 Assert.IsNull (ex.InnerException, "#A3");
458 Assert.IsNotNull (ex.Message, "#A4");
462 ParameterInfo ret = method_create.ReturnParameter;
463 Assert.Fail ("#B1:" + (ret != null));
464 } catch (NotSupportedException ex) {
465 // Specified method is not supported
466 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
467 Assert.IsNull (ex.InnerException, "#B3");
468 Assert.IsNotNull (ex.Message, "#B4");
473 [Category ("NotWorking")]
474 public void ReturnType ()
478 ret = method_create.ReturnType;
479 Assert.AreSame (typeBarOfT, ret, "#1");
480 ret = method_edit.ReturnType;
481 Assert.AreSame (typeBarOfT, ret, "#2");
485 [Category ("NotWorking")]
486 public void ReturnTypeCustomAttributes ()
489 ICustomAttributeProvider attr_prov = method_create.ReturnTypeCustomAttributes;
490 Assert.Fail ("#A1:" + (attr_prov != null));
491 } catch (NotSupportedException ex) {
492 // Specified method is not supported
493 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
494 Assert.IsNull (ex.InnerException, "#A3");
495 Assert.IsNotNull (ex.Message, "#A4");
499 ICustomAttributeProvider attr_prov = method_edit.ReturnTypeCustomAttributes;
500 Assert.Fail ("#B1:" + (attr_prov != null));
501 } catch (NotSupportedException ex) {
502 // Specified method is not supported
503 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
504 Assert.IsNull (ex.InnerException, "#B3");
505 Assert.IsNotNull (ex.Message, "#B4");
509 public class GenericType<T> {
513 [Category ("NotDotNet")]
514 [Category ("NotWorking")]
515 public void MetadataTokenWorksUnderCompilerContext ()
517 SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
518 int mb_token = mb_create.MetadataToken;
519 int inst_token = method_create.MetadataToken;
520 Assert.AreEqual (mb_token, inst_token, "#1");
524 [Category ("NotDotNet")]
525 [Category ("NotWorking")]
526 public void ReturnTypeWorksUnderCompilerContext ()
528 SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
530 Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
531 TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
533 MethodBuilder method_0 = typeBuilder.DefineMethod ("_0", MethodAttributes.Public, typeParams [0], Type.EmptyTypes);
534 MethodBuilder method_1 = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (GenericType<>).MakeGenericType (typeParams [0]), Type.EmptyTypes);
536 Type newGinst = typeBuilder.MakeGenericType (typeof (float));
538 MethodInfo old_method_0 = TypeBuilder.GetMethod (oldGinst, method_0);
539 MethodInfo new_method_0 = TypeBuilder.GetMethod (newGinst, method_0);
541 MethodInfo old_method_1 = TypeBuilder.GetMethod (oldGinst, method_1);
542 MethodInfo new_method_1 = TypeBuilder.GetMethod (newGinst, method_1);
544 Assert.AreEqual (typeof (double), old_method_0.ReturnType, "O#1");
545 Assert.AreEqual (typeof (float), new_method_0.ReturnType, "N#1");
547 Assert.AreEqual (typeof (GenericType <double>), old_method_1.ReturnType, "O#1");
548 Assert.AreEqual (typeof (GenericType <float>), new_method_1.ReturnType, "N#1");
553 [Category ("NotDotNet")]
554 [Category ("NotWorking")]
555 public void GetParametersWorksUnderCompilerContext ()
557 SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
559 Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
560 TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
562 MethodBuilder target_method = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (void),
566 typeParams [0].MakeArrayType (),
567 typeParams [0].MakePointerType (),
568 typeParams [0].MakeByRefType (),
569 typeof (GenericType<>).MakeGenericType (typeParams [0]),
570 typeof (GenericType<>).MakeGenericType (typeof (GenericType<>).MakeGenericType (typeParams [0]))});
573 Type newGinst = typeBuilder.MakeGenericType (typeof (float));
575 MethodInfo old_method = TypeBuilder.GetMethod (oldGinst, target_method);
576 MethodInfo new_method = TypeBuilder.GetMethod (newGinst, target_method);
577 ParameterInfo[] old_params = old_method.GetParameters ();
578 ParameterInfo[] new_params = new_method.GetParameters ();
580 Assert.AreEqual (typeof (int), old_params [0].ParameterType, "O#1");
581 Assert.AreEqual (typeof (double), old_params [1].ParameterType, "O#2");
582 Assert.AreEqual (typeof (double).MakeArrayType (), old_params [2].ParameterType, "O#3");
584 //Assert.AreEqual (typeof (double).MakePointerType (), old_params [3].ParameterType, "O#4");
585 //FIXME this is the current behavior when inflating pointers
586 Assert.AreEqual (typeParams [0].MakePointerType (), old_params [3].ParameterType, "O#4");
588 Assert.AreEqual (typeof (double).MakeByRefType (), old_params [4].ParameterType, "O#5");
589 Assert.AreEqual (typeof (GenericType <double>), old_params [5].ParameterType, "O#6");
590 Assert.AreEqual (typeof (GenericType <GenericType<double>>), old_params [6].ParameterType, "O#7");
592 Assert.AreEqual (typeof (int), new_params [0].ParameterType, "N#1");
593 Assert.AreEqual (typeof (float), new_params [1].ParameterType, "N#2");
594 Assert.AreEqual (typeof (float).MakeArrayType (), new_params [2].ParameterType, "N#3");
596 //Assert.AreEqual (typeof (float).MakePointerType (), new_params [3].ParameterType, "N#4");
597 //FIXME this is the current behavior when inflating pointers
598 Assert.AreEqual (typeParams [0].MakePointerType (), old_params [3].ParameterType, "N#4");
600 Assert.AreEqual (typeof (float).MakeByRefType (), new_params [4].ParameterType, "N#5");
601 Assert.AreEqual (typeof (GenericType <float>), new_params [5].ParameterType, "N#6");
602 Assert.AreEqual (typeof (GenericType <GenericType<float>>), new_params [6].ParameterType, "N#7");