2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / MethodOnTypeBuilderInstTest.cs
1 //
2 // MethodOnTypeBuilderInstTest - NUnit Test Cases for MethodOnTypeBuilderInst
3 //
4 // Author:
5 //   Gert Driesen (drieseng@users.sourceforge.net)
6 //
7 // Copyright (C) 2008 Gert Driesen
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28
29 #if NET_2_0
30
31 using System;
32 using System.Globalization;
33 using System.IO;
34 using System.Reflection;
35 using System.Reflection.Emit;
36
37 using NUnit.Framework;
38
39 namespace MonoTests.System.Reflection.Emit
40 {
41         [TestFixture]
42         public class MethodOnTypeBuilderInstTest
43         {
44                 private static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.MethodOnTypeBuilderInstTest";
45                 
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;
56                 
57
58                 [SetUp]
59                 public void SetUp ()
60                 {
61                         SetUp (AssemblyBuilderAccess.RunAndSave);
62                 }
63                 
64                 void SetUp (AssemblyBuilderAccess access)
65                 {
66                         AssemblyName assemblyName = new AssemblyName ();
67                         assemblyName.Name = ASSEMBLY_NAME;
68
69                         assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (
70                                 assemblyName, access,
71                                 Path.GetTempPath ());
72
73                         module = assembly.DefineDynamicModule ("module1");
74
75                         TypeBuilder tb = typeBuilder = module.DefineType ("Bar");
76                         typeParams = tb.DefineGenericParameters ("T");
77
78                         ConstructorBuilder cb = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
79                         ILGenerator ig = cb.GetILGenerator ();
80                         ig.Emit (OpCodes.Ret);
81
82                         typeBarOfT = tb.MakeGenericType (typeParams [0]);
83
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 (
89                                 typeBarOfT, cb));
90                         ig.Emit (OpCodes.Ret);
91
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 (
97                                 typeBarOfT, cb));
98                         ig.Emit (OpCodes.Ret);
99                         mb_edit.SetParameters (mb_edit.DefineGenericParameters ("X"));
100
101                         typeBarOfInt32 = tb.MakeGenericType (typeof (int));
102
103                         method_create = TypeBuilder.GetMethod (typeBarOfInt32, mb_create);
104                         method_edit = TypeBuilder.GetMethod (typeBarOfInt32, mb_edit);
105                 }
106
107                 [Test]
108                 public void Attributes ()
109                 {
110                         MethodAttributes attrs;
111
112                         attrs = method_create.Attributes;
113                         Assert.AreEqual (MethodAttributes.PrivateScope |
114                                 MethodAttributes.Public | MethodAttributes.Static,
115                                 attrs, "#1");
116                         attrs = method_edit.Attributes;
117                         Assert.AreEqual (MethodAttributes.PrivateScope |
118                                 MethodAttributes.Public | MethodAttributes.Static,
119                                 attrs, "#2");
120                 }
121
122                 [Test]
123                 public void CallingConvention ()
124                 {
125                         CallingConventions conv;
126
127                         conv = method_create.CallingConvention;
128                         Assert.AreEqual (CallingConventions.Standard, conv, "#1");
129                         conv = method_edit.CallingConvention;
130                         Assert.AreEqual (CallingConventions.Standard, conv, "#2");
131                 }
132
133                 [Test]
134                 [Category ("NotWorking")]
135                 public void ContainsGenericParameters ()
136                 {
137                         try {
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");
145                         }
146
147                         try {
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");
155                         }
156                 }
157
158                 [Test]
159                 public void DeclaringType ()
160                 {
161                         Assert.AreSame (typeBarOfInt32, method_create.DeclaringType, "#1");
162                         Assert.AreSame (typeBarOfInt32, method_edit.DeclaringType, "#2");
163                 }
164
165                 [Test]
166                 [Category ("NotWorking")]
167                 public void GetBaseDefinition ()
168                 {
169                         try {
170                                 method_create.GetBaseDefinition ();
171                                 Assert.Fail ("#A1");
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");
177                         }
178
179                         try {
180                                 method_edit.GetBaseDefinition ();
181                                 Assert.Fail ("#B1");
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");
187                         }
188                 }
189
190                 [Test] // GetCustomAttributes (Boolean)
191                 [Category ("NotWorking")]
192                 public void GetCustomAttributes1 ()
193                 {
194                         try {
195                                 method_create.GetCustomAttributes (false);
196                                 Assert.Fail ("#A1");
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");
202                         }
203
204                         try {
205                                 method_edit.GetCustomAttributes (false);
206                                 Assert.Fail ("#B1");
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");
212                         }
213                 }
214
215                 [Test] // GetCustomAttributes (Type, Boolean)
216                 [Category ("NotWorking")]
217                 public void GetCustomAttributes2 ()
218                 {
219                         try {
220                                 method_create.GetCustomAttributes (typeof (FlagsAttribute), false);
221                                 Assert.Fail ("#A1");
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");
227                         }
228
229                         try {
230                                 method_edit.GetCustomAttributes (typeof (FlagsAttribute), false);
231                                 Assert.Fail ("#B1");
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");
237                         }
238                 }
239
240                 [Test]
241                 [Category ("NotWorking")]
242                 public void GetGenericArguments ()
243                 {
244                         Type [] args;
245                         
246                         args = method_create.GetGenericArguments ();
247                         Assert.IsNull (args, "#A");
248
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");
253                 }
254
255                 [Test]
256                 [Category ("NotWorking")]
257                 public void GetGenericMethodDefinition ()
258                 {
259                         MethodInfo method_def;
260
261                         method_def = method_create.GetGenericMethodDefinition ();
262                         Assert.IsNotNull (method_def, "#A1");
263                         Assert.AreSame (mb_create, method_def, "#A2");
264
265                         method_def = method_edit.GetGenericMethodDefinition ();
266                         Assert.IsNotNull (method_def, "#B1");
267                         Assert.AreSame (mb_edit, method_def, "#B2");
268                 }
269
270                 [Test]
271                 public void GetMethodImplementationFlags ()
272                 {
273                         MethodImplAttributes flags;
274                         
275                         flags = method_create.GetMethodImplementationFlags ();
276                         Assert.AreEqual (MethodImplAttributes.Managed, flags, "#1");
277                         flags = method_edit.GetMethodImplementationFlags ();
278                         Assert.AreEqual (MethodImplAttributes.Managed, flags, "#2");
279                 }
280
281                 [Test]
282                 [Category ("NotWorking")]
283                 public void GetParameters ()
284                 {
285                         try {
286                                 method_create.GetParameters ();
287                                 Assert.Fail ("#A1");
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");
293                         }
294
295                         try {
296                                 method_edit.GetParameters ();
297                                 Assert.Fail ("#B1");
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");
303                         }
304                 }
305
306                 [Test]
307                 [Category ("NotWorking")]
308                 public void Invoke ()
309                 {
310                         try {
311                                 method_create.Invoke (null, BindingFlags.Default, null,
312                                         new object [0], CultureInfo.InvariantCulture);
313                                 Assert.Fail ("#A1");
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");
319                         }
320
321                         try {
322                                 method_edit.Invoke (null, BindingFlags.Default, null,
323                                         new object [0], CultureInfo.InvariantCulture);
324                                 Assert.Fail ("#B1");
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");
330                         }
331                 }
332
333                 [Test]
334                 [Category ("NotWorking")]
335                 public void IsDefined ()
336                 {
337                         try {
338                                 method_create.IsDefined (typeof (FlagsAttribute), false);
339                                 Assert.Fail ("#A1");
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");
345                         }
346
347                         try {
348                                 method_edit.IsDefined (typeof (FlagsAttribute), false);
349                                 Assert.Fail ("#B1");
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");
355                         }
356                 }
357
358                 [Test]
359                 public void IsGenericMethodDefinition ()
360                 {
361                         Assert.IsFalse (method_create.IsGenericMethodDefinition, "#1");
362                         Assert.IsTrue (method_edit.IsGenericMethodDefinition, "#2");
363                 }
364
365                 [Test]
366                 public void IsGenericMethod ()
367                 {
368                         Assert.IsFalse (method_create.IsGenericMethod, "#1");
369                         Assert.IsTrue (method_edit.IsGenericMethod, "#2");
370                 }
371
372                 [Test]
373                 [Category ("NotWorking")]
374                 public void MakeGenericMethod ()
375                 {
376                         try {
377                                 method_create.MakeGenericMethod (typeof (int));
378                                 Assert.Fail ("#A1");
379                         } catch (InvalidOperationException ex) {
380                                 // create is not a GenericMethodDefinition.
381                                 // MakeGenericMethod may only be called on a
382                                 // method for which MethodBase.IsGenericMethodDefinition
383                                 // is true
384                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
385                                 Assert.IsNull (ex.InnerException, "#A3");
386                                 Assert.IsNotNull (ex.Message, "#A4");
387                         }
388
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");
393                 }
394
395                 [Test]
396                 public void MemberType ()
397                 {
398                         Assert.AreEqual (MemberTypes.Method, method_create.MemberType, "#1");
399                         Assert.AreEqual (MemberTypes.Method, method_edit.MemberType, "#2");
400                 }
401
402                 [Test]
403                 [Category ("NotWorking")]
404                 public void MethodHandle ()
405                 {
406                         try {
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");
414                         }
415
416                         try {
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");
424                         }
425                 }
426
427                 [Test]
428                 public void Module ()
429                 {
430                         Assert.AreSame (module, method_create.Module, "#1");
431                         Assert.AreSame (module, method_edit.Module, "#2");
432                 }
433
434                 [Test]
435                 public void Name ()
436                 {
437                         Assert.AreEqual ("create", method_create.Name, "#1");
438                         Assert.AreEqual ("edit", method_edit.Name, "#2");
439                 }
440
441                 [Test]
442                 public void ReflectedType ()
443                 {
444                         Assert.AreSame (typeBarOfInt32, method_create.ReflectedType, "#1");
445                         Assert.AreSame (typeBarOfInt32, method_edit.ReflectedType, "#2");
446                 }
447
448                 [Test]
449                 public void ReturnParameter ()
450                 {
451                         try {
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");
459                         }
460
461                         try {
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");
469                         }
470                 }
471
472                 [Test]
473                 [Category ("NotWorking")]
474                 public void ReturnType ()
475                 {
476                         Type ret;
477                         
478                         ret = method_create.ReturnType;
479                         Assert.AreSame (typeBarOfT, ret, "#1");
480                         ret = method_edit.ReturnType;
481                         Assert.AreSame (typeBarOfT, ret, "#2");
482                 }
483
484                 [Test]
485                 [Category ("NotWorking")]
486                 public void ReturnTypeCustomAttributes ()
487                 {
488                         try {
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");
496                         }
497
498                         try {
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");
506                         }
507                 }
508
509                 public class GenericType<T> {
510                 }
511
512                 [Test]
513                 [Category ("NotDotNet")]
514                 public void MetadataTokenWorksUnderCompilerContext  ()
515                 {
516                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
517                         int mb_token = mb_create.MetadataToken;
518                         int inst_token = method_create.MetadataToken;
519                         Assert.AreEqual (mb_token, inst_token, "#1");
520                 }
521                 
522                 [Test]
523                 [Category ("NotDotNet")] //bug #412965
524                 public void NullReturnTypeWorksUnderCompilerContext  ()
525                 {
526                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
527
528                         Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
529                         TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
530
531                         MethodBuilder method_0 = typeBuilder.DefineMethod ("_0", MethodAttributes.Public, typeParams [0], Type.EmptyTypes);
532                         method_0.SetReturnType (null);
533
534                         Type newGinst = typeBuilder.MakeGenericType (typeof (float));
535                         
536                         MethodInfo new_method_0 = TypeBuilder.GetMethod (newGinst, method_0);
537
538                         Assert.AreEqual (null, new_method_0.ReturnType, "O#1");
539                 }
540
541                 [Test]
542                 [Category ("NotDotNet")]
543                 public void ReturnTypeWorksUnderCompilerContext  ()
544                 {
545                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
546
547                         Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
548                         TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
549
550                         MethodBuilder method_0 = typeBuilder.DefineMethod ("_0", MethodAttributes.Public, typeParams [0], Type.EmptyTypes);
551                         MethodBuilder method_1 = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (GenericType<>).MakeGenericType (typeParams [0]), Type.EmptyTypes);
552
553                         Type newGinst = typeBuilder.MakeGenericType (typeof (float));
554
555                         MethodInfo old_method_0 = TypeBuilder.GetMethod (oldGinst, method_0);
556                         MethodInfo new_method_0 = TypeBuilder.GetMethod (newGinst, method_0);
557
558                         MethodInfo old_method_1 = TypeBuilder.GetMethod (oldGinst, method_1);
559                         MethodInfo new_method_1 = TypeBuilder.GetMethod (newGinst, method_1);
560
561                         Assert.AreEqual (typeof (double), old_method_0.ReturnType, "O#1");
562                         Assert.AreEqual (typeof (float), new_method_0.ReturnType, "N#1");
563
564                         Assert.AreEqual (typeof (GenericType <double>), old_method_1.ReturnType, "O#1");
565                         Assert.AreEqual (typeof (GenericType <float>), new_method_1.ReturnType, "N#1");
566                 }
567
568                 [Test]
569                 [Category ("NotDotNet")]
570                 public void GetParametersWorksUnderCompilerContext  ()
571                 {
572                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
573
574                         Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
575                         TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
576
577                         MethodBuilder target_method = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (void), 
578                         new Type[] {
579                                 typeof (int),
580                                 typeParams [0],
581                                 typeParams [0].MakeArrayType (),
582                                 typeParams [0].MakePointerType (),
583                                 typeParams [0].MakeByRefType (),
584                                 typeof (GenericType<>).MakeGenericType (typeParams [0]),
585                                 typeof (GenericType<>).MakeGenericType (typeof (GenericType<>).MakeGenericType (typeParams [0]))});
586
587
588                         Type newGinst = typeBuilder.MakeGenericType (typeof (float));
589
590                         MethodInfo old_method = TypeBuilder.GetMethod (oldGinst, target_method);
591                         MethodInfo new_method = TypeBuilder.GetMethod (newGinst, target_method);
592                         ParameterInfo[] old_params = old_method.GetParameters ();
593                         ParameterInfo[] new_params = new_method.GetParameters ();
594
595                         Assert.AreEqual (typeof (int), old_params [0].ParameterType, "O#1");
596                         Assert.AreEqual (typeof (double), old_params [1].ParameterType, "O#2");
597                         Assert.AreEqual (typeof (double).MakeArrayType (), old_params [2].ParameterType, "O#3");
598
599                         Assert.AreEqual (typeof (double).MakePointerType (), old_params [3].ParameterType, "O#4");
600                         
601                         Assert.AreEqual (typeof (double).MakeByRefType (), old_params [4].ParameterType, "O#5");
602                         Assert.AreEqual (typeof (GenericType <double>), old_params [5].ParameterType, "O#6");
603                         Assert.AreEqual (typeof (GenericType <GenericType<double>>), old_params [6].ParameterType, "O#7");
604
605                         Assert.AreEqual (typeof (int), new_params [0].ParameterType, "N#1");
606                         Assert.AreEqual (typeof (float), new_params [1].ParameterType, "N#2");
607                         Assert.AreEqual (typeof (float).MakeArrayType (), new_params [2].ParameterType, "N#3");
608
609                         Assert.AreEqual (typeof (float).MakePointerType (), new_params [3].ParameterType, "N#4");
610
611                         Assert.AreEqual (typeof (float).MakeByRefType (), new_params [4].ParameterType, "N#5");
612                         Assert.AreEqual (typeof (GenericType <float>), new_params [5].ParameterType, "N#6");
613                         Assert.AreEqual (typeof (GenericType <GenericType<float>>), new_params [6].ParameterType, "N#7");
614                 }
615
616                 [Test]
617                 public void GenericMethodInstanceValues ()
618                 {
619                         var tb = module.DefineType ("foo.type");
620                         var gparam = tb.DefineGenericParameters ("T") [0];
621
622                         var mb0 = tb.DefineMethod ("str2", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type[] { gparam, gparam.MakeArrayType () });
623
624                         var mb = tb.DefineMethod ("str", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type [0]);
625                         var mparam = mb.DefineGenericParameters ("K") [0];
626                         mb.SetReturnType (mparam);
627                         mb.SetParameters (new Type[] { mparam, mparam.MakeArrayType () });
628
629                         var ginst = tb.MakeGenericType (typeof (double));
630                         var gmd = TypeBuilder.GetMethod (ginst, mb);
631                         var minst = gmd.MakeGenericMethod (typeof (int));
632
633                         var mmb = TypeBuilder.GetMethod (ginst, mb0);
634
635                         Assert.IsNull (mmb.GetGenericArguments (), "#1");
636                         Assert.AreEqual (1, gmd.GetGenericArguments ().Length, "#2");
637                         Assert.AreEqual (1, minst.GetGenericArguments ().Length, "#3");
638                         Assert.AreEqual (typeof (int), minst.GetGenericArguments () [0], "#4");
639
640                         try {
641                                 var x = mmb.ContainsGenericParameters;
642                                 Assert.Fail ("#5");
643                         } catch (NotSupportedException) { }
644
645                         Assert.IsTrue (gmd.IsGenericMethodDefinition, "#6");
646                         Assert.IsFalse (minst.IsGenericMethodDefinition, "#7");
647
648                         Assert.IsFalse (mmb.IsGenericMethod, "#8");
649                         Assert.IsTrue (gmd.IsGenericMethod, "#9");
650                         Assert.IsTrue (minst.IsGenericMethod, "#10");
651
652                         Assert.AreEqual (mb0, mmb.GetGenericMethodDefinition (), "#11");
653                         Assert.AreEqual (mb, gmd.GetGenericMethodDefinition (), "#12");
654                         Assert.AreEqual (gmd, minst.GetGenericMethodDefinition (), "#13");
655                 }
656
657                 [Test]
658                 [Category ("NotDotNet")]
659                 public void GenericMethodInstanceValuesUnderCompilerContext ()
660                 {
661                         SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
662
663                         var tb = module.DefineType ("foo.type");
664                         var gparam = tb.DefineGenericParameters ("T") [0];
665
666                         var mb0 = tb.DefineMethod ("str2", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type[] { gparam, gparam.MakeArrayType () });
667
668                         var mb = tb.DefineMethod ("str", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type [0]);
669                         var mparam = mb.DefineGenericParameters ("K") [0];
670                         mb.SetReturnType (mparam);
671                         mb.SetParameters (new Type[] { mparam, mparam.MakeArrayType () });
672
673                         var ginst = tb.MakeGenericType (typeof (double));
674                         var gmd = TypeBuilder.GetMethod (ginst, mb);
675                         var minst = gmd.MakeGenericMethod (typeof (int));
676
677                         var mmb = TypeBuilder.GetMethod (ginst, mb0);
678
679                         Assert.AreEqual (mparam, gmd.ReturnType, "#1");
680                         Assert.AreEqual (typeof (int), minst.ReturnType, "#2");
681
682                         Assert.AreEqual (mparam, gmd.GetParameters ()[0].ParameterType, "#3");
683                         Assert.IsTrue (gmd.GetParameters ()[1].ParameterType.IsArray, "#4");
684                         Assert.AreEqual (typeof (int), minst.GetParameters ()[0].ParameterType, "#5");
685                         Assert.AreEqual (typeof (int[]), minst.GetParameters ()[1].ParameterType, "#6");
686                 }
687         }
688 }
689
690 #endif