2 Copyright (C) 2009, 2010 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;
28 namespace IKVM.Reflection
30 // this represents both generic method instantiations and non-generic methods on generic type instantations
31 // (this means that it can be a generic method declaration as well as a generic method instance)
32 sealed class GenericMethodInstance : MethodInfo
34 private readonly Type declaringType;
35 private readonly MethodInfo method;
36 private readonly Type[] methodArgs;
37 private MethodSignature lazyMethodSignature;
39 internal GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs)
41 System.Diagnostics.Debug.Assert(!(method is GenericMethodInstance));
42 this.declaringType = declaringType;
44 this.methodArgs = methodArgs;
47 public override bool Equals(object obj)
49 GenericMethodInstance other = obj as GenericMethodInstance;
51 && other.method.Equals(method)
52 && other.declaringType.Equals(declaringType)
53 && Util.ArrayEquals(other.methodArgs, methodArgs);
56 public override int GetHashCode()
58 return declaringType.GetHashCode() * 33 ^ method.GetHashCode() ^ Util.GetHashCode(methodArgs);
61 public override Type ReturnType
63 get { return method.ReturnType.BindTypeParameters(this); }
66 public override ParameterInfo ReturnParameter
68 get { return new GenericParameterInfoImpl(this, method.ReturnParameter); }
71 public override ParameterInfo[] GetParameters()
73 ParameterInfo[] parameters = method.GetParameters();
74 for (int i = 0; i < parameters.Length; i++)
76 parameters[i] = new GenericParameterInfoImpl(this, parameters[i]);
81 internal override int ParameterCount
83 get { return method.ParameterCount; }
86 public override CallingConventions CallingConvention
88 get { return method.CallingConvention; }
91 public override MethodAttributes Attributes
93 get { return method.Attributes; }
96 public override MethodImplAttributes GetMethodImplementationFlags()
98 return method.GetMethodImplementationFlags();
101 public override string Name
103 get { return method.Name; }
106 public override Type DeclaringType
108 get { return declaringType.IsModulePseudoType ? null : declaringType; }
111 public override Module Module
113 get { return method.Module; }
116 public override int MetadataToken
118 get { return method.MetadataToken; }
121 public override MethodBody GetMethodBody()
123 IKVM.Reflection.Reader.MethodDefImpl md = method as IKVM.Reflection.Reader.MethodDefImpl;
126 return md.GetMethodBody(this);
128 throw new NotSupportedException();
131 public override int __MethodRVA
133 get { return method.__MethodRVA; }
136 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
138 return new GenericMethodInstance(declaringType, method, typeArguments);
141 public override bool IsGenericMethod
143 get { return method.IsGenericMethod; }
146 public override bool IsGenericMethodDefinition
148 get { return method.IsGenericMethodDefinition && methodArgs == null; }
151 public override bool ContainsGenericParameters
155 if (declaringType.ContainsGenericParameters)
159 if (methodArgs != null)
161 foreach (Type type in methodArgs)
163 if (type.ContainsGenericParameters)
173 public override MethodInfo GetGenericMethodDefinition()
175 if (this.IsGenericMethod)
177 if (this.IsGenericMethodDefinition)
181 else if (declaringType.IsConstructedGenericType)
183 return new GenericMethodInstance(declaringType, method, null);
190 throw new InvalidOperationException();
193 public override MethodBase __GetMethodOnTypeDefinition()
198 public override Type[] GetGenericArguments()
200 if (methodArgs == null)
202 return method.GetGenericArguments();
206 return (Type[])methodArgs.Clone();
210 internal override Type GetGenericMethodArgument(int index)
212 if (methodArgs == null)
214 return method.GetGenericMethodArgument(index);
218 return methodArgs[index];
222 internal override int GetGenericMethodArgumentCount()
224 return method.GetGenericMethodArgumentCount();
227 internal override MethodInfo GetMethodOnTypeDefinition()
229 return method.GetMethodOnTypeDefinition();
232 internal override int ImportTo(Emit.ModuleBuilder module)
234 if (methodArgs == null)
236 return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
240 return module.ImportMethodSpec(declaringType, method, methodArgs);
244 internal override MethodSignature MethodSignature
246 get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
249 internal override MethodBase BindTypeParameters(Type type)
251 System.Diagnostics.Debug.Assert(methodArgs == null);
252 return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
255 internal override bool HasThis
257 get { return method.HasThis; }
260 public override MethodInfo[] __GetMethodImpls()
262 MethodInfo[] methods = method.__GetMethodImpls();
263 for (int i = 0; i < methods.Length; i++)
265 methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType);
270 internal override int GetCurrentToken()
272 return method.GetCurrentToken();
275 internal override bool IsBaked
277 get { return method.IsBaked; }
281 sealed class GenericFieldInstance : FieldInfo
283 private readonly Type declaringType;
284 private readonly FieldInfo field;
286 internal GenericFieldInstance(Type declaringType, FieldInfo field)
288 this.declaringType = declaringType;
292 public override bool Equals(object obj)
294 GenericFieldInstance other = obj as GenericFieldInstance;
295 return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
298 public override int GetHashCode()
300 return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
303 public override FieldAttributes Attributes
305 get { return field.Attributes; }
308 public override string Name
310 get { return field.Name; }
313 public override Type DeclaringType
315 get { return declaringType; }
318 public override Module Module
320 get { return declaringType.Module; }
323 public override int MetadataToken
325 get { return field.MetadataToken; }
328 public override object GetRawConstantValue()
330 return field.GetRawConstantValue();
333 public override void __GetDataFromRVA(byte[] data, int offset, int length)
335 field.__GetDataFromRVA(data, offset, length);
338 public override int __FieldRVA
340 get { return field.__FieldRVA; }
343 public override bool __TryGetFieldOffset(out int offset)
345 return field.__TryGetFieldOffset(out offset);
348 public override FieldInfo __GetFieldOnTypeDefinition()
353 internal override FieldSignature FieldSignature
355 get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
358 internal override int ImportTo(Emit.ModuleBuilder module)
360 return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
363 internal override FieldInfo BindTypeParameters(Type type)
365 return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
368 internal override int GetCurrentToken()
370 return field.GetCurrentToken();
373 internal override bool IsBaked
375 get { return field.IsBaked; }
379 sealed class GenericParameterInfoImpl : ParameterInfo
381 private readonly GenericMethodInstance method;
382 private readonly ParameterInfo parameterInfo;
384 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
386 this.method = method;
387 this.parameterInfo = parameterInfo;
390 public override string Name
392 get { return parameterInfo.Name; }
395 public override Type ParameterType
397 get { return parameterInfo.ParameterType.BindTypeParameters(method); }
400 public override ParameterAttributes Attributes
402 get { return parameterInfo.Attributes; }
405 public override int Position
407 get { return parameterInfo.Position; }
410 public override object RawDefaultValue
412 get { return parameterInfo.RawDefaultValue; }
415 public override CustomModifiers __GetCustomModifiers()
417 return parameterInfo.__GetCustomModifiers().Bind(method);
420 public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
422 return parameterInfo.__TryGetFieldMarshal(out fieldMarshal);
425 public override MemberInfo Member
427 get { return method; }
430 public override int MetadataToken
432 get { return parameterInfo.MetadataToken; }
435 internal override Module Module
437 get { return method.Module; }
441 sealed class GenericPropertyInfo : PropertyInfo
443 private readonly Type typeInstance;
444 private readonly PropertyInfo property;
446 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
448 this.typeInstance = typeInstance;
449 this.property = property;
452 public override bool Equals(object obj)
454 GenericPropertyInfo other = obj as GenericPropertyInfo;
455 return other != null && other.typeInstance == typeInstance && other.property == property;
458 public override int GetHashCode()
460 return typeInstance.GetHashCode() * 537 + property.GetHashCode();
463 public override PropertyAttributes Attributes
465 get { return property.Attributes; }
468 public override bool CanRead
470 get { return property.CanRead; }
473 public override bool CanWrite
475 get { return property.CanWrite; }
478 private MethodInfo Wrap(MethodInfo method)
484 return new GenericMethodInstance(typeInstance, method, null);
487 public override MethodInfo GetGetMethod(bool nonPublic)
489 return Wrap(property.GetGetMethod(nonPublic));
492 public override MethodInfo GetSetMethod(bool nonPublic)
494 return Wrap(property.GetSetMethod(nonPublic));
497 public override MethodInfo[] GetAccessors(bool nonPublic)
499 MethodInfo[] accessors = property.GetAccessors(nonPublic);
500 for (int i = 0; i < accessors.Length; i++)
502 accessors[i] = Wrap(accessors[i]);
507 public override object GetRawConstantValue()
509 return property.GetRawConstantValue();
512 internal override bool IsPublic
514 get { return property.IsPublic; }
517 internal override bool IsNonPrivate
519 get { return property.IsNonPrivate; }
522 internal override bool IsStatic
524 get { return property.IsStatic; }
527 internal override PropertySignature PropertySignature
529 get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
532 public override string Name
534 get { return property.Name; }
537 public override Type DeclaringType
539 get { return typeInstance; }
542 public override Module Module
544 get { return typeInstance.Module; }
547 public override int MetadataToken
549 get { return property.MetadataToken; }
552 internal override PropertyInfo BindTypeParameters(Type type)
554 return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
557 internal override bool IsBaked
559 get { return property.IsBaked; }
562 internal override int GetCurrentToken()
564 return property.GetCurrentToken();
568 sealed class GenericEventInfo : EventInfo
570 private readonly Type typeInstance;
571 private readonly EventInfo eventInfo;
573 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
575 this.typeInstance = typeInstance;
576 this.eventInfo = eventInfo;
579 public override bool Equals(object obj)
581 GenericEventInfo other = obj as GenericEventInfo;
582 return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
585 public override int GetHashCode()
587 return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
590 public override EventAttributes Attributes
592 get { return eventInfo.Attributes; }
595 private MethodInfo Wrap(MethodInfo method)
601 return new GenericMethodInstance(typeInstance, method, null);
604 public override MethodInfo GetAddMethod(bool nonPublic)
606 return Wrap(eventInfo.GetAddMethod(nonPublic));
609 public override MethodInfo GetRaiseMethod(bool nonPublic)
611 return Wrap(eventInfo.GetRaiseMethod(nonPublic));
614 public override MethodInfo GetRemoveMethod(bool nonPublic)
616 return Wrap(eventInfo.GetRemoveMethod(nonPublic));
619 public override MethodInfo[] GetOtherMethods(bool nonPublic)
621 MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
622 for (int i = 0; i < others.Length; i++)
624 others[i] = Wrap(others[i]);
629 public override MethodInfo[] __GetMethods()
631 MethodInfo[] others = eventInfo.__GetMethods();
632 for (int i = 0; i < others.Length; i++)
634 others[i] = Wrap(others[i]);
639 public override Type EventHandlerType
641 get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
644 public override string Name
646 get { return eventInfo.Name; }
649 public override Type DeclaringType
651 get { return typeInstance; }
654 public override Module Module
656 get { return eventInfo.Module; }
659 public override int MetadataToken
661 get { return eventInfo.MetadataToken; }
664 internal override EventInfo BindTypeParameters(Type type)
666 return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
669 internal override bool IsPublic
671 get { return eventInfo.IsPublic; }
674 internal override bool IsNonPrivate
676 get { return eventInfo.IsNonPrivate; }
679 internal override bool IsStatic
681 get { return eventInfo.IsStatic; }
684 internal override bool IsBaked
686 get { return eventInfo.IsBaked; }
689 internal override int GetCurrentToken()
691 return eventInfo.GetCurrentToken();