2009-12-08 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 8 Dec 2009 14:07:22 +0000 (14:07 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 8 Dec 2009 14:07:22 +0000 (14:07 -0000)
* MonoMethod.cs (MakeGenericMethod): If any of the arguments is
a non system type, inflate to a MethodOnTypeBuilderInst.

2009-12-08 Rodrigo Kumpera  <rkumpera@novell.com>

* MethodOnTypeBuilderInst.cs: Add new constructor that takes a MethodInfo
as base method. Change how compiler context is calculated to take the
instantiation vector into account.

svn path=/trunk/mcs/; revision=147852

mcs/class/corlib/System.Reflection.Emit/ChangeLog
mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs
mcs/class/corlib/System.Reflection/ChangeLog
mcs/class/corlib/System.Reflection/MonoMethod.cs

index a5e9cb5193db7a18aa53ff9538a8647f121903b8..41ed1cfd7e6b2684b9db6272238198f269ba11b5 100644 (file)
@@ -1,3 +1,9 @@
+2009-12-08 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * MethodOnTypeBuilderInst.cs: Add new constructor that takes a MethodInfo
+       as base method. Change how compiler context is calculated to take the
+       instantiation vector into account.
+
 2009-12-08 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * MethodOnTypeBuilderInst.cs: Change base_method type from MethodBuilder to
index 11873f28399b3b291b0aee73e9da62ee5039b888..6d38391fa88bf21d5bd5bfce93d9399633697097 100644 (file)
@@ -43,8 +43,9 @@ namespace System.Reflection.Emit
                Type instantiation;
                MethodInfo base_method; /*This is the base method definition, it must be non-inflated and belong to a non-inflated type.*/
                Type[] method_arguments;
-               MethodOnTypeBuilderInst generic_method_definition;
                #endregion
+               MethodInfo generic_method_definition;
+               int is_compiler_context = -1;
 
                public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodBuilder base_method)
                {
@@ -69,6 +70,32 @@ namespace System.Reflection.Emit
                        this.generic_method_definition = gmd;
                }
 
+               internal MethodOnTypeBuilderInst (MethodInfo method, Type[] typeArguments)
+               {
+                       this.instantiation = method.DeclaringType;
+                       this.base_method = ExtractBaseMethod (method);
+                       this.method_arguments = new Type [typeArguments.Length];
+                       typeArguments.CopyTo (this.method_arguments, 0);
+                       this.generic_method_definition = method;
+               }
+
+               static MethodInfo ExtractBaseMethod (MethodInfo info)
+               {
+                       if (info is MethodBuilder)
+                               return info;
+                       if (info is MethodOnTypeBuilderInst)
+                               return ((MethodOnTypeBuilderInst)info).base_method;
+
+                       if (info.IsGenericMethod)
+                               info = info.GetGenericMethodDefinition ();
+
+                       Type t = info.DeclaringType;
+                       if (!t.IsGenericType || t.IsGenericTypeDefinition)
+                               return info;
+
+                       return (MethodInfo)t.Module.ResolveMethod (info.MetadataToken);
+               }
+
                internal Type[] GetTypeArgs ()
                {
                        if (!instantiation.IsGenericType || instantiation.IsGenericParameter)
@@ -78,7 +105,18 @@ namespace System.Reflection.Emit
                }
 
                internal bool IsCompilerContext {
-                       get { return instantiation.IsCompilerContext; }
+                       get {
+                               if (is_compiler_context == -1) {
+                                       bool is_cc = false;
+                                       is_cc |= instantiation.IsCompilerContext;
+                                       if (!is_cc && method_arguments != null) {
+                                               foreach (Type t in method_arguments)
+                                                       is_cc |= t.IsCompilerContext;
+                                       }
+                                       is_compiler_context = is_cc ? 1 : 0;
+                               }
+                               return is_compiler_context == 1;
+                       }
                }
 
                //
@@ -244,7 +282,7 @@ namespace System.Reflection.Emit
 
                public override MethodInfo GetGenericMethodDefinition ()
                {
-                       return (MethodInfo)generic_method_definition ?? base_method;
+                       return generic_method_definition ?? base_method;
                }
 
                public override bool ContainsGenericParameters {
index f330b574091145a7fb540059ab240533a0053226..03118bd0e177193ec3e053f26081595ddbc91ec5 100644 (file)
@@ -1,3 +1,8 @@
+2009-12-08 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * MonoMethod.cs (MakeGenericMethod): If any of the arguments is
+       a non system type, inflate to a MethodOnTypeBuilderInst.
+
 2009-12-08 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * ParameterInfo.cs: Add constructor that takes an array of ParameterInfo
index 49d78bd99b0cabc790c51bba66bc7cad4dec67b4..482ef46727a4c7cee1851f6b87b812d25c5654e9 100644 (file)
@@ -364,9 +364,24 @@ namespace System.Reflection {
                {
                        if (methodInstantiation == null)
                                throw new ArgumentNullException ("methodInstantiation");
-                       foreach (Type type in methodInstantiation)
+
+                       if (!IsGenericMethodDefinition)
+                               throw new InvalidOperationException ("not a generic method definition");
+
+                       /*FIXME add GetGenericArgumentsLength() internal vcall to speed this up*/
+                       if (GetGenericArguments ().Length != methodInstantiation.Length)
+                               throw new ArgumentException ("Incorrect length");
+
+                       bool hasUserType = false;
+                       foreach (Type type in methodInstantiation) {
                                if (type == null)
                                        throw new ArgumentNullException ();
+                               if (!(type is MonoType))
+                                       hasUserType = true;
+                       }
+
+                       if (hasUserType)
+                               return new MethodOnTypeBuilderInst (this, methodInstantiation);
 
                        MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
                        if (ret == null)