Merge pull request #1218 from AndreyAkinshin/master
[mono.git] / mcs / class / corlib / System.Reflection / MonoMethod.cs
1 //
2 // MonoMethod.cs: The class used to represent methods from the mono runtime.
3 //
4 // Authors:
5 //   Paolo Molaro (lupus@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections.Generic;
33 using System.Globalization;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
36 using System.Runtime.Serialization;
37 #if !FULL_AOT_RUNTIME
38 using System.Reflection.Emit;
39 #endif
40 using System.Security;
41 using System.Threading;
42 using System.Text;
43 using System.Diagnostics;
44 using System.Diagnostics.Contracts;
45
46 namespace System.Reflection {
47         
48         internal struct MonoMethodInfo 
49         {
50 #pragma warning disable 649     
51                 private Type parent;
52                 private Type ret;
53                 internal MethodAttributes attrs;
54                 internal MethodImplAttributes iattrs;
55                 private CallingConventions callconv;
56 #pragma warning restore 649             
57
58                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
59                 static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
60                 
61                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
62                 static extern int get_method_attributes (IntPtr handle);
63                 
64                 internal static MonoMethodInfo GetMethodInfo (IntPtr handle)
65                 {
66                         MonoMethodInfo info;
67                         MonoMethodInfo.get_method_info (handle, out info);
68                         return info;
69                 }
70
71                 internal static Type GetDeclaringType (IntPtr handle)
72                 {
73                         return GetMethodInfo (handle).parent;
74                 }
75
76                 internal static Type GetReturnType (IntPtr handle)
77                 {
78                         return GetMethodInfo (handle).ret;
79                 }
80
81                 internal static MethodAttributes GetAttributes (IntPtr handle)
82                 {
83                         return (MethodAttributes)get_method_attributes (handle);
84                 }
85
86                 internal static CallingConventions GetCallingConvention (IntPtr handle)
87                 {
88                         return GetMethodInfo (handle).callconv;
89                 }
90
91                 internal static MethodImplAttributes GetMethodImplementationFlags (IntPtr handle)
92                 {
93                         return GetMethodInfo (handle).iattrs;
94                 }
95
96                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
97                 static extern ParameterInfo[] get_parameter_info (IntPtr handle, MemberInfo member);
98
99                 static internal ParameterInfo[] GetParametersInfo (IntPtr handle, MemberInfo member)
100                 {
101                         return get_parameter_info (handle, member);
102                 }
103
104                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
105                 static extern MarshalAsAttribute get_retval_marshal (IntPtr handle);
106
107                 static internal ParameterInfo GetReturnParameterInfo (MonoMethod method)
108                 {
109                         return ParameterInfo.New (GetReturnType (method.mhandle), method, get_retval_marshal (method.mhandle));
110                 }
111         };
112         
113         abstract class RuntimeMethodInfo : MethodInfo, ISerializable
114         {
115                 internal BindingFlags BindingFlags {
116                         get {
117                                 return 0;
118                         }
119                 }
120
121                 public override Module Module {
122                         get {
123                                 return GetRuntimeModule ();
124                         }
125                 }
126
127                 RuntimeType ReflectedTypeInternal {
128                         get {
129                                 return (RuntimeType) ReflectedType;
130                         }
131                 }
132
133         internal override string FormatNameAndSig (bool serialization)
134         {
135             // Serialization uses ToString to resolve MethodInfo overloads.
136             StringBuilder sbName = new StringBuilder(Name);
137
138             // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads.
139             // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString().
140             TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic;
141
142             if (IsGenericMethod)
143                 sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format));
144
145             sbName.Append("(");
146             ParameterInfo.FormatParameters (sbName, GetParametersNoCopy (), CallingConvention, serialization);
147             sbName.Append(")");
148
149             return sbName.ToString();
150         }
151
152         public override String ToString() 
153         {
154             return ReturnType.FormatTypeName() + " " + FormatNameAndSig(false);
155         }
156
157                 internal RuntimeModule GetRuntimeModule ()
158                 {
159                         return ((RuntimeType)DeclaringType).GetRuntimeModule();
160                 }
161
162         #region ISerializable Implementation
163         public void GetObjectData(SerializationInfo info, StreamingContext context)
164         {
165             if (info == null)
166                 throw new ArgumentNullException("info");
167             Contract.EndContractBlock();
168
169             MemberInfoSerializationHolder.GetSerializationInfo(
170                 info,
171                 Name,
172                 ReflectedTypeInternal,
173                 ToString(),
174                 SerializationToString(),
175                 MemberTypes.Method,
176                 IsGenericMethod & !IsGenericMethodDefinition ? GetGenericArguments() : null);
177         }
178
179         internal string SerializationToString()
180         {
181             return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
182         }
183         #endregion
184         }
185
186         /*
187          * Note: most of this class needs to be duplicated for the contructor, since
188          * the .NET reflection class hierarchy is so broken.
189          */
190         [Serializable()]
191         [StructLayout (LayoutKind.Sequential)]
192         internal class MonoMethod : RuntimeMethodInfo
193         {
194 #pragma warning disable 649
195                 internal IntPtr mhandle;
196                 string name;
197                 Type reftype;
198 #pragma warning restore 649
199
200                 internal MonoMethod () {
201                 }
202
203                 internal MonoMethod (RuntimeMethodHandle mhandle) {
204                         this.mhandle = mhandle.Value;
205                 }
206                 
207                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
208                 internal static extern string get_name (MethodBase method);
209
210                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
211                 internal static extern MonoMethod get_base_method (MonoMethod method, bool definition);
212
213                 public override MethodInfo GetBaseDefinition ()
214                 {
215                         return get_base_method (this, true);
216                 }
217
218                 internal override MethodInfo GetBaseMethod ()
219                 {
220                         return get_base_method (this, false);
221                 }
222
223                 public override ParameterInfo ReturnParameter {
224                         get {
225                                 return MonoMethodInfo.GetReturnParameterInfo (this);
226                         }
227                 }
228
229                 public override Type ReturnType {
230                         get {
231                                 return MonoMethodInfo.GetReturnType (mhandle);
232                         }
233                 }
234                 public override ICustomAttributeProvider ReturnTypeCustomAttributes { 
235                         get {
236                                 return MonoMethodInfo.GetReturnParameterInfo (this);
237                         }
238                 }
239                 
240                 public override MethodImplAttributes GetMethodImplementationFlags ()
241                 {
242                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
243                 }
244
245                 public override ParameterInfo[] GetParameters ()
246                 {
247                         var src = MonoMethodInfo.GetParametersInfo (mhandle, this);
248                         if (src.Length == 0)
249                                 return src;
250
251                         // Have to clone because GetParametersInfo icall returns cached value
252                         var dest = new ParameterInfo [src.Length];
253                         Array.FastCopy (src, 0, dest, 0, src.Length);
254                         return dest;
255                 }
256
257                 internal override ParameterInfo[] GetParametersInternal ()
258                 {
259                         return MonoMethodInfo.GetParametersInfo (mhandle, this);
260                 }
261                 
262                 internal override int GetParametersCount ()
263                 {
264                         return MonoMethodInfo.GetParametersInfo (mhandle, this).Length;
265                 }
266
267                 /*
268                  * InternalInvoke() receives the parameters correctly converted by the 
269                  * binder to match the types of the method signature.
270                  */
271                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
272                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
273
274                 [DebuggerHidden]
275                 [DebuggerStepThrough]
276                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
277                 {
278                         if (binder == null)
279                                 binder = Type.DefaultBinder;
280
281                         /*Avoid allocating an array every time*/
282                         ParameterInfo[] pinfo = GetParametersInternal ();
283                         ConvertValues (binder, parameters, pinfo, culture, invokeAttr);
284
285                         if (ContainsGenericParameters)
286                                 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
287
288                         Exception exc;
289                         object o = null;
290
291                         try {
292                                 // The ex argument is used to distinguish exceptions thrown by the icall
293                                 // from the exceptions thrown by the called method (which need to be
294                                 // wrapped in TargetInvocationException).
295                                 o = InternalInvoke (obj, parameters, out exc);
296                         } catch (ThreadAbortException) {
297                                 throw;
298 #if NET_2_1
299                         } catch (MethodAccessException) {
300                                 throw;
301 #endif
302                         } catch (Exception e) {
303                                 throw new TargetInvocationException (e);
304                         }
305
306                         if (exc != null)
307                                 throw exc;
308                         return o;
309                 }
310
311                 internal static void ConvertValues (Binder binder, object[] args, ParameterInfo[] pinfo, CultureInfo culture, BindingFlags invokeAttr)
312                 {
313                         if (args == null) {
314                                 if (pinfo.Length == 0)
315                                         return;
316
317                                 throw new TargetParameterCountException ();
318                         }
319
320                         if (pinfo.Length != args.Length)
321                                 throw new TargetParameterCountException ();
322
323                         for (int i = 0; i < args.Length; ++i) {
324                                 var arg = args [i];
325                                 var pi = pinfo [i];
326                                 if (arg == Type.Missing) {
327                                         if (pi.DefaultValue == System.DBNull.Value)
328                                                 throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),"parameters");
329
330                                         args [i] = pi.DefaultValue;
331                                         continue;
332                                 }
333
334                                 var rt = (RuntimeType) pi.ParameterType;
335                                 args [i] = rt.CheckValue (arg, binder, culture, invokeAttr);
336                         }
337                 }
338
339                 public override RuntimeMethodHandle MethodHandle { 
340                         get {
341                                 return new RuntimeMethodHandle (mhandle);
342                         } 
343                 }
344                 
345                 public override MethodAttributes Attributes { 
346                         get {
347                                 return MonoMethodInfo.GetAttributes (mhandle);
348                         } 
349                 }
350
351                 public override CallingConventions CallingConvention { 
352                         get {
353                                 return MonoMethodInfo.GetCallingConvention (mhandle);
354                         }
355                 }
356                 
357                 public override Type ReflectedType {
358                         get {
359                                 return reftype;
360                         }
361                 }
362                 public override Type DeclaringType {
363                         get {
364                                 return MonoMethodInfo.GetDeclaringType (mhandle);
365                         }
366                 }
367                 public override string Name {
368                         get {
369                                 if (name != null)
370                                         return name;
371                                 return get_name (this);
372                         }
373                 }
374                 
375                 public override bool IsDefined (Type attributeType, bool inherit) {
376                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
377                 }
378
379                 public override object[] GetCustomAttributes( bool inherit) {
380                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
381                 }
382                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
383                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
384                 }
385
386                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
387                 internal extern void GetPInvoke (out PInvokeAttributes flags, out string entryPoint, out string dllName);
388
389                 internal object[] GetPseudoCustomAttributes ()
390                 {
391                         int count = 0;
392
393                         /* MS.NET doesn't report MethodImplAttribute */
394
395                         MonoMethodInfo info = MonoMethodInfo.GetMethodInfo (mhandle);
396                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
397                                 count ++;
398                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
399                                 count ++;
400                         
401                         if (count == 0)
402                                 return null;
403                         object[] attrs = new object [count];
404                         count = 0;
405
406                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
407                                 attrs [count ++] = new PreserveSigAttribute ();
408                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
409                                 attrs [count ++] = DllImportAttribute.GetCustomAttribute (this);
410                         }
411
412                         return attrs;
413                 }
414
415                 public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
416                 {
417                         if (methodInstantiation == null)
418                                 throw new ArgumentNullException ("methodInstantiation");
419
420                         if (!IsGenericMethodDefinition)
421                                 throw new InvalidOperationException ("not a generic method definition");
422
423                         /*FIXME add GetGenericArgumentsLength() internal vcall to speed this up*/
424                         if (GetGenericArguments ().Length != methodInstantiation.Length)
425                                 throw new ArgumentException ("Incorrect length");
426
427                         bool hasUserType = false;
428                         foreach (Type type in methodInstantiation) {
429                                 if (type == null)
430                                         throw new ArgumentNullException ();
431                                 if (!(type is MonoType))
432                                         hasUserType = true;
433                         }
434
435                         if (hasUserType)
436 #if FULL_AOT_RUNTIME
437                                 throw new NotSupportedException ("User types are not supported under full aot");
438 #else
439                                 return new MethodOnTypeBuilderInst (this, methodInstantiation);
440 #endif
441
442                         MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
443                         if (ret == null)
444                                 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length));
445                         return ret;
446                 }
447
448                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
449                 extern MethodInfo MakeGenericMethod_impl (Type [] types);
450
451                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
452                 public override extern Type [] GetGenericArguments ();
453
454                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
455                 extern MethodInfo GetGenericMethodDefinition_impl ();
456
457                 public override MethodInfo GetGenericMethodDefinition ()
458                 {
459                         MethodInfo res = GetGenericMethodDefinition_impl ();
460                         if (res == null)
461                                 throw new InvalidOperationException ();
462
463                         return res;
464                 }
465
466                 public override extern bool IsGenericMethodDefinition {
467                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
468                         get;
469                 }
470
471                 public override extern bool IsGenericMethod {
472                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
473                         get;
474                 }
475
476                 public override bool ContainsGenericParameters {
477                         get {
478                                 if (IsGenericMethod) {
479                                         foreach (Type arg in GetGenericArguments ())
480                                                 if (arg.ContainsGenericParameters)
481                                                         return true;
482                                 }
483                                 return DeclaringType.ContainsGenericParameters;
484                         }
485                 }
486
487                 public override MethodBody GetMethodBody () {
488                         return GetMethodBody (mhandle);
489                 }
490
491                 public override IList<CustomAttributeData> GetCustomAttributesData () {
492                         return CustomAttributeData.GetCustomAttributes (this);
493                 }
494
495                 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
496                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
497                 public extern int get_core_clr_security_level ();
498
499                 public override bool IsSecurityTransparent {
500                         get { return get_core_clr_security_level () == 0; }
501                 }
502
503                 public override bool IsSecurityCritical {
504                         get { return get_core_clr_security_level () > 0; }
505                 }
506
507                 public override bool IsSecuritySafeCritical {
508                         get { return get_core_clr_security_level () == 1; }
509                 }
510         }
511         
512
513         abstract class RuntimeConstructorInfo : ConstructorInfo, ISerializable
514         {
515                 public override Module Module {
516                         get {
517                                 return GetRuntimeModule ();
518                         }
519                 }
520
521                 internal RuntimeModule GetRuntimeModule ()
522                 {
523                         return RuntimeTypeHandle.GetModule((RuntimeType)DeclaringType);
524                 }
525
526                 internal BindingFlags BindingFlags {
527                         get {
528                                 return 0;
529                         }
530                 }
531
532                 RuntimeType ReflectedTypeInternal {
533                         get {
534                                 return (RuntimeType) ReflectedType;
535                         }
536                 }
537
538         #region ISerializable Implementation
539         public void GetObjectData(SerializationInfo info, StreamingContext context)
540         {
541             if (info == null)
542                 throw new ArgumentNullException("info");
543             Contract.EndContractBlock();
544             MemberInfoSerializationHolder.GetSerializationInfo(
545                 info,
546                 Name,
547                 ReflectedTypeInternal,
548                 ToString(),
549                 SerializationToString(),
550                 MemberTypes.Constructor,
551                 null);
552         }
553
554         internal string SerializationToString()
555         {
556             // We don't need the return type for constructors.
557             return FormatNameAndSig(true);
558         }
559
560                 internal void SerializationInvoke (Object target, SerializationInfo info, StreamingContext context)
561                 {
562                         Invoke (target, new object[] { info, context });
563                 }
564        #endregion
565         }
566
567         [Serializable()]
568         [StructLayout (LayoutKind.Sequential)]
569         internal class MonoCMethod : RuntimeConstructorInfo
570         {
571 #pragma warning disable 649             
572                 internal IntPtr mhandle;
573                 string name;
574                 Type reftype;
575 #pragma warning restore 649             
576                 
577                 public override MethodImplAttributes GetMethodImplementationFlags ()
578                 {
579                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
580                 }
581
582                 public override ParameterInfo[] GetParameters ()
583                 {
584                         return MonoMethodInfo.GetParametersInfo (mhandle, this);
585                 }
586
587                 internal override ParameterInfo[] GetParametersInternal ()
588                 {
589                         return MonoMethodInfo.GetParametersInfo (mhandle, this);
590                 }               
591
592                 internal override int GetParametersCount ()
593                 {
594                         var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
595                         return pi == null ? 0 : pi.Length;
596                 }
597
598                 /*
599                  * InternalInvoke() receives the parameters correctly converted by the binder
600                  * to match the types of the method signature.
601                  */
602                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
603                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
604
605                 [DebuggerHidden]
606                 [DebuggerStepThrough]
607                 public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) 
608                 {
609                         if (obj == null) {
610                                 if (!IsStatic)
611                                         throw new TargetException ("Instance constructor requires a target");
612                         } else if (!DeclaringType.IsInstanceOfType (obj)) {
613                                 throw new TargetException ("Constructor does not match target type");                           
614                         }
615
616                         return DoInvoke (obj, invokeAttr, binder, parameters, culture);
617                 }
618
619                 object DoInvoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) 
620                 {
621                         if (binder == null)
622                                 binder = Type.DefaultBinder;
623
624                         ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
625
626                         MonoMethod.ConvertValues (binder, parameters, pinfo, culture, invokeAttr);
627
628                         if (obj == null && DeclaringType.ContainsGenericParameters)
629                                 throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
630
631                         if ((invokeAttr & BindingFlags.CreateInstance) != 0 && DeclaringType.IsAbstract) {
632                                 throw new MemberAccessException (String.Format ("Cannot create an instance of {0} because it is an abstract class", DeclaringType));
633                         }
634
635                         return InternalInvoke (obj, parameters);
636                 }
637
638                 public object InternalInvoke (object obj, object[] parameters)
639                 {
640                         Exception exc;
641                         object o = null;
642
643                         try {
644                                 o = InternalInvoke (obj, parameters, out exc);
645 #if NET_2_1
646                         } catch (MethodAccessException) {
647                                 throw;
648 #endif
649                         } catch (Exception e) {
650                                 throw new TargetInvocationException (e);
651                         }
652
653                         if (exc != null)
654                                 throw exc;
655
656                         return obj == null ? o : null;
657                 }
658
659                 [DebuggerHidden]
660                 [DebuggerStepThrough]
661                 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
662                 {
663                         return DoInvoke (null, invokeAttr, binder, parameters, culture);
664                 }
665
666                 public override RuntimeMethodHandle MethodHandle { 
667                         get {
668                                 return new RuntimeMethodHandle (mhandle);
669                         } 
670                 }
671                 
672                 public override MethodAttributes Attributes { 
673                         get {
674                                 return MonoMethodInfo.GetAttributes (mhandle);
675                         } 
676                 }
677
678                 public override CallingConventions CallingConvention { 
679                         get {
680                                 return MonoMethodInfo.GetCallingConvention (mhandle);
681                         }
682                 }
683                 
684                 public override bool ContainsGenericParameters {
685                         get {
686                                 return DeclaringType.ContainsGenericParameters;
687                         }
688                 }
689
690                 public override Type ReflectedType {
691                         get {
692                                 return reftype;
693                         }
694                 }
695                 public override Type DeclaringType {
696                         get {
697                                 return MonoMethodInfo.GetDeclaringType (mhandle);
698                         }
699                 }
700                 public override string Name {
701                         get {
702                                 if (name != null)
703                                         return name;
704                                 return MonoMethod.get_name (this);
705                         }
706                 }
707
708                 public override bool IsDefined (Type attributeType, bool inherit) {
709                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
710                 }
711
712                 public override object[] GetCustomAttributes( bool inherit) {
713                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
714                 }
715
716                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
717                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
718                 }
719
720                 public override MethodBody GetMethodBody () {
721                         return GetMethodBody (mhandle);
722                 }
723
724                 public override string ToString () {
725                         StringBuilder sb = new StringBuilder ();
726                         sb.Append ("Void ");
727                         sb.Append (Name);
728                         sb.Append ("(");
729                         ParameterInfo[] p = GetParameters ();
730                         for (int i = 0; i < p.Length; ++i) {
731                                 if (i > 0)
732                                         sb.Append (", ");
733                                 sb.Append (p[i].ParameterType.Name);
734                         }
735                         if (CallingConvention == CallingConventions.Any)
736                                 sb.Append (", ...");
737                         sb.Append (")");
738                         return sb.ToString ();
739                 }
740
741                 public override IList<CustomAttributeData> GetCustomAttributesData () {
742                         return CustomAttributeData.GetCustomAttributes (this);
743                 }
744         }
745 }