Merge pull request #1898 from alexanderkyte/debugger_variable_reflection
[mono.git] / mcs / class / corlib / System.Reflection.Emit / MethodOnTypeBuilderInst.cs
index 65246ea665e648274394ba6602f0ecd28231cf4f..41a79eb6d7e560e48797c385a6804d1f51070533 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#if !FULL_AOT_RUNTIME
 using System;
 using System.Globalization;
 using System.Reflection;
 using System.Text;
+using System.Runtime.InteropServices;
+
 
 namespace System.Reflection.Emit
 {
        /*
         * This class represents a method of an instantiation of a generic type builder.
         */
+       [StructLayout (LayoutKind.Sequential)]
        internal class MethodOnTypeBuilderInst : MethodInfo
        {
                #region Keep in sync with object-internals.h
                Type instantiation;
-               internal MethodBuilder base_method; /*This is the base method definition, it must be non-inflated and belong to a non-inflated type.*/
+               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;
 
-               public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodBuilder base_method)
+               public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodInfo base_method)
                {
                        this.instantiation = instantiation;
                        this.base_method = base_method;
@@ -61,6 +65,33 @@ 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);
+                       if (base_method != method)
+                               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)
@@ -69,10 +100,6 @@ namespace System.Reflection.Emit
                        return instantiation.GetGenericArguments ();
                }
 
-               internal bool IsCompilerContext {
-                       get { return ((ModuleBuilder)base_method.Module).assemblyb.IsCompilerContext; }
-               }
-
                //
                // MemberInfo members
                //
@@ -97,9 +124,13 @@ namespace System.Reflection.Emit
 
                public override Type ReturnType {
                        get { 
-                               if (!IsCompilerContext)
-                                       return base_method.ReturnType;
-                               return MonoGenericClass.InflateType (base_method.ReturnType, GetTypeArgs (), method_arguments);
+                               return base_method.ReturnType;
+                       }
+               }
+
+               public override Module Module {
+                       get {
+                               return base_method.Module;
                        }
                }
 
@@ -125,14 +156,6 @@ namespace System.Reflection.Emit
                         sb.Append (" ");
                         sb.Append (base_method.Name);
                         sb.Append ("(");
-                        if (IsCompilerContext) {
-                                ParameterInfo [] par = GetParameters ();
-                                for (int i = 0; i < par.Length; ++i) {
-                                       if (i > 0)
-                                               sb.Append (", ");
-                                       sb.Append (par [i].ParameterType);
-                                }
-                       }
                         sb.Append (")");
                         return sb.ToString ();
                }
@@ -147,28 +170,23 @@ namespace System.Reflection.Emit
 
                public override ParameterInfo [] GetParameters ()
                {
-                       if (!IsCompilerContext)
-                               throw new NotSupportedException ();
+                       return GetParametersInternal ();
+               }
 
-                       ParameterInfo [] res = new ParameterInfo [base_method.parameters.Length];
-                       for (int i = 0; i < base_method.parameters.Length; i++) {
-                               Type type = MonoGenericClass.InflateType (base_method.parameters [i], GetTypeArgs (), method_arguments);
-                               res [i] = new ParameterInfo (base_method.pinfo == null ? null : base_method.pinfo [i + 1], type, this, i + 1);
-                       }
-                       return res;
+               internal override ParameterInfo [] GetParametersInternal ()
+               {
+                       throw new NotSupportedException ();
                }
 
                public override int MetadataToken {
                        get {
-                               if (!IsCompilerContext)
-                                       return base.MetadataToken;
-                               return base_method.MetadataToken;
+                               return base.MetadataToken;
                        }
                }
 
-               internal override int GetParameterCount ()
+               internal override int GetParametersCount ()
                {
-                       return base_method.GetParameterCount ();
+                       return base_method.GetParametersCount ();
                }
 
                public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
@@ -194,30 +212,30 @@ namespace System.Reflection.Emit
                        }
                }
 
-               public override MethodInfo MakeGenericMethod (params Type [] typeArguments)
+               public override MethodInfo MakeGenericMethod (params Type [] methodInstantiation)
                {
-                       if (base_method.generic_params == null || method_arguments != null)
-                               throw new NotSupportedException (); //FIXME is this the right exception?
+                       if (!base_method.IsGenericMethodDefinition || (method_arguments != null))
+                               throw new InvalidOperationException ("Method is not a generic method definition");
 
-                       if (typeArguments == null)
-                               throw new ArgumentNullException ("typeArguments");
+                       if (methodInstantiation == null)
+                               throw new ArgumentNullException ("methodInstantiation");
 
-                       foreach (Type t in typeArguments) {
-                               if (t == null)
-                                       throw new ArgumentNullException ("typeArguments");
-                       }
+                       if (base_method.GetGenericArguments ().Length != methodInstantiation.Length)
+                               throw new ArgumentException ("Incorrect length", "methodInstantiation");
 
-                       if (base_method.generic_params.Length != typeArguments.Length)
-                               throw new ArgumentException ("Invalid argument array length");
+                       foreach (Type type in methodInstantiation) {
+                               if (type == null)
+                                       throw new ArgumentNullException ("methodInstantiation");
+                       }
 
-                       return new MethodOnTypeBuilderInst (this, typeArguments);
+                       return new MethodOnTypeBuilderInst (this, methodInstantiation);
                }
 
                public override Type [] GetGenericArguments ()
                {
-                       if (base_method.generic_params == null)
+                       if (!base_method.IsGenericMethodDefinition)
                                return null;
-                       Type[] source = method_arguments ?? base_method.generic_params;
+                       Type[] source = method_arguments ?? base_method.GetGenericArguments ();
                        Type[] result = new Type [source.Length];
                        source.CopyTo (result, 0);
                        return result;
@@ -225,12 +243,14 @@ 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 {
                        get {
-                               if (base_method.generic_params == null)
+                               if (base_method.ContainsGenericParameters)
+                                       return true;
+                               if (!base_method.IsGenericMethodDefinition)
                                        throw new NotSupportedException ();
                                if (method_arguments == null)
                                        return true;
@@ -244,13 +264,13 @@ namespace System.Reflection.Emit
 
                public override bool IsGenericMethodDefinition {
                        get {
-                               return base_method.generic_params != null && method_arguments == null;
+                               return base_method.IsGenericMethodDefinition && method_arguments == null;
                        }
                }
 
                public override bool IsGenericMethod {
                        get {
-                               return base_method.generic_params != null;
+                               return base_method.IsGenericMethodDefinition;
                        }
                }
 
@@ -271,3 +291,4 @@ namespace System.Reflection.Emit
        }
 }
 
+#endif