2 Copyright (C) 2009-2012 Jeroen Frijters
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.
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:
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.
25 using System.Collections.Generic;
26 using System.Diagnostics;
29 namespace IKVM.Reflection
31 public abstract class MethodInfo : MethodBase, IGenericContext, IGenericBinder
33 // prevent external subclasses
38 public sealed override MemberTypes MemberType
40 get { return MemberTypes.Method; }
43 public abstract Type ReturnType { get; }
44 public abstract ParameterInfo ReturnParameter { get; }
46 public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments)
48 throw new NotSupportedException(this.GetType().FullName);
51 public virtual MethodInfo GetGenericMethodDefinition()
53 throw new NotSupportedException(this.GetType().FullName);
56 public override string ToString()
58 StringBuilder sb = new StringBuilder();
59 sb.Append(this.ReturnType.Name).Append(' ').Append(this.Name);
61 if (this.IsGenericMethod)
65 foreach (Type arg in GetGenericArguments())
67 sb.Append(sep).Append(arg);
74 foreach (ParameterInfo arg in GetParameters())
76 sb.Append(sep).Append(arg.ParameterType);
83 internal bool IsNewSlot
85 get { return (this.Attributes & MethodAttributes.NewSlot) != 0; }
88 public MethodInfo GetBaseDefinition()
90 MethodInfo match = this;
93 for (Type type = this.DeclaringType.BaseType; type != null && !match.IsNewSlot; type = type.BaseType)
95 MethodInfo method = type.FindMethod(this.Name, this.MethodSignature) as MethodInfo;
96 if (method != null && method.IsVirtual)
105 public virtual MethodInfo[] __GetMethodImpls()
107 throw new NotSupportedException();
110 public bool __TryGetImplMap(out ImplMapFlags mappingFlags, out string importName, out string importScope)
112 Module module = this.Module;
113 foreach (int i in module.ImplMap.Filter(GetCurrentToken()))
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]);
126 Type IGenericContext.GetGenericTypeArgument(int index)
128 return this.DeclaringType.GetGenericTypeArgument(index);
131 Type IGenericContext.GetGenericMethodArgument(int index)
133 return GetGenericMethodArgument(index);
136 internal virtual Type GetGenericMethodArgument(int index)
138 throw new InvalidOperationException();
141 internal virtual int GetGenericMethodArgumentCount()
143 throw new InvalidOperationException();
146 internal override MethodInfo GetMethodOnTypeDefinition()
151 Type IGenericBinder.BindTypeParameter(Type type)
153 return this.DeclaringType.GetGenericTypeArgument(type.GenericParameterPosition);
156 Type IGenericBinder.BindMethodParameter(Type type)
158 return GetGenericMethodArgument(type.GenericParameterPosition);
161 internal override MethodBase BindTypeParameters(Type type)
163 return new GenericMethodInstance(this.DeclaringType.BindTypeParameters(type), this, null);
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
171 get { return !IsStatic; }
174 internal sealed override MemberInfo SetReflectedType(Type type)
176 return new MethodInfoWithReflectedType(type, this);
179 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
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)))
189 if (__TryGetImplMap(out flags, out importName, out importScope))
191 list.Add(CustomAttributeData.CreateDllImportPseudoCustomAttribute(module, flags, importName, importScope, GetMethodImplementationFlags()));
194 if ((GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0
195 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_PreserveSigAttribute)))
197 list.Add(CustomAttributeData.CreatePreserveSigPseudoCustomAttribute(module));
203 sealed class MethodInfoWithReflectedType : MethodInfo
205 private readonly Type reflectedType;
206 private readonly MethodInfo method;
208 internal MethodInfoWithReflectedType(Type reflectedType, MethodInfo method)
210 Debug.Assert(reflectedType != method.DeclaringType);
211 this.reflectedType = reflectedType;
212 this.method = method;
215 public override bool Equals(object obj)
217 MethodInfoWithReflectedType other = obj as MethodInfoWithReflectedType;
219 && other.reflectedType == reflectedType
220 && other.method == method;
223 public override int GetHashCode()
225 return reflectedType.GetHashCode() ^ method.GetHashCode();
228 internal override MethodSignature MethodSignature
230 get { return method.MethodSignature; }
233 internal override int ParameterCount
235 get { return method.ParameterCount; }
238 public override ParameterInfo[] GetParameters()
240 ParameterInfo[] parameters = method.GetParameters();
241 for (int i = 0; i < parameters.Length; i++)
243 parameters[i] = new ParameterInfoWrapper(this, parameters[i]);
248 public override MethodAttributes Attributes
250 get { return method.Attributes; }
253 public override MethodImplAttributes GetMethodImplementationFlags()
255 return method.GetMethodImplementationFlags();
258 public override MethodBody GetMethodBody()
260 return method.GetMethodBody();
263 public override CallingConventions CallingConvention
265 get { return method.CallingConvention; }
268 public override int __MethodRVA
270 get { return method.__MethodRVA; }
273 public override Type ReturnType
275 get { return method.ReturnType; }
278 public override ParameterInfo ReturnParameter
280 get { return new ParameterInfoWrapper(this, method.ReturnParameter); }
283 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
285 return SetReflectedType(method.MakeGenericMethod(typeArguments), reflectedType);
288 public override MethodInfo GetGenericMethodDefinition()
290 return method.GetGenericMethodDefinition();
293 public override string ToString()
295 return method.ToString();
298 public override MethodInfo[] __GetMethodImpls()
300 return method.__GetMethodImpls();
303 internal override Type GetGenericMethodArgument(int index)
305 return method.GetGenericMethodArgument(index);
308 internal override int GetGenericMethodArgumentCount()
310 return method.GetGenericMethodArgumentCount();
313 internal override MethodInfo GetMethodOnTypeDefinition()
315 return method.GetMethodOnTypeDefinition();
318 internal override bool HasThis
320 get { return method.HasThis; }
323 public override Module Module
325 get { return method.Module; }
328 public override Type DeclaringType
330 get { return method.DeclaringType; }
333 public override Type ReflectedType
335 get { return reflectedType; }
338 public override string Name
340 get { return method.Name; }
343 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
345 return method.ImportTo(module);
348 public override MethodBase __GetMethodOnTypeDefinition()
350 return method.__GetMethodOnTypeDefinition();
353 public override bool __IsMissing
355 get { return method.__IsMissing; }
358 internal override MethodBase BindTypeParameters(Type type)
360 return method.BindTypeParameters(type);
363 public override bool ContainsGenericParameters
365 get { return method.ContainsGenericParameters; }
368 public override Type[] GetGenericArguments()
370 return method.GetGenericArguments();
373 public override bool IsGenericMethod
375 get { return method.IsGenericMethod; }
378 public override bool IsGenericMethodDefinition
380 get { return method.IsGenericMethodDefinition; }
383 public override int MetadataToken
385 get { return method.MetadataToken; }
388 internal override int GetCurrentToken()
390 return method.GetCurrentToken();
393 internal override bool IsBaked
395 get { return method.IsBaked; }