New tests.
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / MethodOnTypeBuilderInstTest.cs
index 6ef86d8af1e47c33afc02d549559f4e781cd2671..6c558448030ba51691d8ae7673f7516d158c95ea 100644 (file)
@@ -29,6 +29,7 @@
 #if NET_2_0
 
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Reflection;
@@ -51,21 +52,29 @@ namespace MonoTests.System.Reflection.Emit
                private Type typeBarOfInt32;
                private MethodInfo method_create;
                private MethodInfo method_edit;
+               private TypeBuilder typeBuilder;
+               private GenericTypeParameterBuilder[] typeParams;
+               
 
                [SetUp]
                public void SetUp ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave);
+               }
+               
+               void SetUp (AssemblyBuilderAccess access)
                {
                        AssemblyName assemblyName = new AssemblyName ();
                        assemblyName.Name = ASSEMBLY_NAME;
 
                        assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (
-                               assemblyName, AssemblyBuilderAccess.RunAndSave,
+                               assemblyName, access,
                                Path.GetTempPath ());
 
                        module = assembly.DefineDynamicModule ("module1");
 
-                       TypeBuilder tb = module.DefineType ("Bar");
-                       GenericTypeParameterBuilder [] typeParams = tb.DefineGenericParameters ("T");
+                       TypeBuilder tb = typeBuilder = module.DefineType ("Bar");
+                       typeParams = tb.DefineGenericParameters ("T");
 
                        ConstructorBuilder cb = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
                        ILGenerator ig = cb.GetILGenerator ();
@@ -497,6 +506,200 @@ namespace MonoTests.System.Reflection.Emit
                                Assert.IsNotNull (ex.Message, "#B4");
                        }
                }
+
+               public class GenericType<T> {
+               }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void MetadataTokenWorksUnderCompilerContext  ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+                       int mb_token = mb_create.MetadataToken;
+                       int inst_token = method_create.MetadataToken;
+                       Assert.AreEqual (mb_token, inst_token, "#1");
+               }
+               
+               [Test]
+               [Category ("NotDotNet")] //bug #412965
+               public void NullReturnTypeWorksUnderCompilerContext  ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+
+                       Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
+                       TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
+
+                       MethodBuilder method_0 = typeBuilder.DefineMethod ("_0", MethodAttributes.Public, typeParams [0], Type.EmptyTypes);
+                       method_0.SetReturnType (null);
+
+                       Type newGinst = typeBuilder.MakeGenericType (typeof (float));
+                       
+                       MethodInfo new_method_0 = TypeBuilder.GetMethod (newGinst, method_0);
+
+                       Assert.AreEqual (null, new_method_0.ReturnType, "O#1");
+               }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void ReturnTypeWorksUnderCompilerContext  ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+
+                       Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
+                       TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
+
+                       MethodBuilder method_0 = typeBuilder.DefineMethod ("_0", MethodAttributes.Public, typeParams [0], Type.EmptyTypes);
+                       MethodBuilder method_1 = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (GenericType<>).MakeGenericType (typeParams [0]), Type.EmptyTypes);
+
+                       Type newGinst = typeBuilder.MakeGenericType (typeof (float));
+
+                       MethodInfo old_method_0 = TypeBuilder.GetMethod (oldGinst, method_0);
+                       MethodInfo new_method_0 = TypeBuilder.GetMethod (newGinst, method_0);
+
+                       MethodInfo old_method_1 = TypeBuilder.GetMethod (oldGinst, method_1);
+                       MethodInfo new_method_1 = TypeBuilder.GetMethod (newGinst, method_1);
+
+                       Assert.AreEqual (typeof (double), old_method_0.ReturnType, "O#1");
+                       Assert.AreEqual (typeof (float), new_method_0.ReturnType, "N#1");
+
+                       Assert.AreEqual (typeof (GenericType <double>), old_method_1.ReturnType, "O#1");
+                       Assert.AreEqual (typeof (GenericType <float>), new_method_1.ReturnType, "N#1");
+               }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void GetParametersWorksUnderCompilerContext  ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+
+                       Type oldGinst = typeBuilder.MakeGenericType (typeof (double));
+                       TypeBuilder.GetMethod (oldGinst, mb_create); //cause it to be inflated
+
+                       MethodBuilder target_method = typeBuilder.DefineMethod ("_1", MethodAttributes.Public, typeof (void), 
+                       new Type[] {
+                               typeof (int),
+                               typeParams [0],
+                               typeParams [0].MakeArrayType (),
+                               typeParams [0].MakePointerType (),
+                               typeParams [0].MakeByRefType (),
+                               typeof (GenericType<>).MakeGenericType (typeParams [0]),
+                               typeof (GenericType<>).MakeGenericType (typeof (GenericType<>).MakeGenericType (typeParams [0]))});
+
+
+                       Type newGinst = typeBuilder.MakeGenericType (typeof (float));
+
+                       MethodInfo old_method = TypeBuilder.GetMethod (oldGinst, target_method);
+                       MethodInfo new_method = TypeBuilder.GetMethod (newGinst, target_method);
+                       ParameterInfo[] old_params = old_method.GetParameters ();
+                       ParameterInfo[] new_params = new_method.GetParameters ();
+
+                       Assert.AreEqual (typeof (int), old_params [0].ParameterType, "O#1");
+                       Assert.AreEqual (typeof (double), old_params [1].ParameterType, "O#2");
+                       Assert.AreEqual (typeof (double).MakeArrayType (), old_params [2].ParameterType, "O#3");
+
+                       Assert.AreEqual (typeof (double).MakePointerType (), old_params [3].ParameterType, "O#4");
+                       
+                       Assert.AreEqual (typeof (double).MakeByRefType (), old_params [4].ParameterType, "O#5");
+                       Assert.AreEqual (typeof (GenericType <double>), old_params [5].ParameterType, "O#6");
+                       Assert.AreEqual (typeof (GenericType <GenericType<double>>), old_params [6].ParameterType, "O#7");
+
+                       Assert.AreEqual (typeof (int), new_params [0].ParameterType, "N#1");
+                       Assert.AreEqual (typeof (float), new_params [1].ParameterType, "N#2");
+                       Assert.AreEqual (typeof (float).MakeArrayType (), new_params [2].ParameterType, "N#3");
+
+                       Assert.AreEqual (typeof (float).MakePointerType (), new_params [3].ParameterType, "N#4");
+
+                       Assert.AreEqual (typeof (float).MakeByRefType (), new_params [4].ParameterType, "N#5");
+                       Assert.AreEqual (typeof (GenericType <float>), new_params [5].ParameterType, "N#6");
+                       Assert.AreEqual (typeof (GenericType <GenericType<float>>), new_params [6].ParameterType, "N#7");
+               }
+
+               [Test]
+               public void GenericMethodInstanceValues ()
+               {
+                       var tb = module.DefineType ("foo.type");
+                       var gparam = tb.DefineGenericParameters ("T") [0];
+
+                       var mb0 = tb.DefineMethod ("str2", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type[] { gparam, gparam.MakeArrayType () });
+
+                       var mb = tb.DefineMethod ("str", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type [0]);
+                       var mparam = mb.DefineGenericParameters ("K") [0];
+                       mb.SetReturnType (mparam);
+                       mb.SetParameters (new Type[] { mparam, mparam.MakeArrayType () });
+
+                       var ginst = tb.MakeGenericType (typeof (double));
+                       var gmd = TypeBuilder.GetMethod (ginst, mb);
+                       var minst = gmd.MakeGenericMethod (typeof (int));
+
+                       var mmb = TypeBuilder.GetMethod (ginst, mb0);
+
+                       Assert.IsNull (mmb.GetGenericArguments (), "#1");
+                       Assert.AreEqual (1, gmd.GetGenericArguments ().Length, "#2");
+                       Assert.AreEqual (1, minst.GetGenericArguments ().Length, "#3");
+                       Assert.AreEqual (typeof (int), minst.GetGenericArguments () [0], "#4");
+
+                       try {
+                               var x = mmb.ContainsGenericParameters;
+                               Assert.Fail ("#5");
+                       } catch (NotSupportedException) { }
+
+                       Assert.IsTrue (gmd.IsGenericMethodDefinition, "#6");
+                       Assert.IsFalse (minst.IsGenericMethodDefinition, "#7");
+
+                       Assert.IsFalse (mmb.IsGenericMethod, "#8");
+                       Assert.IsTrue (gmd.IsGenericMethod, "#9");
+                       Assert.IsTrue (minst.IsGenericMethod, "#10");
+
+                       Assert.AreEqual (mb0, mmb.GetGenericMethodDefinition (), "#11");
+                       Assert.AreEqual (mb, gmd.GetGenericMethodDefinition (), "#12");
+                       Assert.AreEqual (gmd, minst.GetGenericMethodDefinition (), "#13");
+               }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void GenericMethodInstanceValuesUnderCompilerContext ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+
+                       var tb = module.DefineType ("foo.type");
+                       var gparam = tb.DefineGenericParameters ("T") [0];
+
+                       var mb0 = tb.DefineMethod ("str2", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type[] { gparam, gparam.MakeArrayType () });
+
+                       var mb = tb.DefineMethod ("str", MethodAttributes.Public | MethodAttributes.Static, typeof (object), new Type [0]);
+                       var mparam = mb.DefineGenericParameters ("K") [0];
+                       mb.SetReturnType (mparam);
+                       mb.SetParameters (new Type[] { mparam, mparam.MakeArrayType () });
+
+                       var ginst = tb.MakeGenericType (typeof (double));
+                       var gmd = TypeBuilder.GetMethod (ginst, mb);
+                       var minst = gmd.MakeGenericMethod (typeof (int));
+
+                       var mmb = TypeBuilder.GetMethod (ginst, mb0);
+
+                       Assert.AreEqual (mparam, gmd.ReturnType, "#1");
+                       Assert.AreEqual (typeof (int), minst.ReturnType, "#2");
+
+                       Assert.AreEqual (mparam, gmd.GetParameters ()[0].ParameterType, "#3");
+                       Assert.IsTrue (gmd.GetParameters ()[1].ParameterType.IsArray, "#4");
+                       Assert.AreEqual (typeof (int), minst.GetParameters ()[0].ParameterType, "#5");
+                       Assert.AreEqual (typeof (int[]), minst.GetParameters ()[1].ParameterType, "#6");
+               }
+
+               [Test]
+               public void PropertiesOfANonGenericMethodOnGenericType ()
+               {
+                       Type t = typeof (List<>);
+                       Type a = t.GetGenericArguments () [0];
+                       MethodInfo m = t.GetMethod ("IndexOf", new Type [] { a });
+       
+                       var tb = module.DefineType ("foo.type");
+                       Type ttt = t.MakeGenericType (tb);
+                       MethodInfo mm = TypeBuilder.GetMethod (ttt, m);
+                       Assert.IsTrue (mm.GetGenericMethodDefinition ().ContainsGenericParameters, "#1");
+                       Assert.IsTrue (mm.ContainsGenericParameters, "#2");
+               }
+
        }
 }