diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2009-08-07 05:56:45 +0400 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2009-08-07 05:56:45 +0400 |
commit | e5d7850ed839e42a4399a865c188c4df750c0ff7 (patch) | |
tree | 717e109aa7246770bf6796432ad86262c816572b /mcs/class | |
parent | ecb3993369eeeecfbff190f6b23f9f5a266dca0c (diff) |
2009-08-06 Rodrigo Kumpera <rkumpera@novell.com>
* Environment.cs: Bump corlib version.
2009-08-06 Rodrigo Kumpera <rkumpera@novell.com>
* MonoGenericClass.cs (InflateType): Add support to inflate
generic method arguments.
* MonoGenericClass.cs (GetMethod): Remove restriction
with generic methods.
2009-08-06 Rodrigo Kumpera <rkumpera@novell.com>
* MethodOnTypeBuilderInstTest.cs: Add tests for
generic method instances over generic type instances.
2009-08-06 Rodrigo Kumpera <rkumpera@novell.com>
* MethodBuilder.cs: Mark generic_params internal.
* MethodOnTypeBuilderInst.cs: Add fields to support
inflated generic methods. Implement generics related
methods.
svn path=/trunk/mcs/; revision=139534
Diffstat (limited to 'mcs/class')
9 files changed, 167 insertions, 38 deletions
diff --git a/mcs/class/corlib/System.Reflection.Emit/ChangeLog b/mcs/class/corlib/System.Reflection.Emit/ChangeLog index fc497b97e1a..2a59ea5a9b8 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ChangeLog +++ b/mcs/class/corlib/System.Reflection.Emit/ChangeLog @@ -1,3 +1,11 @@ +2009-08-06 Rodrigo Kumpera <rkumpera@novell.com> + + * MethodBuilder.cs: Mark generic_params internal. + + * MethodOnTypeBuilderInst.cs: Add fields to support + inflated generic methods. Implement generics related + methods. + 2009-08-06 Marek Safar <marek.safar@gmail.com> * ILGenerator.cs: Add 4.0 ILOffset. diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs index 84b3ba7af7b..2b2dd48becc 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs @@ -72,7 +72,7 @@ namespace System.Reflection.Emit private bool init_locals = true; private IntPtr generic_container; #if NET_2_0 || BOOTSTRAP_NET_2_0 - private GenericTypeParameterBuilder[] generic_params; + internal GenericTypeParameterBuilder[] generic_params; #else private Object generic_params; /* so offsets are the same */ #endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs index 5baecc3a2bd..336745486f2 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs @@ -44,6 +44,8 @@ namespace System.Reflection.Emit #region Keep in sync with object-internals.h MonoGenericClass instantiation; internal MethodBuilder mb; + Type[] method_arguments; + MethodOnTypeBuilderInst generic_method_definition; #endregion public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodBuilder mb) @@ -52,6 +54,14 @@ namespace System.Reflection.Emit this.mb = mb; } + internal MethodOnTypeBuilderInst (MethodOnTypeBuilderInst gmd, Type[] typeArguments) + { + this.instantiation = gmd.instantiation; + this.mb = gmd.mb; + this.method_arguments = new Type [typeArguments.Length]; + typeArguments.CopyTo (this.method_arguments, 0); + this.generic_method_definition = gmd; + } // // MemberInfo members // @@ -78,7 +88,7 @@ namespace System.Reflection.Emit get { if (!((ModuleBuilder)mb.Module).assemblyb.IsCompilerContext) return mb.ReturnType; - return instantiation.InflateType (mb.ReturnType); + return instantiation.InflateType (mb.ReturnType, method_arguments); } } @@ -131,7 +141,7 @@ namespace System.Reflection.Emit ParameterInfo [] res = new ParameterInfo [mb.parameters.Length]; for (int i = 0; i < mb.parameters.Length; i++) { - Type type = instantiation.InflateType (mb.parameters [i]); + Type type = instantiation.InflateType (mb.parameters [i], method_arguments); res [i] = new ParameterInfo (mb.pinfo == null ? null : mb.pinfo [i + 1], type, this, i + 1); } return res; @@ -173,34 +183,63 @@ namespace System.Reflection.Emit } } + public override MethodInfo MakeGenericMethod (params Type [] typeArguments) + { + if (mb.generic_params == null || method_arguments != null) + throw new NotSupportedException (); //FIXME is this the right exception? + + if (typeArguments == null) + throw new ArgumentNullException ("typeArguments"); + + foreach (Type t in typeArguments) { + if (t == null) + throw new ArgumentNullException ("typeArguments"); + } + + if (mb.generic_params.Length != typeArguments.Length) + throw new ArgumentException ("Invalid argument array length"); + + return new MethodOnTypeBuilderInst (this, typeArguments); + } + public override Type [] GetGenericArguments () { - //FIXME test that once we support generic methods - return mb.GetGenericArguments (); + if (mb.generic_params == null) + return null; + Type[] source = method_arguments ?? mb.generic_params; + Type[] result = new Type [source.Length]; + source.CopyTo (result, 0); + return result; } public override MethodInfo GetGenericMethodDefinition () { - return mb; + return (MethodInfo)generic_method_definition ?? mb; } public override bool ContainsGenericParameters { get { - throw new NotSupportedException (); + if (mb.generic_params == null) + throw new NotSupportedException (); + if (method_arguments == null) + return true; + foreach (Type t in method_arguments) { + if (t.ContainsGenericParameters) + return true; + } + return false; } } public override bool IsGenericMethodDefinition { get { - //FIXME test that once we support generic methods - return mb.IsGenericMethodDefinition; + return mb.generic_params != null && method_arguments == null; } } public override bool IsGenericMethod { get { - //FIXME test that once we support generic methods - return mb.IsGenericMethod; + return mb.generic_params != null; } } diff --git a/mcs/class/corlib/System.Reflection/ChangeLog b/mcs/class/corlib/System.Reflection/ChangeLog index a8503a9c80e..980ecd3dc96 100644 --- a/mcs/class/corlib/System.Reflection/ChangeLog +++ b/mcs/class/corlib/System.Reflection/ChangeLog @@ -1,3 +1,11 @@ +2009-08-06 Rodrigo Kumpera <rkumpera@novell.com> + + * MonoGenericClass.cs (InflateType): Add support to inflate + generic method arguments. + + * MonoGenericClass.cs (GetMethod): Remove restriction + with generic methods. + 2009-08-05 Rodrigo Kumpera <rkumpera@novell.com> * MonoGenericClass.cs (FullName): mcs depends that FullName diff --git a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs index 572707194d0..4eb43c9fff5 100644 --- a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs +++ b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs @@ -78,9 +78,6 @@ namespace System.Reflection [MethodImplAttribute(MethodImplOptions.InternalCall)] extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic); - private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; @@ -111,6 +108,11 @@ namespace System.Reflection internal Type InflateType (Type type) { + return InflateType (type, null); + } + + internal Type InflateType (Type type, Type[] method_args) + { if (type == null) return null; if (!type.IsGenericParameter && !type.ContainsGenericParameters) @@ -118,23 +120,25 @@ namespace System.Reflection if (type.IsGenericParameter) { if (type.DeclaringMethod == null) return type_arguments [type.GenericParameterPosition]; + if (method_args != null) + return method_args [type.GenericParameterPosition]; return type; } if (type.IsPointer) - return InflateType (type.GetElementType ()).MakePointerType (); + return InflateType (type.GetElementType (), method_args).MakePointerType (); if (type.IsByRef) - return InflateType (type.GetElementType ()).MakeByRefType (); + return InflateType (type.GetElementType (), method_args).MakeByRefType (); if (type.IsArray) { if (type.GetArrayRank () > 1) - return InflateType (type.GetElementType ()).MakeArrayType (type.GetArrayRank ()); + return InflateType (type.GetElementType (), method_args).MakeArrayType (type.GetArrayRank ()); if (type.ToString ().EndsWith ("[*]")) /*FIXME, the reflection API doesn't offer a way around this*/ - return InflateType (type.GetElementType ()).MakeArrayType (1); - return InflateType (type.GetElementType ()).MakeArrayType (); + return InflateType (type.GetElementType (), method_args).MakeArrayType (1); + return InflateType (type.GetElementType (), method_args).MakeArrayType (); } Type[] args = type.GetGenericArguments (); for (int i = 0; i < args.Length; ++i) - args [i] = InflateType (args [i]); + args [i] = InflateType (args [i], method_args); Type gtd = type.IsGenericTypeDefinition ? type : type.GetGenericTypeDefinition (); return gtd.MakeGenericType (args); @@ -176,23 +180,12 @@ namespace System.Reflection if (!(fromNoninstanciated is MethodBuilder)) throw new InvalidOperationException ("Inflating non MethodBuilder objects is not supported: " + fromNoninstanciated.GetType ()); - if (fromNoninstanciated is MethodBuilder) { - MethodBuilder mb = (MethodBuilder)fromNoninstanciated; - - // FIXME: We can't yet handle creating generic instantiations of - // MethodOnTypeBuilderInst objects - // Also, mono_image_get_method_on_inst_token () can't handle generic - // methods - if (!mb.IsGenericMethodDefinition) { - if (methods == null) - methods = new Hashtable (); - if (!methods.ContainsKey (mb)) - methods [mb] = new MethodOnTypeBuilderInst (this, mb); - return (MethodInfo)methods [mb]; - } - } - - return GetCorrespondingInflatedMethod (fromNoninstanciated); + MethodBuilder mb = (MethodBuilder)fromNoninstanciated; + if (methods == null) + methods = new Hashtable (); + if (!methods.ContainsKey (mb)) + methods [mb] = new MethodOnTypeBuilderInst (this, mb); + return (MethodInfo)methods [mb]; } internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated) diff --git a/mcs/class/corlib/System/ChangeLog b/mcs/class/corlib/System/ChangeLog index a25a3e011dd..d567ab58913 100644 --- a/mcs/class/corlib/System/ChangeLog +++ b/mcs/class/corlib/System/ChangeLog @@ -1,3 +1,7 @@ +2009-08-06 Rodrigo Kumpera <rkumpera@novell.com> + + * Environment.cs: Bump corlib version. + 2009-08-04 Rodrigo Kumpera <rkumpera@novell.com> * Environment.cs: Bump corlib version. diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs index 975ff52bf8a..ef2bceec599 100644 --- a/mcs/class/corlib/System/Environment.cs +++ b/mcs/class/corlib/System/Environment.cs @@ -63,7 +63,7 @@ namespace System { * Changes which are already detected at runtime, like the addition * of icalls, do not require an increment. */ - private const int mono_corlib_version = 81; + private const int mono_corlib_version = 82; #if NET_2_0 [ComVisible (true)] diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog b/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog index ad576522abc..cc043f6eae9 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog +++ b/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog @@ -1,3 +1,8 @@ +2009-08-06 Rodrigo Kumpera <rkumpera@novell.com> + + * MethodOnTypeBuilderInstTest.cs: Add tests for + generic method instances over generic type instances. + 2009-08-04 Rodrigo Kumpera <rkumpera@novell.com> * MethodOnTypeBuilderInstTest.cs: Really fix the test. diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/MethodOnTypeBuilderInstTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/MethodOnTypeBuilderInstTest.cs index 9ff579f5c63..ee80a484d72 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/MethodOnTypeBuilderInstTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/MethodOnTypeBuilderInstTest.cs @@ -612,6 +612,78 @@ namespace MonoTests.System.Reflection.Emit 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"); + } } } |