X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection.Emit%2FMethodOnTypeBuilderInst.cs;h=1384f9971e4a46b4a89b19e6cabc39d6ea05932d;hb=3673d051fbd6ac16b184f51efcb352cfc4a1481c;hp=a1b2dd6739bdc203bfe70792d15d39781b5a46f1;hpb=8efe5cab3eab18bef5ac682dc66904c4da1f7b9b;p=mono.git diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs index a1b2dd6739b..1384f9971e4 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs @@ -27,28 +27,77 @@ // 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; -#if NET_2_0 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 - MonoGenericClass instantiation; - internal MethodBuilder mb; + 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; #endregion + MethodInfo generic_method_definition; - public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodBuilder mb) + public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodInfo base_method) { this.instantiation = instantiation; - this.mb = mb; + this.base_method = base_method; + } + + internal MethodOnTypeBuilderInst (MethodOnTypeBuilderInst gmd, Type[] typeArguments) + { + this.instantiation = gmd.instantiation; + this.base_method = gmd.base_method; + this.method_arguments = new Type [typeArguments.Length]; + typeArguments.CopyTo (this.method_arguments, 0); + 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) + return null; + + return instantiation.GetGenericArguments (); } // @@ -63,7 +112,7 @@ namespace System.Reflection.Emit public override string Name { get { - return mb.Name; + return base_method.Name; } } @@ -75,9 +124,7 @@ namespace System.Reflection.Emit public override Type ReturnType { get { - if (!((ModuleBuilder)mb.Module).assemblyb.IsCompilerContext) - return mb.ReturnType; - return instantiation.InflateType (mb.ReturnType); + return base_method.ReturnType; } } @@ -96,39 +143,44 @@ namespace System.Reflection.Emit throw new NotSupportedException (); } + public override string ToString () + { + //IEnumerable`1 get_Item(TKey) + StringBuilder sb = new StringBuilder (ReturnType.ToString ()); + sb.Append (" "); + sb.Append (base_method.Name); + sb.Append ("("); + sb.Append (")"); + return sb.ToString (); + } // // MethodBase members // public override MethodImplAttributes GetMethodImplementationFlags () { - return mb.GetMethodImplementationFlags (); + return base_method.GetMethodImplementationFlags (); } public override ParameterInfo [] GetParameters () { - if (!((ModuleBuilder)mb.Module).assemblyb.IsCompilerContext) - throw new NotSupportedException (); + return GetParametersInternal (); + } - ParameterInfo [] res = new ParameterInfo [mb.parameters.Length]; - for (int i = 0; i < mb.parameters.Length; i++) { - Type type = instantiation.InflateType (mb.parameters [i]); - res [i] = new ParameterInfo (mb.pinfo == null ? null : mb.pinfo [i + 1], type, this, i + 1); - } - return res; + internal override ParameterInfo [] GetParametersInternal () + { + throw new NotSupportedException (); } public override int MetadataToken { get { - if (!((ModuleBuilder)mb.Module).assemblyb.IsCompilerContext) - return base.MetadataToken; - return mb.MetadataToken; + return base.MetadataToken; } } - internal override int GetParameterCount () + internal override int GetParametersCount () { - return mb.GetParameterCount (); + return base_method.GetParametersCount (); } public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) @@ -144,44 +196,75 @@ namespace System.Reflection.Emit public override MethodAttributes Attributes { get { - return mb.Attributes; + return base_method.Attributes; } } public override CallingConventions CallingConvention { get { - return mb.CallingConvention; + return base_method.CallingConvention; + } + } + + public override MethodInfo MakeGenericMethod (params Type [] methodInstantiation) + { + if (!base_method.IsGenericMethodDefinition || (method_arguments != null)) + throw new InvalidOperationException ("Method is not a generic method definition"); + + if (methodInstantiation == null) + throw new ArgumentNullException ("methodInstantiation"); + + if (base_method.GetGenericArguments ().Length != methodInstantiation.Length) + throw new ArgumentException ("Incorrect length", "methodInstantiation"); + + foreach (Type type in methodInstantiation) { + if (type == null) + throw new ArgumentNullException ("methodInstantiation"); } + + return new MethodOnTypeBuilderInst (this, methodInstantiation); } public override Type [] GetGenericArguments () { - //FIXME test that once we support generic methods - return mb.GetGenericArguments (); + if (!base_method.IsGenericMethodDefinition) + return null; + Type[] source = method_arguments ?? base_method.GetGenericArguments (); + Type[] result = new Type [source.Length]; + source.CopyTo (result, 0); + return result; } public override MethodInfo GetGenericMethodDefinition () { - return mb; + return generic_method_definition ?? base_method; } public override bool ContainsGenericParameters { get { - throw new NotSupportedException (); + if (base_method.ContainsGenericParameters) + return true; + if (!base_method.IsGenericMethodDefinition) + 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 base_method.IsGenericMethodDefinition && method_arguments == null; } } public override bool IsGenericMethod { get { - //FIXME test that once we support generic methods - return mb.IsGenericMethod; + return base_method.IsGenericMethodDefinition; } }