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 public ConstructorInfo __AsConstructorInfo()
128 return new ConstructorInfoImpl(this);
131 Type IGenericContext.GetGenericTypeArgument(int index)
133 return this.DeclaringType.GetGenericTypeArgument(index);
136 Type IGenericContext.GetGenericMethodArgument(int index)
138 return GetGenericMethodArgument(index);
141 internal virtual Type GetGenericMethodArgument(int index)
143 throw new InvalidOperationException();
146 internal virtual int GetGenericMethodArgumentCount()
148 throw new InvalidOperationException();
151 internal override MethodInfo GetMethodOnTypeDefinition()
156 Type IGenericBinder.BindTypeParameter(Type type)
158 return this.DeclaringType.GetGenericTypeArgument(type.GenericParameterPosition);
161 Type IGenericBinder.BindMethodParameter(Type type)
163 return GetGenericMethodArgument(type.GenericParameterPosition);
166 internal override MethodBase BindTypeParameters(Type type)
168 return new GenericMethodInstance(this.DeclaringType.BindTypeParameters(type), this, null);
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
176 get { return !IsStatic; }
179 internal sealed override MemberInfo SetReflectedType(Type type)
181 return new MethodInfoWithReflectedType(type, this);
184 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
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)))
194 if (__TryGetImplMap(out flags, out importName, out importScope))
196 list.Add(CustomAttributeData.CreateDllImportPseudoCustomAttribute(module, flags, importName, importScope, GetMethodImplementationFlags()));
199 if ((GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0
200 && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_PreserveSigAttribute)))
202 list.Add(CustomAttributeData.CreatePreserveSigPseudoCustomAttribute(module));
208 sealed class MethodInfoWithReflectedType : MethodInfo
210 private readonly Type reflectedType;
211 private readonly MethodInfo method;
213 internal MethodInfoWithReflectedType(Type reflectedType, MethodInfo method)
215 Debug.Assert(reflectedType != method.DeclaringType);
216 this.reflectedType = reflectedType;
217 this.method = method;
220 public override bool Equals(object obj)
222 MethodInfoWithReflectedType other = obj as MethodInfoWithReflectedType;
224 && other.reflectedType == reflectedType
225 && other.method == method;
228 public override int GetHashCode()
230 return reflectedType.GetHashCode() ^ method.GetHashCode();
233 internal override MethodSignature MethodSignature
235 get { return method.MethodSignature; }
238 internal override int ParameterCount
240 get { return method.ParameterCount; }
243 public override ParameterInfo[] GetParameters()
245 ParameterInfo[] parameters = method.GetParameters();
246 for (int i = 0; i < parameters.Length; i++)
248 parameters[i] = new ParameterInfoWrapper(this, parameters[i]);
253 public override MethodAttributes Attributes
255 get { return method.Attributes; }
258 public override MethodImplAttributes GetMethodImplementationFlags()
260 return method.GetMethodImplementationFlags();
263 public override MethodBody GetMethodBody()
265 return method.GetMethodBody();
268 public override CallingConventions CallingConvention
270 get { return method.CallingConvention; }
273 public override int __MethodRVA
275 get { return method.__MethodRVA; }
278 public override Type ReturnType
280 get { return method.ReturnType; }
283 public override ParameterInfo ReturnParameter
285 get { return new ParameterInfoWrapper(this, method.ReturnParameter); }
288 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
290 return SetReflectedType(method.MakeGenericMethod(typeArguments), reflectedType);
293 public override MethodInfo GetGenericMethodDefinition()
295 return method.GetGenericMethodDefinition();
298 public override string ToString()
300 return method.ToString();
303 public override MethodInfo[] __GetMethodImpls()
305 return method.__GetMethodImpls();
308 internal override Type GetGenericMethodArgument(int index)
310 return method.GetGenericMethodArgument(index);
313 internal override int GetGenericMethodArgumentCount()
315 return method.GetGenericMethodArgumentCount();
318 internal override MethodInfo GetMethodOnTypeDefinition()
320 return method.GetMethodOnTypeDefinition();
323 internal override bool HasThis
325 get { return method.HasThis; }
328 public override Module Module
330 get { return method.Module; }
333 public override Type DeclaringType
335 get { return method.DeclaringType; }
338 public override Type ReflectedType
340 get { return reflectedType; }
343 public override string Name
345 get { return method.Name; }
348 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
350 return method.ImportTo(module);
353 public override MethodBase __GetMethodOnTypeDefinition()
355 return method.__GetMethodOnTypeDefinition();
358 public override bool __IsMissing
360 get { return method.__IsMissing; }
363 internal override MethodBase BindTypeParameters(Type type)
365 return method.BindTypeParameters(type);
368 public override bool ContainsGenericParameters
370 get { return method.ContainsGenericParameters; }
373 public override Type[] GetGenericArguments()
375 return method.GetGenericArguments();
378 public override bool IsGenericMethod
380 get { return method.IsGenericMethod; }
383 public override bool IsGenericMethodDefinition
385 get { return method.IsGenericMethodDefinition; }
388 public override int MetadataToken
390 get { return method.MetadataToken; }
393 internal override int GetCurrentToken()
395 return method.GetCurrentToken();
398 internal override bool IsBaked
400 get { return method.IsBaked; }