Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / corlib / System.Reflection / MonoMethod.cs
1 //
2 // System.Reflection/MonoMethod.cs
3 // The class used to represent methods from the mono runtime.
4 //
5 // Author:
6 //   Paolo Molaro (lupus@ximian.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.Collections.Generic;
32 using System.Globalization;
33 using System.Runtime.CompilerServices;
34 using System.Runtime.InteropServices;
35 using System.Runtime.Serialization;
36 using System.Reflection.Emit;
37 using System.Security;
38 using System.Threading;
39 using System.Text;
40 using System.Diagnostics;
41
42 namespace System.Reflection {
43         
44         internal struct MonoMethodInfo 
45         {
46 #pragma warning disable 649     
47                 private Type parent;
48                 private Type ret;
49                 internal MethodAttributes attrs;
50                 internal MethodImplAttributes iattrs;
51                 private CallingConventions callconv;
52 #pragma warning restore 649             
53
54                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
55                 static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
56                 
57                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
58                 static extern int get_method_attributes (IntPtr handle);
59                 
60                 internal static MonoMethodInfo GetMethodInfo (IntPtr handle)
61                 {
62                         MonoMethodInfo info;
63                         MonoMethodInfo.get_method_info (handle, out info);
64                         return info;
65                 }
66
67                 internal static Type GetDeclaringType (IntPtr handle)
68                 {
69                         return GetMethodInfo (handle).parent;
70                 }
71
72                 internal static Type GetReturnType (IntPtr handle)
73                 {
74                         return GetMethodInfo (handle).ret;
75                 }
76
77                 internal static MethodAttributes GetAttributes (IntPtr handle)
78                 {
79                         return (MethodAttributes)get_method_attributes (handle);
80                 }
81
82                 internal static CallingConventions GetCallingConvention (IntPtr handle)
83                 {
84                         return GetMethodInfo (handle).callconv;
85                 }
86
87                 internal static MethodImplAttributes GetMethodImplementationFlags (IntPtr handle)
88                 {
89                         return GetMethodInfo (handle).iattrs;
90                 }
91
92                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
93                 static extern ParameterInfo[] get_parameter_info (IntPtr handle, MemberInfo member);
94
95                 static internal ParameterInfo[] GetParametersInfo (IntPtr handle, MemberInfo member)
96                 {
97                         return get_parameter_info (handle, member);
98                 }
99
100                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
101                 static extern UnmanagedMarshal get_retval_marshal (IntPtr handle);
102
103                 static internal ParameterInfo GetReturnParameterInfo (MonoMethod method)
104                 {
105                         return new ParameterInfo (GetReturnType (method.mhandle), method, get_retval_marshal (method.mhandle));
106                 }
107         };
108         
109         /*
110          * Note: most of this class needs to be duplicated for the contructor, since
111          * the .NET reflection class hierarchy is so broken.
112          */
113         [Serializable()]
114         [StructLayout (LayoutKind.Sequential)]
115         internal class MonoMethod : MethodInfo, ISerializable
116         {
117 #pragma warning disable 649
118                 internal IntPtr mhandle;
119                 string name;
120                 Type reftype;
121 #pragma warning restore 649
122
123                 internal MonoMethod () {
124                 }
125
126                 internal MonoMethod (RuntimeMethodHandle mhandle) {
127                         this.mhandle = mhandle.Value;
128                 }
129                 
130                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
131                 internal static extern string get_name (MethodBase method);
132
133                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
134                 internal static extern MonoMethod get_base_method (MonoMethod method, bool definition);
135
136                 public override MethodInfo GetBaseDefinition ()
137                 {
138                         return get_base_method (this, true);
139                 }
140
141                 internal override MethodInfo GetBaseMethod ()
142                 {
143                         return get_base_method (this, false);
144                 }
145
146                 public override ParameterInfo ReturnParameter {
147                         get {
148                                 return MonoMethodInfo.GetReturnParameterInfo (this);
149                         }
150                 }
151
152                 public override Type ReturnType {
153                         get {
154                                 return MonoMethodInfo.GetReturnType (mhandle);
155                         }
156                 }
157                 public override ICustomAttributeProvider ReturnTypeCustomAttributes { 
158                         get {
159                                 return MonoMethodInfo.GetReturnParameterInfo (this);
160                         }
161                 }
162                 
163                 public override MethodImplAttributes GetMethodImplementationFlags ()
164                 {
165                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
166                 }
167
168                 public override ParameterInfo[] GetParameters ()
169                 {
170                         ParameterInfo[] src = MonoMethodInfo.GetParametersInfo (mhandle, this);
171                         ParameterInfo[] res = new ParameterInfo [src.Length];
172                         src.CopyTo (res, 0);
173                         return res;
174                 }
175                 
176                 internal override int GetParameterCount ()
177                 {
178                         var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
179                         return pi == null ? 0 : pi.Length;
180                 }
181
182                 /*
183                  * InternalInvoke() receives the parameters correctly converted by the 
184                  * binder to match the types of the method signature.
185                  */
186                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
187                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
188
189                 [DebuggerHidden]
190                 [DebuggerStepThrough]
191                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
192                 {
193                         if (binder == null)
194                                 binder = Binder.DefaultBinder;
195                         /*Avoid allocating an array every time*/
196                         ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
197
198                         if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
199                                 throw new TargetParameterCountException ("parameters do not match signature");
200                         
201                         if ((invokeAttr & BindingFlags.ExactBinding) == 0) {
202                                 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
203                                         throw new ArgumentException ("failed to convert parameters");
204                         } else {
205                                 for (int i = 0; i < pinfo.Length; i++)
206                                         if (parameters[i].GetType() != pinfo[i].ParameterType)
207                                                 throw new ArgumentException ("parameters do not match signature");
208                         }
209
210 #if !NET_2_1
211                         if (SecurityManager.SecurityEnabled) {
212                                 // sadly Attributes doesn't tell us which kind of security action this is so
213                                 // we must do it the hard way - and it also means that we can skip calling
214                                 // Attribute (which is another an icall)
215                                 SecurityManager.ReflectedLinkDemandInvoke (this);
216                         }
217 #endif
218
219                         if (ContainsGenericParameters)
220                                 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
221
222                         Exception exc;
223                         object o = null;
224
225                         try {
226                                 // The ex argument is used to distinguish exceptions thrown by the icall
227                                 // from the exceptions thrown by the called method (which need to be
228                                 // wrapped in TargetInvocationException).
229                                 o = InternalInvoke (obj, parameters, out exc);
230                         } catch (ThreadAbortException) {
231                                 throw;
232 #if NET_2_1
233                         } catch (MethodAccessException) {
234                                 throw;
235 #endif
236                         } catch (Exception e) {
237                                 throw new TargetInvocationException (e);
238                         }
239
240                         if (exc != null)
241                                 throw exc;
242                         return o;
243                 }
244
245                 public override RuntimeMethodHandle MethodHandle { 
246                         get {
247                                 return new RuntimeMethodHandle (mhandle);
248                         } 
249                 }
250                 
251                 public override MethodAttributes Attributes { 
252                         get {
253                                 return MonoMethodInfo.GetAttributes (mhandle);
254                         } 
255                 }
256
257                 public override CallingConventions CallingConvention { 
258                         get {
259                                 return MonoMethodInfo.GetCallingConvention (mhandle);
260                         }
261                 }
262                 
263                 public override Type ReflectedType {
264                         get {
265                                 return reftype;
266                         }
267                 }
268                 public override Type DeclaringType {
269                         get {
270                                 return MonoMethodInfo.GetDeclaringType (mhandle);
271                         }
272                 }
273                 public override string Name {
274                         get {
275                                 if (name != null)
276                                         return name;
277                                 return get_name (this);
278                         }
279                 }
280                 
281                 public override bool IsDefined (Type attributeType, bool inherit) {
282                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
283                 }
284
285                 public override object[] GetCustomAttributes( bool inherit) {
286                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
287                 }
288                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
289                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
290                 }
291
292                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
293                 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
294
295                 internal object[] GetPseudoCustomAttributes ()
296                 {
297                         int count = 0;
298
299                         /* MS.NET doesn't report MethodImplAttribute */
300
301                         MonoMethodInfo info = MonoMethodInfo.GetMethodInfo (mhandle);
302                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
303                                 count ++;
304                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
305                                 count ++;
306                         
307                         if (count == 0)
308                                 return null;
309                         object[] attrs = new object [count];
310                         count = 0;
311
312                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
313                                 attrs [count ++] = new PreserveSigAttribute ();
314                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
315                                 DllImportAttribute attr = GetDllImportAttribute (mhandle);
316                                 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
317                                         attr.PreserveSig = true;
318                                 attrs [count ++] = attr;
319                         }
320
321                         return attrs;
322                 }
323
324                 static bool ShouldPrintFullName (Type type) {
325                         return type.IsClass && (!type.IsPointer ||
326                                 (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested));
327                 }
328
329                 public override string ToString () {
330                         StringBuilder sb = new StringBuilder ();
331                         Type retType = ReturnType;
332                         if (ShouldPrintFullName (retType))
333                                 sb.Append (retType.ToString ());
334                         else
335                                 sb.Append (retType.Name);
336                         sb.Append (" ");
337                         sb.Append (Name);
338                         if (IsGenericMethod) {
339                                 Type[] gen_params = GetGenericArguments ();
340                                 sb.Append ("[");
341                                 for (int j = 0; j < gen_params.Length; j++) {
342                                         if (j > 0)
343                                                 sb.Append (",");
344                                         sb.Append (gen_params [j].Name);
345                                 }
346                                 sb.Append ("]");
347                         }
348                         sb.Append ("(");
349                         ParameterInfo[] p = GetParameters ();
350                         for (int i = 0; i < p.Length; ++i) {
351                                 if (i > 0)
352                                         sb.Append (", ");
353                                 Type pt = p[i].ParameterType;
354                                 bool byref = pt.IsByRef;
355                                 if (byref)
356                                         pt = pt.GetElementType ();
357                                 if (ShouldPrintFullName (pt))
358                                         sb.Append (pt.ToString ());
359                                 else
360                                         sb.Append (pt.Name);
361                                 if (byref)
362                                         sb.Append (" ByRef");
363                         }
364                         if ((CallingConvention & CallingConventions.VarArgs) != 0) {
365                                 if (p.Length > 0)
366                                         sb.Append (", ");
367                                 sb.Append ("...");
368                         }
369                         
370                         sb.Append (")");
371                         return sb.ToString ();
372                 }
373
374         
375                 // ISerializable
376                 public void GetObjectData(SerializationInfo info, StreamingContext context) 
377                 {
378                         Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition
379                                 ? GetGenericArguments () : null;
380                         MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments);
381                 }
382
383                 public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
384                 {
385                         if (methodInstantiation == null)
386                                 throw new ArgumentNullException ("methodInstantiation");
387
388                         if (!IsGenericMethodDefinition)
389                                 throw new InvalidOperationException ("not a generic method definition");
390
391                         /*FIXME add GetGenericArgumentsLength() internal vcall to speed this up*/
392                         if (GetGenericArguments ().Length != methodInstantiation.Length)
393                                 throw new ArgumentException ("Incorrect length");
394
395                         bool hasUserType = false;
396                         foreach (Type type in methodInstantiation) {
397                                 if (type == null)
398                                         throw new ArgumentNullException ();
399                                 if (!(type is MonoType))
400                                         hasUserType = true;
401                         }
402
403                         if (hasUserType)
404                                 return new MethodOnTypeBuilderInst (this, methodInstantiation);
405
406                         MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
407                         if (ret == null)
408                                 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length));
409                         return ret;
410                 }
411
412                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
413                 extern MethodInfo MakeGenericMethod_impl (Type [] types);
414
415                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
416                 public override extern Type [] GetGenericArguments ();
417
418                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
419                 extern MethodInfo GetGenericMethodDefinition_impl ();
420
421                 public override MethodInfo GetGenericMethodDefinition ()
422                 {
423                         MethodInfo res = GetGenericMethodDefinition_impl ();
424                         if (res == null)
425                                 throw new InvalidOperationException ();
426
427                         return res;
428                 }
429
430                 public override extern bool IsGenericMethodDefinition {
431                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
432                         get;
433                 }
434
435                 public override extern bool IsGenericMethod {
436                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
437                         get;
438                 }
439
440                 public override bool ContainsGenericParameters {
441                         get {
442                                 if (IsGenericMethod) {
443                                         foreach (Type arg in GetGenericArguments ())
444                                                 if (arg.ContainsGenericParameters)
445                                                         return true;
446                                 }
447                                 return DeclaringType.ContainsGenericParameters;
448                         }
449                 }
450
451                 public override MethodBody GetMethodBody () {
452                         return GetMethodBody (mhandle);
453                 }
454
455 #if NET_4_0
456                 public override IList<CustomAttributeData> GetCustomAttributesData () {
457                         return CustomAttributeData.GetCustomAttributes (this);
458                 }
459 #endif
460         }
461         
462         [StructLayout (LayoutKind.Sequential)]
463         internal class MonoCMethod : ConstructorInfo, ISerializable
464         {
465 #pragma warning disable 649             
466                 internal IntPtr mhandle;
467                 string name;
468                 Type reftype;
469 #pragma warning restore 649             
470                 
471                 public override MethodImplAttributes GetMethodImplementationFlags ()
472                 {
473                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
474                 }
475
476                 public override ParameterInfo[] GetParameters ()
477                 {
478                         return MonoMethodInfo.GetParametersInfo (mhandle, this);
479                 }
480
481                 internal override int GetParameterCount ()
482                 {
483                         var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
484                         return pi == null ? 0 : pi.Length;
485                 }
486
487                 /*
488                  * InternalInvoke() receives the parameters corretcly converted by the binder
489                  * to match the types of the method signature.
490                  */
491                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
492                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
493
494                 [DebuggerHidden]
495                 [DebuggerStepThrough]
496                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
497                 {
498                         if (binder == null)
499                                 binder = Binder.DefaultBinder;
500
501                         ParameterInfo[] pinfo = GetParameters ();
502
503                         if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
504                                 throw new TargetParameterCountException ("parameters do not match signature");
505                         
506                         if ((invokeAttr & BindingFlags.ExactBinding) == 0) {
507                                 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
508                                         throw new ArgumentException ("failed to convert parameters");
509                         } else {
510                                 for (int i = 0; i < pinfo.Length; i++)
511                                         if (parameters[i].GetType() != pinfo[i].ParameterType)
512                                                 throw new ArgumentException ("parameters do not match signature");
513                         }
514
515 #if !NET_2_1
516                         if (SecurityManager.SecurityEnabled) {
517                                 // sadly Attributes doesn't tell us which kind of security action this is so
518                                 // we must do it the hard way - and it also means that we can skip calling
519                                 // Attribute (which is another an icall)
520                                 SecurityManager.ReflectedLinkDemandInvoke (this);
521                         }
522 #endif
523
524                         if (obj == null && DeclaringType.ContainsGenericParameters)
525                                 throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
526
527                         if ((invokeAttr & BindingFlags.CreateInstance) != 0 && DeclaringType.IsAbstract) {
528                                 throw new MemberAccessException (String.Format ("Cannot create an instance of {0} because it is an abstract class", DeclaringType));
529                         }
530
531                         Exception exc = null;
532                         object o = null;
533
534                         try {
535                                 o = InternalInvoke (obj, parameters, out exc);
536 #if NET_2_1
537                         } catch (MethodAccessException) {
538                                 throw;
539 #endif
540                         } catch (Exception e) {
541                                 throw new TargetInvocationException (e);
542                         }
543
544                         if (exc != null)
545                                 throw exc;
546                         return (obj == null) ? o : null;
547                 }
548
549                 [DebuggerHidden]
550                 [DebuggerStepThrough]
551                 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
552                 {
553                         return Invoke (null, invokeAttr, binder, parameters, culture);
554                 }
555
556                 public override RuntimeMethodHandle MethodHandle { 
557                         get {
558                                 return new RuntimeMethodHandle (mhandle);
559                         } 
560                 }
561                 
562                 public override MethodAttributes Attributes { 
563                         get {
564                                 return MonoMethodInfo.GetAttributes (mhandle);
565                         } 
566                 }
567
568                 public override CallingConventions CallingConvention { 
569                         get {
570                                 return MonoMethodInfo.GetCallingConvention (mhandle);
571                         }
572                 }
573                 
574                 public override Type ReflectedType {
575                         get {
576                                 return reftype;
577                         }
578                 }
579                 public override Type DeclaringType {
580                         get {
581                                 return MonoMethodInfo.GetDeclaringType (mhandle);
582                         }
583                 }
584                 public override string Name {
585                         get {
586                                 if (name != null)
587                                         return name;
588                                 return MonoMethod.get_name (this);
589                         }
590                 }
591
592                 public override bool IsDefined (Type attributeType, bool inherit) {
593                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
594                 }
595
596                 public override object[] GetCustomAttributes( bool inherit) {
597                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
598                 }
599
600                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
601                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
602                 }
603
604                 public override MethodBody GetMethodBody () {
605                         return GetMethodBody (mhandle);
606                 }
607
608                 public override string ToString () {
609                         StringBuilder sb = new StringBuilder ();
610                         sb.Append ("Void ");
611                         sb.Append (Name);
612                         sb.Append ("(");
613                         ParameterInfo[] p = GetParameters ();
614                         for (int i = 0; i < p.Length; ++i) {
615                                 if (i > 0)
616                                         sb.Append (", ");
617                                 sb.Append (p[i].ParameterType.Name);
618                         }
619                         if (CallingConvention == CallingConventions.Any)
620                                 sb.Append (", ...");
621                         sb.Append (")");
622                         return sb.ToString ();
623                 }
624
625                 // ISerializable
626                 public void GetObjectData(SerializationInfo info, StreamingContext context) 
627                 {
628                         MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);
629                 }
630
631 #if NET_4_0
632                 public override IList<CustomAttributeData> GetCustomAttributesData () {
633                         return CustomAttributeData.GetCustomAttributes (this);
634                 }
635 #endif
636         }
637 }