Wrap always_inline and noinline attributes in compiler checks and use MSVC equivalent.
[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                 Type IGenericContext.GetGenericTypeArgument(int index)
127                 {
128                         return this.DeclaringType.GetGenericTypeArgument(index);
129                 }
130
131                 Type IGenericContext.GetGenericMethodArgument(int index)
132                 {
133                         return GetGenericMethodArgument(index);
134                 }
135
136                 internal virtual Type GetGenericMethodArgument(int index)
137                 {
138                         throw new InvalidOperationException();
139                 }
140
141                 internal virtual int GetGenericMethodArgumentCount()
142                 {
143                         throw new InvalidOperationException();
144                 }
145
146                 internal override MethodInfo GetMethodOnTypeDefinition()
147                 {
148                         return this;
149                 }
150
151                 Type IGenericBinder.BindTypeParameter(Type type)
152                 {
153                         return this.DeclaringType.GetGenericTypeArgument(type.GenericParameterPosition);
154                 }
155
156                 Type IGenericBinder.BindMethodParameter(Type type)
157                 {
158                         return GetGenericMethodArgument(type.GenericParameterPosition);
159                 }
160
161                 internal override MethodBase BindTypeParameters(Type type)
162                 {
163                         return new GenericMethodInstance(this.DeclaringType.BindTypeParameters(type), this, null);
164                 }
165
166                 // This method is used by ILGenerator and exists to allow ArrayMethod to override it,
167                 // because ArrayMethod doesn't have a working MethodAttributes property, so it needs
168                 // to base the result of this on the CallingConvention.
169                 internal virtual bool HasThis
170                 {
171                         get { return !IsStatic; }
172                 }
173
174                 internal sealed override MemberInfo SetReflectedType(Type type)
175                 {
176                         return new MethodInfoWithReflectedType(type, this);
177                 }
178
179                 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
180                 {
181                         Module module = this.Module;
182                         List<CustomAttributeData> list = new List<CustomAttributeData>();
183                         if ((this.Attributes & MethodAttributes.PinvokeImpl) != 0
184                                 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_DllImportAttribute)))
185                         {
186                                 ImplMapFlags flags;
187                                 string importName;
188                                 string importScope;
189                                 if (__TryGetImplMap(out flags, out importName, out importScope))
190                                 {
191                                         list.Add(CustomAttributeData.CreateDllImportPseudoCustomAttribute(module, flags, importName, importScope, GetMethodImplementationFlags()));
192                                 }
193                         }
194                         if ((GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0
195                                 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_PreserveSigAttribute)))
196                         {
197                                 list.Add(CustomAttributeData.CreatePreserveSigPseudoCustomAttribute(module));
198                         }
199                         return list;
200                 }
201         }
202
203         sealed class MethodInfoWithReflectedType : MethodInfo
204         {
205                 private readonly Type reflectedType;
206                 private readonly MethodInfo method;
207
208                 internal MethodInfoWithReflectedType(Type reflectedType, MethodInfo method)
209                 {
210                         Debug.Assert(reflectedType != method.DeclaringType);
211                         this.reflectedType = reflectedType;
212                         this.method = method;
213                 }
214
215                 public override bool Equals(object obj)
216                 {
217                         MethodInfoWithReflectedType other = obj as MethodInfoWithReflectedType;
218                         return other != null
219                                 && other.reflectedType == reflectedType
220                                 && other.method == method;
221                 }
222
223                 public override int GetHashCode()
224                 {
225                         return reflectedType.GetHashCode() ^ method.GetHashCode();
226                 }
227
228                 internal override MethodSignature MethodSignature
229                 {
230                         get { return method.MethodSignature; }
231                 }
232
233                 internal override int ParameterCount
234                 {
235                         get { return method.ParameterCount; }
236                 }
237
238                 public override ParameterInfo[] GetParameters()
239                 {
240                         ParameterInfo[] parameters = method.GetParameters();
241                         for (int i = 0; i < parameters.Length; i++)
242                         {
243                                 parameters[i] = new ParameterInfoWrapper(this, parameters[i]);
244                         }
245                         return parameters;
246                 }
247
248                 public override MethodAttributes Attributes
249                 {
250                         get { return method.Attributes; }
251                 }
252
253                 public override MethodImplAttributes GetMethodImplementationFlags()
254                 {
255                         return method.GetMethodImplementationFlags();
256                 }
257
258                 public override MethodBody GetMethodBody()
259                 {
260                         return method.GetMethodBody();
261                 }
262
263                 public override CallingConventions CallingConvention
264                 {
265                         get { return method.CallingConvention; }
266                 }
267
268                 public override int __MethodRVA
269                 {
270                         get { return method.__MethodRVA; }
271                 }
272
273                 public override Type ReturnType
274                 {
275                         get { return method.ReturnType; }
276                 }
277
278                 public override ParameterInfo ReturnParameter
279                 {
280                         get { return new ParameterInfoWrapper(this, method.ReturnParameter); }
281                 }
282
283                 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
284                 {
285                         return SetReflectedType(method.MakeGenericMethod(typeArguments), reflectedType);
286                 }
287
288                 public override MethodInfo GetGenericMethodDefinition()
289                 {
290                         return method.GetGenericMethodDefinition();
291                 }
292
293                 public override string ToString()
294                 {
295                         return method.ToString();
296                 }
297
298                 public override MethodInfo[] __GetMethodImpls()
299                 {
300                         return method.__GetMethodImpls();
301                 }
302
303                 internal override Type GetGenericMethodArgument(int index)
304                 {
305                         return method.GetGenericMethodArgument(index);
306                 }
307
308                 internal override int GetGenericMethodArgumentCount()
309                 {
310                         return method.GetGenericMethodArgumentCount();
311                 }
312
313                 internal override MethodInfo GetMethodOnTypeDefinition()
314                 {
315                         return method.GetMethodOnTypeDefinition();
316                 }
317
318                 internal override bool HasThis
319                 {
320                         get { return method.HasThis; }
321                 }
322
323                 public override Module Module
324                 {
325                         get { return method.Module; }
326                 }
327
328                 public override Type DeclaringType
329                 {
330                         get { return method.DeclaringType; }
331                 }
332
333                 public override Type ReflectedType
334                 {
335                         get { return reflectedType; }
336                 }
337
338                 public override string Name
339                 {
340                         get { return method.Name; }
341                 }
342
343                 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
344                 {
345                         return method.ImportTo(module);
346                 }
347
348                 public override MethodBase __GetMethodOnTypeDefinition()
349                 {
350                         return method.__GetMethodOnTypeDefinition();
351                 }
352
353                 public override bool __IsMissing
354                 {
355                         get { return method.__IsMissing; }
356                 }
357
358                 internal override MethodBase BindTypeParameters(Type type)
359                 {
360                         return method.BindTypeParameters(type);
361                 }
362
363                 public override bool ContainsGenericParameters
364                 {
365                         get { return method.ContainsGenericParameters; }
366                 }
367
368                 public override Type[] GetGenericArguments()
369                 {
370                         return method.GetGenericArguments();
371                 }
372
373                 public override bool IsGenericMethod
374                 {
375                         get { return method.IsGenericMethod; }
376                 }
377
378                 public override bool IsGenericMethodDefinition
379                 {
380                         get { return method.IsGenericMethodDefinition; }
381                 }
382
383                 public override int MetadataToken
384                 {
385                         get { return method.MetadataToken; }
386                 }
387
388                 internal override int GetCurrentToken()
389                 {
390                         return method.GetCurrentToken();
391                 }
392
393                 internal override bool IsBaked
394                 {
395                         get { return method.IsBaked; }
396                 }
397         }
398 }