* attribute.cs (GetMarshal): Work even if "DefineCustom" is
[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.Globalization;
32 using System.Runtime.CompilerServices;
33 using System.Runtime.InteropServices;
34 using System.Runtime.Serialization;
35 using System.Security;
36
37 namespace System.Reflection {
38         
39         internal struct MonoMethodInfo 
40         {
41                 internal Type parent;
42                 internal Type ret;
43                 internal MethodAttributes attrs;
44                 internal MethodImplAttributes iattrs;
45                 internal CallingConventions callconv;
46
47                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
48                 internal static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
49                 
50                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
51                 internal static extern ParameterInfo[] get_parameter_info (IntPtr handle);
52         };
53         
54         /*
55          * Note: most of this class needs to be duplicated for the contructor, since
56          * the .NET reflection class hierarchy is so broken.
57          */
58         [Serializable()]
59         internal class MonoMethod : MethodInfo, ISerializable\r
60         {
61                 internal IntPtr mhandle;
62                 string name;
63                 Type reftype;
64
65                 internal MonoMethod () {
66                 }
67
68                 internal MonoMethod (RuntimeMethodHandle mhandle) {
69                         this.mhandle = mhandle.Value;
70                 }
71                 
72                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
73                 internal static extern MonoMethod get_base_definition (MonoMethod method);
74
75                 public override MethodInfo GetBaseDefinition ()
76                 {
77                         return get_base_definition (this);
78                 }
79
80                 public override Type ReturnType {
81                         get {
82                                 MonoMethodInfo info;
83                                 MonoMethodInfo.get_method_info (mhandle, out info);
84                                 return info.ret;
85                         }
86                 }
87                 public override ICustomAttributeProvider ReturnTypeCustomAttributes { 
88                         get {
89                                 return new ParameterInfo (ReturnType, this);
90                         }
91                 }
92                 
93                 public override MethodImplAttributes GetMethodImplementationFlags() {
94                         MonoMethodInfo info;
95                         MonoMethodInfo.get_method_info (mhandle, out info);
96                         return info.iattrs;
97                 }
98
99                 public override ParameterInfo[] GetParameters() {
100                         return MonoMethodInfo.get_parameter_info (mhandle);
101                 }
102
103                 /*
104                  * InternalInvoke() receives the parameters correctly converted by the 
105                  * binder to match the types of the method signature.
106                  */
107                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
108                 internal extern Object InternalInvoke (Object obj, Object[] parameters);
109                 
110                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
111                 {
112                         if (binder == null)
113                                 binder = Binder.DefaultBinder;
114                         ParameterInfo[] pinfo = GetParameters ();
115                         if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
116                                 throw new ArgumentException ("parameters");
117
118                         if (SecurityManager.SecurityEnabled) {
119                                 // sadly Attributes doesn't tell us which kind of security action this is so
120                                 // we must do it the hard way - and it also means that we can skip calling
121                                 // Attribute (which is another an icall)
122                                 SecurityManager.ReflectedLinkDemandInvoke (this);
123                         }
124
125                         try {
126                                 return InternalInvoke (obj, parameters);
127                         } catch (InvalidOperationException) {
128                                 throw;
129                         } catch (TargetException) {
130                                 throw;
131                         } catch (Exception e) {
132                                 throw new TargetInvocationException (e);
133                         }
134                 }
135
136                 public override RuntimeMethodHandle MethodHandle { 
137                         get {return new RuntimeMethodHandle (mhandle);} 
138                 }
139                 public override MethodAttributes Attributes { 
140                         get {
141                                 MonoMethodInfo info;
142                                 MonoMethodInfo.get_method_info (mhandle, out info);
143                                 return info.attrs;
144                         } 
145                 }
146
147                 public override CallingConventions CallingConvention { 
148                         get {
149                                 MonoMethodInfo info;
150                                 MonoMethodInfo.get_method_info (mhandle, out info);
151                                 return info.callconv;
152                         }
153                 }
154                 
155                 public override Type ReflectedType {
156                         get {
157                                 return reftype;
158                         }
159                 }
160                 public override Type DeclaringType {
161                         get {
162                                 MonoMethodInfo info;
163                                 MonoMethodInfo.get_method_info (mhandle, out info);
164                                 return info.parent;
165                         }
166                 }
167                 public override string Name {
168                         get {
169                                 return name;
170                         }
171                 }
172                 
173                 public override bool IsDefined (Type attributeType, bool inherit) {
174                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
175                 }
176
177                 public override object[] GetCustomAttributes( bool inherit) {
178                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
179                 }
180                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
181                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
182                 }
183
184                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
185                 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
186
187                 internal object[] GetPseudoCustomAttributes ()
188                 {
189                         int count = 0;
190
191                         /* MS.NET doesn't report MethodImplAttribute */
192
193                         MonoMethodInfo info;
194                         MonoMethodInfo.get_method_info (mhandle, out info);
195                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
196                                 count ++;
197                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
198                                 count ++;
199                         
200                         if (count == 0)
201                                 return null;
202                         object[] attrs = new object [count];
203                         count = 0;
204
205                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
206                                 attrs [count ++] = new PreserveSigAttribute ();
207                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
208                                 DllImportAttribute attr = GetDllImportAttribute (mhandle);
209                                 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
210                                         attr.PreserveSig = true;
211                                 attrs [count ++] = attr;
212                         }
213
214                         return attrs;
215                 }
216
217                 public override string ToString () {
218                         string parms = "";
219                         ParameterInfo[] p = GetParameters ();
220                         for (int i = 0; i < p.Length; ++i) {
221                                 if (i > 0)
222                                         parms = parms + ", ";
223                                 Type pt = p[i].ParameterType;
224                                 if (pt.IsClass && pt.Namespace != "")
225                                         parms = parms + pt.Namespace + "." + pt.Name;
226                                 else
227                                         parms = parms + pt.Name;
228                         }
229                         if (ReturnType.IsClass && ReturnType.Namespace != "")
230                                 return ReturnType.Namespace + "." + ReturnType.Name + " " + Name + "(" + parms + ")";
231                         string generic = "";
232 #if NET_2_0 || BOOTSTRAP_NET_2_0
233                         if (HasGenericParameters) {
234                                 Type[] gen_params = GetGenericArguments ();
235                                 generic = "[";
236                                 for (int j = 0; j < gen_params.Length; j++) {
237                                         if (j > 0)
238                                                 generic += ",";
239                                         generic += gen_params [j].Name;
240                                 }
241                                 generic += "]";
242                         }
243 #endif
244                         return ReturnType.Name + " " + Name + generic + "(" + parms + ")";
245                 }
246
247         \r
248                 // ISerializable\r
249                 public void GetObjectData(SerializationInfo info, StreamingContext context) \r
250                 {\r
251                         ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);\r
252                 }\r
253
254 #if NET_2_0 || BOOTSTRAP_NET_2_0
255                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
256                 public override extern MethodInfo BindGenericParameters (Type [] types);
257
258                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
259                 public override extern Type [] GetGenericArguments ();
260
261                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
262                 extern MethodInfo GetGenericMethodDefinition_impl ();
263
264                 public override MethodInfo GetGenericMethodDefinition ()
265                 {
266                         MethodInfo res = GetGenericMethodDefinition_impl ();
267                         if (res == null)
268                                 throw new InvalidOperationException ();
269
270                         return res;
271                 }
272
273                 public override extern bool Mono_IsInflatedMethod {
274                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
275                         get;
276                 }
277
278                 public override extern bool HasGenericParameters {
279                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
280                         get;
281                 }
282
283                 public override extern bool IsGenericMethodDefinition {
284                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
285                         get;
286                 }
287 #endif
288
289 #if NET_2_0
290                 public override MethodBody GetMethodBody () {
291                         return GetMethodBody (mhandle);
292                 }
293 #endif
294         }
295         
296         internal class MonoCMethod : ConstructorInfo, ISerializable\r
297         {
298                 internal IntPtr mhandle;
299                 string name;
300                 Type reftype;
301                 
302                 public override MethodImplAttributes GetMethodImplementationFlags() {
303                         MonoMethodInfo info;
304                         MonoMethodInfo.get_method_info (mhandle, out info);
305                         return info.iattrs;
306                 }
307
308                 public override ParameterInfo[] GetParameters() {
309                         return MonoMethodInfo.get_parameter_info (mhandle);
310                 }
311
312                 /*
313                  * InternalInvoke() receives the parameters corretcly converted by the binder
314                  * to match the types of the method signature.
315                  */
316                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
317                 internal extern Object InternalInvoke (Object obj, Object[] parameters);
318
319                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
320                 {
321                         if (binder == null)
322                                 binder = Binder.DefaultBinder;
323                         ParameterInfo[] pinfo = GetParameters ();
324                         if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
325                                 throw new ArgumentException ("parameters");
326
327                         if (SecurityManager.SecurityEnabled) {
328                                 // sadly Attributes doesn't tell us which kind of security action this is so
329                                 // we must do it the hard way - and it also means that we can skip calling
330                                 // Attribute (which is another an icall)
331                                 SecurityManager.ReflectedLinkDemandInvoke (this);
332                         }
333
334                         try {
335                                 return InternalInvoke (obj, parameters);
336                         } catch (InvalidOperationException) {
337                                 throw;
338                         } catch (TargetException) {
339                                 throw;
340                         } catch (Exception e) {
341                                 throw new TargetInvocationException (e);
342                         }
343                 }
344
345                 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
346                         return Invoke (null, invokeAttr, binder, parameters, culture);
347                 }
348
349                 public override RuntimeMethodHandle MethodHandle { 
350                         get {return new RuntimeMethodHandle (mhandle);} 
351                 }
352                 public override MethodAttributes Attributes { 
353                         get {
354                                 MonoMethodInfo info;
355                                 MonoMethodInfo.get_method_info (mhandle, out info);
356                                 return info.attrs;
357                         } 
358                 }
359
360                 public override CallingConventions CallingConvention { 
361                         get {
362                                 MonoMethodInfo info;
363                                 MonoMethodInfo.get_method_info (mhandle, out info);
364                                 return info.callconv;
365                         }
366                 }
367                 
368                 public override Type ReflectedType {
369                         get {
370                                 return reftype;
371                         }
372                 }
373                 public override Type DeclaringType {
374                         get {
375                                 MonoMethodInfo info;
376                                 MonoMethodInfo.get_method_info (mhandle, out info);
377                                 return info.parent;
378                         }
379                 }
380                 public override string Name {
381                         get {
382                                 return name;
383                         }
384                 }
385
386                 public override bool IsDefined (Type attributeType, bool inherit) {
387                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
388                 }
389
390                 public override object[] GetCustomAttributes( bool inherit) {
391                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
392                 }
393
394                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
395                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
396                 }
397
398 #if NET_2_0 || BOOTSTRAP_NET_2_0
399                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
400                 extern MethodInfo GetGenericMethodDefinition_impl ();
401
402                 public override MethodInfo GetGenericMethodDefinition ()
403                 {
404                         MethodInfo res = GetGenericMethodDefinition_impl ();
405                         if (res == null)
406                                 throw new InvalidOperationException ();
407
408                         return res;
409                 }
410
411                 public override extern bool Mono_IsInflatedMethod {
412                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
413                         get;
414                 }
415
416                 public override bool HasGenericParameters {
417                         get {
418                                 return false;
419                         }
420                 }
421
422                 public override bool IsGenericMethodDefinition {
423                         get {
424                                 return false;
425                         }
426                 }
427 #endif
428
429 #if NET_2_0
430                 public override MethodBody GetMethodBody () {
431                         return GetMethodBody (mhandle);
432                 }
433 #endif
434
435                 public override string ToString () {
436                         string parms = "";
437                         ParameterInfo[] p = GetParameters ();
438                         for (int i = 0; i < p.Length; ++i) {
439                                 if (i > 0)
440                                         parms = parms + ", ";
441                                 parms = parms + p [i].ParameterType.Name;
442                         }
443                         return "Void "+Name+"("+parms+")";
444                 }
445 \r
446                 // ISerializable\r
447                 public void GetObjectData(SerializationInfo info, StreamingContext context) \r
448                 {\r
449                         ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);\r
450                 }\r
451         }
452 }