Switch to compiler-tester
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / MethodBuilderTest.cs
index 803596a15093916a9800fbb37cf8f55b6934a102..8db0b3a51d04a69a0ef3633ddd55b1c4be323767 100644 (file)
-//\r
-// MethodBuilderTest.cs - NUnit Test Cases for the MethodBuilder class\r
-//\r
-// Zoltan Varga (vargaz@freemail.hu)\r
-//\r
-// (C) Ximian, Inc.  http://www.ximian.com\r
-\r
-// TODO:\r
-//  - implement 'Signature' (what the hell it does???) and test it\r
-//  - implement Equals and test it\r
-\r
-using System;\r
-using System.Threading;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Runtime.CompilerServices;\r
-using System.Security;\r
-using System.Security.Permissions;\r
-\r
-using NUnit.Framework;\r
-\r
-namespace MonoTests.System.Reflection.Emit\r
-{\r
-\r
-[TestFixture]\r
-public class MethodBuilderTest : Assertion\r
-{      \r
-    private TypeBuilder genClass;\r
-\r
-       private ModuleBuilder module;\r
-\r
-       [SetUp]\r
-       protected void SetUp () {\r
-               AssemblyName assemblyName = new AssemblyName();\r
-               assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodBuilderTest";\r
-\r
-               AssemblyBuilder assembly \r
-                       = Thread.GetDomain().DefineDynamicAssembly(\r
-                               assemblyName, AssemblyBuilderAccess.Run);\r
-\r
-               module = assembly.DefineDynamicModule("module1");\r
-               \r
-               genClass = module.DefineType(genTypeName (), \r
-                                                                        TypeAttributes.Public);\r
-       }\r
-\r
-       static int methodIndexer = 0;\r
-\r
-       static int typeIndexer = 0;\r
-\r
-       // Return a unique method name\r
-       private string genMethodName () {\r
-               return "m" + (methodIndexer ++);\r
-       }\r
-\r
-       // Return a unique type name\r
-       private string genTypeName () {\r
-               return "class" + (typeIndexer ++);\r
-       }\r
-\r
-       public void TestAttributes () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Public, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("Attributes works", \r
-                                         MethodAttributes.Public, mb.Attributes);\r
-       }\r
-\r
-       public void TestCallingConvention () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type[0]);\r
-               AssertEquals ("CallingConvetion defaults to Standard+HasThis",\r
-                                         CallingConventions.Standard | CallingConventions.HasThis,\r
-                                         mb.CallingConvention);\r
-\r
-               MethodBuilder mb3 = genClass.DefineMethod (\r
-                       genMethodName (), 0, CallingConventions.VarArgs, typeof (void), new Type[0]);\r
-               AssertEquals ("CallingConvetion works",\r
-                                         CallingConventions.VarArgs | CallingConventions.HasThis,\r
-                                         mb3.CallingConvention);\r
-\r
-               MethodBuilder mb4 = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Static, CallingConventions.Standard,\r
-                       typeof (void), new Type [0]);\r
-               AssertEquals ("Static implies !HasThis",\r
-                                         CallingConventions.Standard,\r
-                                         mb4.CallingConvention);\r
-       }\r
-\r
-       public void TestDeclaringType () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type[0]);\r
-\r
-               AssertEquals ("DeclaringType works",\r
-                                         genClass, mb.DeclaringType);\r
-       }\r
-\r
-       public void TestInitLocals () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type[0]);\r
-\r
-               Assert ("InitLocals defaults to true", mb.InitLocals);\r
-               mb.InitLocals = false;\r
-               Assert ("InitLocals is settable", !mb.InitLocals);\r
-       }\r
-\r
-       public void TestMethodHandle () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               try {\r
-                       RuntimeMethodHandle handle = mb.MethodHandle;\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-       }\r
-\r
-       public void TestName () {\r
-               string name = genMethodName ();\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       name, 0, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("Name works", name, mb.Name);\r
-       }\r
-\r
-       public void TestReflectedType () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("ReflectedType works", \r
-                                         genClass, mb.ReflectedType);\r
-       }\r
-\r
-       public void TestReturnType () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (Console), new Type [0]);\r
-\r
-               AssertEquals ("ReturnType works", typeof (Console),\r
-                                         mb.ReturnType);\r
-\r
-               \r
-               MethodBuilder mb2 = genClass.DefineMethod (\r
-                       genMethodName (), 0, null, new Type [0]);\r
-\r
-               Assert ("void ReturnType works", (mb2.ReturnType == null) || (mb2.ReturnType == typeof (void)));\r
-       }\r
-\r
-       public void TestReturnTypeCustomAttributes () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (Console), new Type [0]);\r
-\r
-               AssertEquals ("ReturnTypeCustomAttributes must be null", null,\r
-                                         mb.ReturnTypeCustomAttributes);\r
-       }\r
-\r
-       /*\r
-       public void TestSignature () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       "m91", 0, typeof (Console), new Type [1] { typeof (Console) });\r
-\r
-               Console.WriteLine (mb.Signature);\r
-       }\r
-       */\r
-\r
-       public void TestCreateMethodBody () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               // Clear body\r
-               mb.CreateMethodBody (null, 999);\r
-\r
-               // Check arguments 1.\r
-               try {\r
-                       mb.CreateMethodBody (new byte[1], -1);\r
-                       Fail ();\r
-               } catch (ArgumentException) {\r
-               }\r
-\r
-               // Check arguments 2.\r
-               try {\r
-                       mb.CreateMethodBody (new byte[1], 2);\r
-                       Fail ();\r
-               } catch (ArgumentException) {\r
-               }\r
-\r
-               mb.CreateMethodBody (new byte[2], 1);\r
-\r
-               // Could only be called once\r
-               try {\r
-                       mb.CreateMethodBody (new byte[2], 1);\r
-                       Fail ();\r
-               } catch (InvalidOperationException) {\r
-               }\r
-\r
-               // Can not be called on a created type\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               MethodBuilder mb2 = tb.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-               ILGenerator ilgen = mb2.GetILGenerator ();\r
-               ilgen.Emit (OpCodes.Ret);\r
-               tb.CreateType ();\r
-\r
-               try {\r
-                       mb2.CreateMethodBody (new byte[2], 1);\r
-                       Fail ();\r
-               } catch (InvalidOperationException) {\r
-               }\r
-       }\r
-\r
-       public void TestDefineParameter () {\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               MethodBuilder mb = tb.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), \r
-                       new Type [2] { typeof(int), typeof(int) });\r
-\r
-               // index out of range\r
-\r
-               // This fails on mono because the mono version accepts a 0 index\r
-               /*\r
-               try {\r
-                       mb.DefineParameter (0, 0, "param1");\r
-                       Fail ();\r
-               } catch (ArgumentOutOfRangeException) {\r
-               }\r
-               */\r
-\r
-               try {\r
-                       mb.DefineParameter (3, 0, "param1");\r
-                       Fail ();\r
-               } catch (ArgumentOutOfRangeException) {\r
-               }\r
-\r
-               // Normal usage\r
-               mb.DefineParameter (1, 0, "param1");\r
-               mb.DefineParameter (1, 0, "param1");\r
-               mb.DefineParameter (2, 0, null);\r
-\r
-               // Can not be called on a created type\r
-               mb.CreateMethodBody (new byte[2], 0);\r
-               tb.CreateType ();\r
-               try {\r
-                       mb.DefineParameter (1, 0, "param1");\r
-                       Fail ();\r
-               }\r
-               catch (InvalidOperationException) {\r
-               }\r
-       }\r
-\r
-       public void TestGetBaseDefinition () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("GetBaseDefinition works",\r
-                                         mb.GetBaseDefinition (), mb);\r
-       }\r
-\r
-       public void TestGetILGenerator () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               // The same instance is returned on the second call\r
-               ILGenerator ilgen1 = mb.GetILGenerator ();\r
-               ILGenerator ilgen2 = mb.GetILGenerator ();\r
-\r
-               AssertEquals ("The same ilgen is returned on the second call",\r
-                                         ilgen1, ilgen2);\r
-\r
-               // Does not work on unmanaged code\r
-               MethodBuilder mb2 = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);              \r
-               try {\r
-                       mb2.SetImplementationFlags (MethodImplAttributes.Unmanaged);\r
-                       mb2.GetILGenerator ();\r
-                       Fail ();\r
-               } catch (InvalidOperationException) {\r
-               }\r
-               try {\r
-                       mb2.SetImplementationFlags (MethodImplAttributes.Native);\r
-                       mb2.GetILGenerator ();\r
-                       Fail ();\r
-               } catch (InvalidOperationException) {\r
-               }\r
-       }\r
-\r
-       public void TestMethodImplementationFlags () {\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               MethodBuilder mb = tb.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("MethodImplementationFlags defaults to Managed+IL",\r
-                                         MethodImplAttributes.Managed | MethodImplAttributes.IL,\r
-                                         mb.GetMethodImplementationFlags ());\r
-\r
-               mb.SetImplementationFlags (MethodImplAttributes.OPTIL);\r
-\r
-               AssertEquals ("SetImplementationFlags works",\r
-                                         MethodImplAttributes.OPTIL, \r
-                                         mb.GetMethodImplementationFlags ());\r
-\r
-               // Can not be called on a created type\r
-               mb.CreateMethodBody (new byte[2], 0);\r
-               mb.SetImplementationFlags (MethodImplAttributes.Managed);\r
-               tb.CreateType ();\r
-               try {\r
-                       mb.SetImplementationFlags (MethodImplAttributes.OPTIL);\r
-                       Fail ();\r
-               }\r
-               catch (InvalidOperationException) {\r
-               }\r
-       }\r
-\r
-       public void TestGetModule () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [0]);\r
-\r
-               AssertEquals ("GetMethod works", module, \r
-                                         mb.GetModule ());\r
-       }\r
-\r
-       public void TestGetParameters () {\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               MethodBuilder mb = tb.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});\r
-\r
-               /*\r
-                * According to the MSDN docs, this method should fail with a\r
-                * NotSupportedException. In reality, it throws an \r
-                * InvalidOperationException under MS .NET, and returns the \r
-                * requested data under mono.\r
-                */\r
-               /*\r
-               try {\r
-                       mb.GetParameters ();\r
-                       Fail ("#161");\r
-               } catch (InvalidOperationException ex) {\r
-                       Console.WriteLine (ex);\r
-               }\r
-               */\r
-       }\r
-\r
-       public void TestGetToken () {\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               MethodBuilder mb = tb.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});\r
-\r
-               mb.GetToken ();\r
-       }\r
-\r
-       public void TestInvoke () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), \r
-                       new Type [1] {typeof(int)});\r
-\r
-               try {\r
-                       mb.Invoke (null, new object [1] { 42 });\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-\r
-               try {\r
-                       mb.Invoke (null, 0, null, new object [1] { 42 }, null);\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-       }\r
-\r
-       public void TestIsDefined () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), \r
-                       new Type [1] {typeof(int)});\r
-\r
-               try {\r
-                       mb.IsDefined (null, true);\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-       }\r
-\r
-       public void TestGetCustomAttributes () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), 0, typeof (void), \r
-                       new Type [1] {typeof(int)});\r
-\r
-               try {\r
-                       mb.GetCustomAttributes (true);\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-\r
-               try {\r
-                       mb.GetCustomAttributes (null, true);\r
-                       Fail ();\r
-               } catch (NotSupportedException) {\r
-               }\r
-       }\r
-\r
-       public void TestSetCustomAttribute () {\r
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);\r
-               string name = genMethodName ();\r
-               MethodBuilder mb = tb.DefineMethod (\r
-                       name, MethodAttributes.Public, typeof (void), \r
-                       new Type [1] {typeof(int)});\r
-\r
-               // Null argument\r
-               try {\r
-                       mb.SetCustomAttribute (null);\r
-                       Fail ();\r
-               } catch (ArgumentNullException) {\r
-               }\r
-\r
-               byte[] custAttrData = { 1, 0, 0, 0, 0};\r
-               Type attrType = Type.GetType\r
-                       ("System.Reflection.AssemblyKeyNameAttribute");\r
-               Type[] paramTypes = new Type[1];\r
-               paramTypes[0] = typeof(String);\r
-               ConstructorInfo ctorInfo =\r
-                       attrType.GetConstructor(paramTypes);\r
-\r
-               mb.SetCustomAttribute (ctorInfo, custAttrData);\r
-\r
-               // Test MethodImplAttribute\r
-               mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (MethodImplAttribute).GetConstructor (new Type[1] { typeof (short) }), new object[1] {(short)MethodImplAttributes.Synchronized}));\r
-               mb.GetILGenerator ().Emit (OpCodes.Ret);\r
-\r
-               Type t = tb.CreateType ();\r
-\r
-               AssertEquals ("Setting MethodImplAttributes works",\r
-                                         t.GetMethod (name).GetMethodImplementationFlags (),\r
-                                         MethodImplAttributes.Synchronized);\r
-\r
-               // Null arguments again\r
-               try {\r
-                       mb.SetCustomAttribute (null, new byte[2]);\r
-                       Fail ();\r
-               } catch (ArgumentNullException) {\r
-               }\r
-\r
-               try {\r
-                       mb.SetCustomAttribute (ctorInfo, null);\r
-                       Fail ();\r
-               } catch (ArgumentNullException) {\r
-               }\r
-       }\r
-\r
-       [Test]\r
-       [ExpectedException (typeof (InvalidOperationException))]\r
-       public void TestAddDeclarativeSecurityAlreadyCreated () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Public, typeof (void),\r
-                       new Type [0]);\r
-               ILGenerator ilgen = mb.GetILGenerator ();\r
-               ilgen.Emit (OpCodes.Ret);\r
-               genClass.CreateType ();\r
-\r
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
-       }\r
-\r
-       [Test]\r
-       [ExpectedException (typeof (ArgumentNullException))]\r
-       public void TestAddDeclarativeSecurityNullPermissionSet () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Public, typeof (void), \r
-                       new Type [0]);\r
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, null);\r
-       }\r
-\r
-       [Test]\r
-       public void TestAddDeclarativeSecurityInvalidAction () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Public, typeof (void), \r
-                       new Type [0]);\r
-\r
-               SecurityAction[] actions = new SecurityAction [] { \r
-                       SecurityAction.RequestMinimum,\r
-                       SecurityAction.RequestOptional,\r
-                       SecurityAction.RequestRefuse };\r
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
-\r
-               foreach (SecurityAction action in actions) {\r
-                       try {\r
-                               mb.AddDeclarativeSecurity (action, set);\r
-                               Fail ();\r
-                       }\r
-                       catch (ArgumentException) {\r
-                       }\r
-               }\r
-       }\r
-\r
-       [Test]\r
-       [ExpectedException (typeof (InvalidOperationException))]\r
-       public void TestAddDeclarativeSecurityDuplicateAction () {\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       genMethodName (), MethodAttributes.Public, typeof (void), \r
-                       new Type [0]);\r
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);\r
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);\r
-       }\r
-\r
-       [AttributeUsage (AttributeTargets.Parameter)]\r
-       class ParamAttribute : Attribute {\r
-\r
-               public ParamAttribute () {\r
-               }\r
-       }\r
-\r
-       [Test]\r
-       public void TestDynamicParams () {\r
-               string mname = genMethodName ();\r
-\r
-               MethodBuilder mb = genClass.DefineMethod (\r
-                       mname, MethodAttributes.Public, typeof (void), \r
-                       new Type [] { typeof (string) });\r
-               ParameterBuilder pb = mb.DefineParameter (1, 0, "foo");\r
-               pb.SetCustomAttribute (new CustomAttributeBuilder (typeof (ParamAttribute).GetConstructors () [0], new object [] { }));\r
-\r
-               Type t = genClass.CreateType ();\r
-               MethodInfo m = t.GetMethod (mname);\r
-               ParameterInfo pi = m.GetParameters ()[0];\r
-\r
-               AssertEquals ("foo", pi.Name);\r
-\r
-               object[] cattrs = pi.GetCustomAttributes (true);\r
-               AssertEquals (1, cattrs.Length);\r
-               AssertEquals (typeof (ParamAttribute), cattrs [0].GetType ());\r
-       }\r
-}\r
-}\r
+//
+// MethodBuilderTest.cs - NUnit Test Cases for the MethodBuilder class
+//
+// Zoltan Varga (vargaz@freemail.hu)
+//
+// (C) Ximian, Inc.  http://www.ximian.com
+
+// TODO:
+//  - implement 'Signature' (what the hell it does???) and test it
+//  - implement Equals and test it
+
+using System;
+using System.Threading;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Runtime.InteropServices;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Reflection.Emit
+{
+
+[TestFixture]
+public class MethodBuilderTest : Assertion
+{      
+    private TypeBuilder genClass;
+
+       private ModuleBuilder module;
+
+       [SetUp]
+       protected void SetUp () {
+               AssemblyName assemblyName = new AssemblyName();
+               assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodBuilderTest";
+
+               AssemblyBuilder assembly 
+                       = Thread.GetDomain().DefineDynamicAssembly(
+                               assemblyName, AssemblyBuilderAccess.Run);
+
+               module = assembly.DefineDynamicModule("module1");
+               
+               genClass = module.DefineType(genTypeName (), 
+                                                                        TypeAttributes.Public);
+       }
+
+       static int methodIndexer = 0;
+
+       static int typeIndexer = 0;
+
+       // Return a unique method name
+       private string genMethodName () {
+               return "m" + (methodIndexer ++);
+       }
+
+       // Return a unique type name
+       private string genTypeName () {
+               return "class" + (typeIndexer ++);
+       }
+
+       [Test]
+       public void TestAttributes () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Public, typeof (void), new Type [0]);
+
+               AssertEquals ("Attributes works", 
+                                         MethodAttributes.Public, mb.Attributes);
+       }
+
+       [Test]
+       public void TestCallingConvention () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type[0]);
+               AssertEquals ("CallingConvetion defaults to Standard+HasThis",
+                                         CallingConventions.Standard | CallingConventions.HasThis,
+                                         mb.CallingConvention);
+
+               MethodBuilder mb3 = genClass.DefineMethod (
+                       genMethodName (), 0, CallingConventions.VarArgs, typeof (void), new Type[0]);
+               AssertEquals ("CallingConvetion works",
+                                         CallingConventions.VarArgs | CallingConventions.HasThis,
+                                         mb3.CallingConvention);
+
+               MethodBuilder mb4 = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Static, CallingConventions.Standard,
+                       typeof (void), new Type [0]);
+               AssertEquals ("Static implies !HasThis",
+                                         CallingConventions.Standard,
+                                         mb4.CallingConvention);
+       }
+
+       [Test]
+       public void TestDeclaringType () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type[0]);
+
+               AssertEquals ("DeclaringType works",
+                                         genClass, mb.DeclaringType);
+       }
+
+       [Test]
+       public void TestInitLocals () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type[0]);
+
+               Assert ("InitLocals defaults to true", mb.InitLocals);
+               mb.InitLocals = false;
+               Assert ("InitLocals is settable", !mb.InitLocals);
+       }
+       
+       [Test]
+       [ExpectedException (typeof(NotSupportedException))]
+       public void TestMethodHandleIncomplete () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               RuntimeMethodHandle handle = mb.MethodHandle;
+       }
+
+       [Test]
+       [ExpectedException (typeof(NotSupportedException))]
+       public void TestMethodHandleComplete () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+               mb.CreateMethodBody (new byte[2], 0);
+               genClass.CreateType ();
+
+               RuntimeMethodHandle handle = mb.MethodHandle;
+       }
+
+       [Test]
+       public void TestName () {
+               string name = genMethodName ();
+               MethodBuilder mb = genClass.DefineMethod (
+                       name, 0, typeof (void), new Type [0]);
+
+               AssertEquals ("Name works", name, mb.Name);
+       }
+
+       [Test]
+       public void TestReflectedType () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               AssertEquals ("ReflectedType works", 
+                                         genClass, mb.ReflectedType);
+       }
+
+       [Test]
+       public void TestReturnType () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (Console), new Type [0]);
+
+               AssertEquals ("ReturnType works", typeof (Console),
+                                         mb.ReturnType);
+
+               
+               MethodBuilder mb2 = genClass.DefineMethod (
+                       genMethodName (), 0, null, new Type [0]);
+
+               Assert ("void ReturnType works", (mb2.ReturnType == null) || (mb2.ReturnType == typeof (void)));
+       }
+
+       [Test]
+       public void TestReturnTypeCustomAttributes () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (Console), new Type [0]);
+
+               AssertEquals ("ReturnTypeCustomAttributes must be null", null,
+                                         mb.ReturnTypeCustomAttributes);
+       }
+
+       /*
+       public void TestSignature () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       "m91", 0, typeof (Console), new Type [1] { typeof (Console) });
+
+               Console.WriteLine (mb.Signature);
+       }
+       */
+
+       [Test]
+       public void TestCreateMethodBody () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               // Clear body
+               mb.CreateMethodBody (null, 999);
+
+               // Check arguments 1.
+               try {
+                       mb.CreateMethodBody (new byte[1], -1);
+                       Fail ();
+               } catch (ArgumentException) {
+               }
+
+               // Check arguments 2.
+               try {
+                       mb.CreateMethodBody (new byte[1], 2);
+                       Fail ();
+               } catch (ArgumentException) {
+               }
+
+               mb.CreateMethodBody (new byte[2], 1);
+
+               // Could only be called once
+               try {
+                       mb.CreateMethodBody (new byte[2], 1);
+                       Fail ();
+               } catch (InvalidOperationException) {
+               }
+
+               // Can not be called on a created type
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb2 = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+               ILGenerator ilgen = mb2.GetILGenerator ();
+               ilgen.Emit (OpCodes.Ret);
+               tb.CreateType ();
+
+               try {
+                       mb2.CreateMethodBody (new byte[2], 1);
+                       Fail ();
+               } catch (InvalidOperationException) {
+               }
+       }
+
+       [Test]
+       [ExpectedException (typeof(InvalidOperationException))]
+       public void TestDefineParameterInvalidIndexComplete ()
+       {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void),
+                       new Type[2] {
+                       typeof(int), typeof(int)
+               });
+               mb.CreateMethodBody (new byte[2], 0);
+               tb.CreateType ();
+               mb.DefineParameter (-5, ParameterAttributes.None, "param1");
+       }
+
+       [Test]
+       [ExpectedException (typeof(InvalidOperationException))]
+       public void TestDefineParameterValidIndexComplete ()
+       {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void),
+                       new Type[2] {
+                       typeof(int), typeof(int)
+               });
+               mb.CreateMethodBody (new byte[2], 0);
+               tb.CreateType ();
+               mb.DefineParameter (1, ParameterAttributes.None, "param1");
+       }
+
+       [Test]
+       public void TestDefineParameter () {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void), 
+                       new Type [2] { typeof(int), typeof(int) });
+
+               // index out of range
+
+               // This fails on mono because the mono version accepts a 0 index
+               /*
+               try {
+                       mb.DefineParameter (0, 0, "param1");
+                       Fail ();
+               } catch (ArgumentOutOfRangeException) {
+               }
+               */
+
+               try {
+                       mb.DefineParameter (3, 0, "param1");
+                       Fail ();
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               // Normal usage
+               mb.DefineParameter (1, 0, "param1");
+               mb.DefineParameter (1, 0, "param1");
+               mb.DefineParameter (2, 0, null);
+
+               // Can not be called on a created type
+               mb.CreateMethodBody (new byte[2], 0);
+               tb.CreateType ();
+               try {
+                       mb.DefineParameter (1, 0, "param1");
+                       Fail ();
+               }
+               catch (InvalidOperationException) {
+               }
+       }
+
+       [Test]
+       public void TestHashCode ()
+       {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               string methodName = genMethodName ();
+               MethodBuilder mb = tb.DefineMethod (
+                       methodName, 0, typeof (void),
+                       new Type[2] {
+                       typeof(int), typeof(int)
+               });
+               AssertEquals ("Hashcode of method should be equal to hashcode of method name",
+                       methodName.GetHashCode (), mb.GetHashCode ());
+       }
+
+       [Test]
+       public void TestGetBaseDefinition () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               AssertEquals ("GetBaseDefinition works",
+                                         mb.GetBaseDefinition (), mb);
+       }
+
+       [Test]
+       public void TestGetILGenerator () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               // The same instance is returned on the second call
+               ILGenerator ilgen1 = mb.GetILGenerator ();
+               ILGenerator ilgen2 = mb.GetILGenerator ();
+
+               AssertEquals ("The same ilgen is returned on the second call",
+                                         ilgen1, ilgen2);
+
+               // Does not work on unmanaged code
+               MethodBuilder mb2 = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);              
+               try {
+                       mb2.SetImplementationFlags (MethodImplAttributes.Unmanaged);
+                       mb2.GetILGenerator ();
+                       Fail ();
+               } catch (InvalidOperationException) {
+               }
+               try {
+                       mb2.SetImplementationFlags (MethodImplAttributes.Native);
+                       mb2.GetILGenerator ();
+                       Fail ();
+               } catch (InvalidOperationException) {
+               }
+       }
+
+       [Test]
+       public void TestMethodImplementationFlags () {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               AssertEquals ("MethodImplementationFlags defaults to Managed+IL",
+                                         MethodImplAttributes.Managed | MethodImplAttributes.IL,
+                                         mb.GetMethodImplementationFlags ());
+
+               mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+
+               AssertEquals ("SetImplementationFlags works",
+                                         MethodImplAttributes.OPTIL, 
+                                         mb.GetMethodImplementationFlags ());
+
+               // Can not be called on a created type
+               mb.CreateMethodBody (new byte[2], 0);
+               mb.SetImplementationFlags (MethodImplAttributes.Managed);
+               tb.CreateType ();
+               try {
+                       mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+                       Fail ();
+               }
+               catch (InvalidOperationException) {
+               }
+       }
+
+       [Test]
+       public void TestGetModule () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [0]);
+
+               AssertEquals ("GetMethod works", module, 
+                                         mb.GetModule ());
+       }
+
+       [Test]
+       public void TestGetParameters () {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});
+
+               /*
+                * According to the MSDN docs, this method should fail with a
+                * NotSupportedException. In reality, it throws an 
+                * InvalidOperationException under MS .NET, and returns the 
+                * requested data under mono.
+                */
+               /*
+               try {
+                       mb.GetParameters ();
+                       Fail ("#161");
+               } catch (InvalidOperationException ex) {
+                       Console.WriteLine (ex);
+               }
+               */
+       }
+
+       [Test]
+       public void TestGetToken () {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});
+
+               mb.GetToken ();
+       }
+
+       [Test]
+       public void TestInvoke () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), 
+                       new Type [1] {typeof(int)});
+
+               try {
+                       mb.Invoke (null, new object [1] { 42 });
+                       Fail ();
+               } catch (NotSupportedException) {
+               }
+
+               try {
+                       mb.Invoke (null, 0, null, new object [1] { 42 }, null);
+                       Fail ();
+               } catch (NotSupportedException) {
+               }
+       }
+
+       [Test]
+       [ExpectedException (typeof (NotSupportedException))]
+       public void TestIsDefined () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), 
+                       new Type [1] {typeof(int)});
+               mb.IsDefined (null, true);
+       }
+
+       [Test]
+       public void TestGetCustomAttributes () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), 0, typeof (void), 
+                       new Type [1] {typeof(int)});
+               
+               try {
+                       mb.GetCustomAttributes (true);
+                       Fail ();
+               } catch (NotSupportedException) {
+               }
+
+               try {
+                       mb.GetCustomAttributes (null, true);
+                       Fail ();
+               } catch (NotSupportedException) {
+               }
+       }
+
+       [Test]
+       public void TestSetCustomAttribute () {
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               string name = genMethodName ();
+               MethodBuilder mb = tb.DefineMethod (
+                       name, MethodAttributes.Public, typeof (void), 
+                       new Type [1] {typeof(int)});
+
+               // Null argument
+               try {
+                       mb.SetCustomAttribute (null);
+                       Fail ();
+               } catch (ArgumentNullException) {
+               }
+
+               byte[] custAttrData = { 1, 0, 0, 0, 0};
+               Type attrType = Type.GetType
+                       ("System.Reflection.AssemblyKeyNameAttribute");
+               Type[] paramTypes = new Type[1];
+               paramTypes[0] = typeof(String);
+               ConstructorInfo ctorInfo =
+                       attrType.GetConstructor(paramTypes);
+
+               mb.SetCustomAttribute (ctorInfo, custAttrData);
+
+               // Test MethodImplAttribute
+               mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (MethodImplAttribute).GetConstructor (new Type[1] { typeof (short) }), new object[1] {(short)MethodImplAttributes.Synchronized}));
+               mb.GetILGenerator ().Emit (OpCodes.Ret);
+
+               Type t = tb.CreateType ();
+
+               AssertEquals ("Setting MethodImplAttributes works",
+                                         t.GetMethod (name).GetMethodImplementationFlags (),
+                                         MethodImplAttributes.Synchronized);
+
+               // Null arguments again
+               try {
+                       mb.SetCustomAttribute (null, new byte[2]);
+                       Fail ();
+               } catch (ArgumentNullException) {
+               }
+
+               try {
+                       mb.SetCustomAttribute (ctorInfo, null);
+                       Fail ();
+               } catch (ArgumentNullException) {
+               }
+       }
+
+       [Test]
+       [ExpectedException (typeof (InvalidOperationException))]
+       public void TestAddDeclarativeSecurityAlreadyCreated () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Public, typeof (void),
+                       new Type [0]);
+               ILGenerator ilgen = mb.GetILGenerator ();
+               ilgen.Emit (OpCodes.Ret);
+               genClass.CreateType ();
+
+               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+       }
+
+       [Test]
+       [ExpectedException (typeof (ArgumentNullException))]
+       public void TestAddDeclarativeSecurityNullPermissionSet () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Public, typeof (void), 
+                       new Type [0]);
+               mb.AddDeclarativeSecurity (SecurityAction.Demand, null);
+       }
+
+       [Test]
+       public void TestAddDeclarativeSecurityInvalidAction () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Public, typeof (void), 
+                       new Type [0]);
+
+               SecurityAction[] actions = new SecurityAction [] { 
+                       SecurityAction.RequestMinimum,
+                       SecurityAction.RequestOptional,
+                       SecurityAction.RequestRefuse };
+               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+
+               foreach (SecurityAction action in actions) {
+                       try {
+                               mb.AddDeclarativeSecurity (action, set);
+                               Fail ();
+                       }
+                       catch (ArgumentException) {
+                       }
+               }
+       }
+
+       [Test]
+       [ExpectedException (typeof (InvalidOperationException))]
+       public void TestAddDeclarativeSecurityDuplicateAction () {
+               MethodBuilder mb = genClass.DefineMethod (
+                       genMethodName (), MethodAttributes.Public, typeof (void), 
+                       new Type [0]);
+               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+       }
+
+       [AttributeUsage (AttributeTargets.Parameter)]
+       class ParamAttribute : Attribute {
+
+               public ParamAttribute () {
+               }
+       }
+
+       [Test]
+       public void TestDynamicParams () {
+               string mname = genMethodName ();
+
+               MethodBuilder mb = genClass.DefineMethod (
+                       mname, MethodAttributes.Public, typeof (void), 
+                       new Type [] { typeof (int), typeof (string) });
+               ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
+               pb.SetConstant (52);
+               pb.SetCustomAttribute (new CustomAttributeBuilder (typeof (ParamAttribute).GetConstructors () [0], new object [] { }));
+               ParameterBuilder pb2 = mb.DefineParameter (2, 0, "bar");
+               pb2.SetConstant ("foo");
+               mb.GetILGenerator ().Emit (OpCodes.Ret);
+
+               Type t = genClass.CreateType ();
+               MethodInfo m = t.GetMethod (mname);
+               ParameterInfo[] pi = m.GetParameters ();
+
+               AssertEquals ("foo", pi [0].Name);
+               AssertEquals (true, pi [0].IsIn);
+               AssertEquals (52, pi [0].DefaultValue);
+               object[] cattrs = pi [0].GetCustomAttributes (true);
+
+               AssertEquals ("foo", pi [1].DefaultValue);
+               
+
+               /* This test does not run under MS.NET: */
+               /*
+                 AssertEquals (1, cattrs.Length);
+                 AssertEquals (typeof (ParamAttribute), cattrs [0].GetType ());
+               */
+       }
+
+#if NET_2_0
+       [Test]
+       public void SetCustomAttribute_DllImport1 () {
+               string mname = genMethodName ();
+
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       mname, MethodAttributes.Public, typeof (void), 
+                       new Type [] { typeof (int), typeof (string) });
+
+               // Create an attribute with default values
+               mb.SetCustomAttribute (new CustomAttributeBuilder(typeof(DllImportAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "kernel32" }));
+
+               Type t = tb.CreateType ();
+
+               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+               AssertEquals (CallingConvention.Winapi, attr.CallingConvention);
+               AssertEquals (mname, attr.EntryPoint);
+               AssertEquals ("kernel32", attr.Value);
+               AssertEquals (false, attr.ExactSpelling);
+               AssertEquals (true, attr.PreserveSig);
+               AssertEquals (false, attr.SetLastError);
+               AssertEquals (false, attr.BestFitMapping);
+               AssertEquals (false, attr.ThrowOnUnmappableChar);
+       }
+
+       [Test]
+       public void SetCustomAttribute_DllImport2 () {
+               string mname = genMethodName ();
+
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       mname, MethodAttributes.Public, typeof (void), 
+                       new Type [] { typeof (int), typeof (string) });
+
+               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] {typeof (DllImportAttribute).GetField ("EntryPoint"), typeof (DllImportAttribute).GetField ("CallingConvention"), typeof (DllImportAttribute).GetField ("CharSet"), typeof (DllImportAttribute).GetField ("ExactSpelling"), typeof (DllImportAttribute).GetField ("PreserveSig")}, new object [] { "bar", CallingConvention.StdCall, CharSet.Unicode, true, false });
+               mb.SetCustomAttribute (cb);
+
+               Type t = tb.CreateType ();
+
+               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+               AssertEquals (CallingConvention.StdCall, attr.CallingConvention);
+               AssertEquals (CharSet.Unicode, attr.CharSet);
+               AssertEquals ("bar", attr.EntryPoint);
+               AssertEquals ("foo", attr.Value);
+               AssertEquals (true, attr.ExactSpelling);
+               AssertEquals (false, attr.PreserveSig);
+               AssertEquals (false, attr.SetLastError);
+               AssertEquals (false, attr.BestFitMapping);
+               AssertEquals (false, attr.ThrowOnUnmappableChar);
+       }
+
+       [Test]
+       public void SetCustomAttribute_DllImport3 () {
+               string mname = genMethodName ();
+
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       mname, MethodAttributes.Public, typeof (void), 
+                       new Type [] { typeof (int), typeof (string) });
+
+               // Test attributes with three values (on/off/missing)
+               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { false, false });
+               mb.SetCustomAttribute (cb);
+
+               Type t = tb.CreateType ();
+
+               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+               AssertEquals (false, attr.BestFitMapping);
+               AssertEquals (false, attr.ThrowOnUnmappableChar);
+       }
+
+       [Test]
+       public void SetCustomAttribute_DllImport4 () {
+               string mname = genMethodName ();
+
+               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+               MethodBuilder mb = tb.DefineMethod (
+                       mname, MethodAttributes.Public, typeof (void), 
+                       new Type [] { typeof (int), typeof (string) });
+
+               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("SetLastError"), typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { true, true, true });
+               mb.SetCustomAttribute (cb);
+
+               Type t = tb.CreateType ();
+
+               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+               AssertEquals (true, attr.SetLastError);
+               AssertEquals (true, attr.BestFitMapping);
+               AssertEquals (true, attr.ThrowOnUnmappableChar);
+       }
+#endif
+}
+}