Merge pull request #496 from nicolas-raoul/unit-test-for-issue2907
[mono.git] / mcs / class / corlib / System.Reflection / MethodBase.cs
1 //
2 // System.Reflection/MethodBase.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 // Copyright 2011 Xamarin Inc (http://www.xamarin.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.Diagnostics;
32 using System.Globalization;
33 #if !FULL_AOT_RUNTIME
34 using System.Reflection.Emit;
35 #endif
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38
39 namespace System.Reflection {
40
41         [ComVisible (true)]
42         [ComDefaultInterfaceAttribute (typeof (_MethodBase))]
43         [Serializable]
44         [ClassInterface(ClassInterfaceType.None)]
45         public abstract class MethodBase: MemberInfo, _MethodBase {
46
47                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
48                 public extern static MethodBase GetCurrentMethod ();
49
50                 internal static MethodBase GetMethodFromHandleNoGenericCheck (RuntimeMethodHandle handle)
51                 {
52                         return GetMethodFromIntPtr (handle.Value, IntPtr.Zero);
53                 }
54
55                 static MethodBase GetMethodFromIntPtr (IntPtr handle, IntPtr declaringType)
56                 {
57                         if (handle == IntPtr.Zero)
58                                 throw new ArgumentException ("The handle is invalid.");
59                         MethodBase res = GetMethodFromHandleInternalType (handle, declaringType);
60                         if (res == null)
61                                 throw new ArgumentException ("The handle is invalid.");                 
62                         return res;
63                 }
64
65                 public static MethodBase GetMethodFromHandle (RuntimeMethodHandle handle)
66                 {
67                         MethodBase res = GetMethodFromIntPtr (handle.Value, IntPtr.Zero);
68                         Type t = res.DeclaringType;
69                         if (t.IsGenericType || t.IsGenericTypeDefinition)
70                                 throw new ArgumentException ("Cannot resolve method because it's declared in a generic class.");
71                         return res;
72                 }
73
74                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
75                 private extern static MethodBase GetMethodFromHandleInternalType (IntPtr method_handle, IntPtr type_handle);
76
77                 [ComVisible (false)]
78                 public static MethodBase GetMethodFromHandle (RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
79                 {
80                         return GetMethodFromIntPtr (handle.Value, declaringType.Value);
81                 }
82
83                 public abstract MethodImplAttributes GetMethodImplementationFlags();
84
85                 public abstract ParameterInfo[] GetParameters();
86                 
87                 //
88                 // This is a quick version for our own use. We should override
89                 // it where possible so that it does not allocate an array.
90                 //
91                 internal virtual int GetParameterCount ()
92                 {
93                         throw new NotImplementedException ("must be implemented");
94                 }
95
96                 internal virtual Type GetParameterType (int pos) {
97                         throw new NotImplementedException ();
98                 }
99
100                 [DebuggerHidden]
101                 [DebuggerStepThrough]           
102                 public Object Invoke(Object obj, Object[] parameters) {
103                         return Invoke (obj, 0, null, parameters, null);
104                 }
105
106                 public abstract Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
107
108                 protected MethodBase()
109                 {
110                 }
111
112                 public abstract RuntimeMethodHandle MethodHandle { get; }
113                 public abstract MethodAttributes Attributes { get; }
114                 public virtual CallingConventions CallingConvention { get {return CallingConventions.Standard;} }
115                 public Boolean IsPublic { 
116                         get {
117                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
118                         }
119                 }
120                 public Boolean IsPrivate {
121                         get {
122                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
123                         }
124                 }
125                 public Boolean IsFamily {
126                         get {
127                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
128                         }
129                 }
130                 public Boolean IsAssembly {
131                         get {
132                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
133                         }
134                 }
135                 public Boolean IsFamilyAndAssembly {
136                         get {
137                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
138                         }
139                 }
140                 public Boolean IsFamilyOrAssembly {
141                         get {
142                                 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
143                         }
144                 }
145                 public Boolean IsStatic {
146                         get {
147                                 return (Attributes & MethodAttributes.Static) != 0;
148                         }
149                 }
150                 public Boolean IsFinal {
151                         get {
152                                 return (Attributes & MethodAttributes.Final) != 0;
153                         }
154                 }
155                 public Boolean IsVirtual {
156                         get {
157                                 return (Attributes & MethodAttributes.Virtual) != 0;
158                         }
159                 }
160                 public Boolean IsHideBySig {
161                         get {
162                                 return (Attributes & MethodAttributes.HideBySig) != 0;
163                         }
164                 }
165                 public Boolean IsAbstract {
166                         get {
167                                 return (Attributes & MethodAttributes.Abstract) != 0;
168                         }
169                 }
170                 public Boolean IsSpecialName {
171                         get {
172                                 int attr = (int)Attributes;
173                                 return (attr & (int)MethodAttributes.SpecialName) != 0;
174                         }
175                 }
176                 [ComVisibleAttribute (true)]
177                 public Boolean IsConstructor {
178                         get {
179                                 int attr = (int)Attributes;
180                                 return ((attr & (int)MethodAttributes.RTSpecialName) != 0
181                                         && (Name == ".ctor"));
182                         }
183                 }
184
185                 internal virtual int get_next_table_index (object obj, int table, bool inc) {
186 #if !FULL_AOT_RUNTIME
187                         if (this is MethodBuilder) {
188                                 MethodBuilder mb = (MethodBuilder)this;
189                                 return mb.get_next_table_index (obj, table, inc);
190                         }
191                         if (this is ConstructorBuilder) {
192                                 ConstructorBuilder mb = (ConstructorBuilder)this;
193                                 return mb.get_next_table_index (obj, table, inc);
194                         }
195 #endif
196                         throw new Exception ("Method is not a builder method");
197                 }
198
199                 [ComVisible (true)]
200                 public virtual Type [] GetGenericArguments ()
201                 {
202                         throw new NotSupportedException ();
203                 }
204
205                 public virtual bool ContainsGenericParameters {
206                         get {
207                                 return false;
208                         }
209                 }
210
211                 public virtual bool IsGenericMethodDefinition {
212                         get {
213                                 return false;
214                         }
215                 }
216
217                 public virtual bool IsGenericMethod {
218                         get {
219                                 return false;
220                         }
221                 }
222
223                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
224                 internal extern static MethodBody GetMethodBodyInternal (IntPtr handle);
225
226                 internal static MethodBody GetMethodBody (IntPtr handle) {
227                         return GetMethodBodyInternal (handle);
228                 }
229
230                 public virtual MethodBody GetMethodBody () {
231                         throw new NotSupportedException ();
232                 }
233
234 #if NET_4_0
235                 public override bool Equals (object obj)
236                 {
237                         return obj == (object) this;
238                 }
239
240                 public override int GetHashCode ()
241                 {
242                         return base.GetHashCode ();
243                 }
244
245                 public static bool operator == (MethodBase left, MethodBase right)
246                 {
247                         if ((object)left == (object)right)
248                                 return true;
249                         if ((object)left == null ^ (object)right == null)
250                                 return false;
251                         return left.Equals (right);
252                 }
253
254                 public static bool operator != (MethodBase left, MethodBase right)
255                 {
256                         if ((object)left == (object)right)
257                                 return false;
258                         if ((object)left == null ^ (object)right == null)
259                                 return true;
260                         return !left.Equals (right);
261                 }
262                 
263                 public virtual bool IsSecurityCritical {
264                         get {
265                                 throw new NotImplementedException ();
266                         }
267                 }
268                 
269                 public virtual bool IsSecuritySafeCritical {
270                         get {
271                                 throw new NotImplementedException ();
272                         }
273                 }
274
275                 public virtual bool IsSecurityTransparent {
276                         get {
277                                 throw new NotImplementedException ();
278                         }
279                 }
280 #endif
281
282                 void _MethodBase.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
283                 {
284                         throw new NotImplementedException ();
285                 }
286
287                 void _MethodBase.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
288                 {
289                         throw new NotImplementedException ();
290                 }
291
292                 void _MethodBase.GetTypeInfoCount (out uint pcTInfo)
293                 {
294                         throw new NotImplementedException ();
295                 }
296
297                 void _MethodBase.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
298                 {
299                         throw new NotImplementedException ();
300                 }
301         }
302 }