Update mcs/class/System.Core/System/TimeZoneInfo.cs
[mono.git] / mcs / class / IKVM.Reflection / MethodInfo.cs
1 /*
2   Copyright (C) 2009-2012 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Diagnostics;
27 using System.Text;
28
29 namespace IKVM.Reflection
30 {
31         public abstract class MethodInfo : MethodBase, IGenericContext, IGenericBinder
32         {
33                 // prevent external subclasses
34                 internal MethodInfo()
35                 {
36                 }
37
38                 public sealed override MemberTypes MemberType
39                 {
40                         get { return MemberTypes.Method; }
41                 }
42
43                 public abstract Type ReturnType { get; }
44                 public abstract ParameterInfo ReturnParameter { get; }
45
46                 public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments)
47                 {
48                         throw new NotSupportedException(this.GetType().FullName);
49                 }
50
51                 public virtual MethodInfo GetGenericMethodDefinition()
52                 {
53                         throw new NotSupportedException(this.GetType().FullName);
54                 }
55
56                 public override string ToString()
57                 {
58                         StringBuilder sb = new StringBuilder();
59                         sb.Append(this.ReturnType.Name).Append(' ').Append(this.Name);
60                         string sep;
61                         if (this.IsGenericMethod)
62                         {
63                                 sb.Append('[');
64                                 sep = "";
65                                 foreach (Type arg in GetGenericArguments())
66                                 {
67                                         sb.Append(sep).Append(arg);
68                                         sep = ", ";
69                                 }
70                                 sb.Append(']');
71                         }
72                         sb.Append('(');
73                         sep = "";
74                         foreach (ParameterInfo arg in GetParameters())
75                         {
76                                 sb.Append(sep).Append(arg.ParameterType);
77                                 sep = ", ";
78                         }
79                         sb.Append(')');
80                         return sb.ToString();
81                 }
82
83                 internal bool IsNewSlot
84                 {
85                         get { return (this.Attributes & MethodAttributes.NewSlot) != 0; }
86                 }
87
88                 public MethodInfo GetBaseDefinition()
89                 {
90                         MethodInfo match = this;
91                         if (match.IsVirtual)
92                         {
93                                 for (Type type = this.DeclaringType.BaseType; type != null && !match.IsNewSlot; type = type.BaseType)
94                                 {
95                                         MethodInfo method = type.FindMethod(this.Name, this.MethodSignature) as MethodInfo;
96                                         if (method != null && method.IsVirtual)
97                                         {
98                                                 match = method;
99                                         }
100                                 }
101                         }
102                         return match;
103                 }
104
105                 public virtual MethodInfo[] __GetMethodImpls()
106                 {
107                         throw new NotSupportedException();
108                 }
109
110                 public bool __TryGetImplMap(out ImplMapFlags mappingFlags, out string importName, out string importScope)
111                 {
112                         Module module = this.Module;
113                         foreach (int i in module.ImplMap.Filter(GetCurrentToken()))
114                         {
115                                 mappingFlags = (ImplMapFlags)(ushort)module.ImplMap.records[i].MappingFlags;
116                                 importName = module.GetString(module.ImplMap.records[i].ImportName);
117                                 importScope = module.GetString(module.ModuleRef.records[(module.ImplMap.records[i].ImportScope & 0xFFFFFF) - 1]);
118                                 return true;
119                         }
120                         mappingFlags = 0;
121                         importName = null;
122                         importScope = null;
123                         return false;
124                 }
125
126                 public ConstructorInfo __AsConstructorInfo()
127                 {
128                         return new ConstructorInfoImpl(this);
129                 }
130
131                 Type IGenericContext.GetGenericTypeArgument(int index)
132                 {
133                         return this.DeclaringType.GetGenericTypeArgument(index);
134                 }
135
136                 Type IGenericContext.GetGenericMethodArgument(int index)
137                 {
138                         return GetGenericMethodArgument(index);
139                 }
140
141                 internal virtual Type GetGenericMethodArgument(int index)
142                 {
143                         throw new InvalidOperationException();
144                 }
145
146                 internal virtual int GetGenericMethodArgumentCount()
147                 {
148                         throw new InvalidOperationException();
149                 }
150
151                 internal override MethodInfo GetMethodOnTypeDefinition()
152                 {
153                         return this;
154                 }
155
156                 Type IGenericBinder.BindTypeParameter(Type type)
157                 {
158                         return this.DeclaringType.GetGenericTypeArgument(type.GenericParameterPosition);
159                 }
160
161                 Type IGenericBinder.BindMethodParameter(Type type)
162                 {
163                         return GetGenericMethodArgument(type.GenericParameterPosition);
164                 }
165
166                 internal override MethodBase BindTypeParameters(Type type)
167                 {
168                         return new GenericMethodInstance(this.DeclaringType.BindTypeParameters(type), this, null);
169                 }
170
171                 // This method is used by ILGenerator and exists to allow ArrayMethod to override it,
172                 // because ArrayMethod doesn't have a working MethodAttributes property, so it needs
173                 // to base the result of this on the CallingConvention.
174                 internal virtual bool HasThis
175                 {
176                         get { return !IsStatic; }
177                 }
178
179                 internal sealed override MemberInfo SetReflectedType(Type type)
180                 {
181                         return new MethodInfoWithReflectedType(type, this);
182                 }
183
184                 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
185                 {
186                         Module module = this.Module;
187                         List<CustomAttributeData> list = new List<CustomAttributeData>();
188                         if ((this.Attributes & MethodAttributes.PinvokeImpl) != 0
189                                 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_DllImportAttribute)))
190                         {
191                                 ImplMapFlags flags;
192                                 string importName;
193                                 string importScope;
194                                 if (__TryGetImplMap(out flags, out importName, out importScope))
195                                 {
196                                         list.Add(CustomAttributeData.CreateDllImportPseudoCustomAttribute(module, flags, importName, importScope, GetMethodImplementationFlags()));
197                                 }
198                         }
199                         if ((GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0
200                                 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_PreserveSigAttribute)))
201                         {
202                                 list.Add(CustomAttributeData.CreatePreserveSigPseudoCustomAttribute(module));
203                         }
204                         return list;
205                 }
206         }
207
208         sealed class MethodInfoWithReflectedType : MethodInfo
209         {
210                 private readonly Type reflectedType;
211                 private readonly MethodInfo method;
212
213                 internal MethodInfoWithReflectedType(Type reflectedType, MethodInfo method)
214                 {
215                         Debug.Assert(reflectedType != method.DeclaringType);
216                         this.reflectedType = reflectedType;
217                         this.method = method;
218                 }
219
220                 public override bool Equals(object obj)
221                 {
222                         MethodInfoWithReflectedType other = obj as MethodInfoWithReflectedType;
223                         return other != null
224                                 && other.reflectedType == reflectedType
225                                 && other.method == method;
226                 }
227
228                 public override int GetHashCode()
229                 {
230                         return reflectedType.GetHashCode() ^ method.GetHashCode();
231                 }
232
233                 internal override MethodSignature MethodSignature
234                 {
235                         get { return method.MethodSignature; }
236                 }
237
238                 internal override int ParameterCount
239                 {
240                         get { return method.ParameterCount; }
241                 }
242
243                 public override ParameterInfo[] GetParameters()
244                 {
245                         ParameterInfo[] parameters = method.GetParameters();
246                         for (int i = 0; i < parameters.Length; i++)
247                         {
248                                 parameters[i] = new ParameterInfoWrapper(this, parameters[i]);
249                         }
250                         return parameters;
251                 }
252
253                 public override MethodAttributes Attributes
254                 {
255                         get { return method.Attributes; }
256                 }
257
258                 public override MethodImplAttributes GetMethodImplementationFlags()
259                 {
260                         return method.GetMethodImplementationFlags();
261                 }
262
263                 public override MethodBody GetMethodBody()
264                 {
265                         return method.GetMethodBody();
266                 }
267
268                 public override CallingConventions CallingConvention
269                 {
270                         get { return method.CallingConvention; }
271                 }
272
273                 public override int __MethodRVA
274                 {
275                         get { return method.__MethodRVA; }
276                 }
277
278                 public override Type ReturnType
279                 {
280                         get { return method.ReturnType; }
281                 }
282
283                 public override ParameterInfo ReturnParameter
284                 {
285                         get { return new ParameterInfoWrapper(this, method.ReturnParameter); }
286                 }
287
288                 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
289                 {
290                         return SetReflectedType(method.MakeGenericMethod(typeArguments), reflectedType);
291                 }
292
293                 public override MethodInfo GetGenericMethodDefinition()
294                 {
295                         return method.GetGenericMethodDefinition();
296                 }
297
298                 public override string ToString()
299                 {
300                         return method.ToString();
301                 }
302
303                 public override MethodInfo[] __GetMethodImpls()
304                 {
305                         return method.__GetMethodImpls();
306                 }
307
308                 internal override Type GetGenericMethodArgument(int index)
309                 {
310                         return method.GetGenericMethodArgument(index);
311                 }
312
313                 internal override int GetGenericMethodArgumentCount()
314                 {
315                         return method.GetGenericMethodArgumentCount();
316                 }
317
318                 internal override MethodInfo GetMethodOnTypeDefinition()
319                 {
320                         return method.GetMethodOnTypeDefinition();
321                 }
322
323                 internal override bool HasThis
324                 {
325                         get { return method.HasThis; }
326                 }
327
328                 public override Module Module
329                 {
330                         get { return method.Module; }
331                 }
332
333                 public override Type DeclaringType
334                 {
335                         get { return method.DeclaringType; }
336                 }
337
338                 public override Type ReflectedType
339                 {
340                         get { return reflectedType; }
341                 }
342
343                 public override string Name
344                 {
345                         get { return method.Name; }
346                 }
347
348                 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
349                 {
350                         return method.ImportTo(module);
351                 }
352
353                 public override MethodBase __GetMethodOnTypeDefinition()
354                 {
355                         return method.__GetMethodOnTypeDefinition();
356                 }
357
358                 public override bool __IsMissing
359                 {
360                         get { return method.__IsMissing; }
361                 }
362
363                 internal override MethodBase BindTypeParameters(Type type)
364                 {
365                         return method.BindTypeParameters(type);
366                 }
367
368                 public override bool ContainsGenericParameters
369                 {
370                         get { return method.ContainsGenericParameters; }
371                 }
372
373                 public override Type[] GetGenericArguments()
374                 {
375                         return method.GetGenericArguments();
376                 }
377
378                 public override bool IsGenericMethod
379                 {
380                         get { return method.IsGenericMethod; }
381                 }
382
383                 public override bool IsGenericMethodDefinition
384                 {
385                         get { return method.IsGenericMethodDefinition; }
386                 }
387
388                 public override int MetadataToken
389                 {
390                         get { return method.MetadataToken; }
391                 }
392
393                 internal override int GetCurrentToken()
394                 {
395                         return method.GetCurrentToken();
396                 }
397
398                 internal override bool IsBaked
399                 {
400                         get { return method.IsBaked; }
401                 }
402         }
403 }