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 MethodInfo MakeGenericMethod(params Type[] typeArguments)
133 return new GenericMethodInstance(declaringType, method, typeArguments);
136 public override bool IsGenericMethod
138 get { return method.IsGenericMethod; }
141 public override bool IsGenericMethodDefinition
143 get { return method.IsGenericMethodDefinition && methodArgs == null; }
146 public override bool ContainsGenericParameters
150 if (declaringType.ContainsGenericParameters)
154 if (methodArgs != null)
156 foreach (Type type in methodArgs)
158 if (type.ContainsGenericParameters)
168 public override MethodInfo GetGenericMethodDefinition()
170 if (this.IsGenericMethod)
172 if (this.IsGenericMethodDefinition)
176 else if (declaringType.IsGenericTypeInstance)
178 return new GenericMethodInstance(declaringType, method, null);
185 throw new InvalidOperationException();
188 public override MethodBase __GetMethodOnTypeDefinition()
193 public override Type[] GetGenericArguments()
195 if (methodArgs == null)
197 return method.GetGenericArguments();
201 return (Type[])methodArgs.Clone();
205 internal override Type GetGenericMethodArgument(int index)
207 if (methodArgs == null)
209 return method.GetGenericMethodArgument(index);
213 return methodArgs[index];
217 internal override int GetGenericMethodArgumentCount()
219 return method.GetGenericMethodArgumentCount();
222 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
224 return method.GetCustomAttributesData(attributeType);
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 Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
241 Signature.WriteMethodSpec(module, spec, methodArgs);
242 Metadata.MethodSpecTable.Record rec = new Metadata.MethodSpecTable.Record();
243 Emit.MethodBuilder mb = method as Emit.MethodBuilder;
244 if (mb != null && mb.ModuleBuilder == module && !declaringType.IsGenericType)
246 rec.Method = mb.MetadataToken;
250 rec.Method = module.ImportMember(GetGenericMethodDefinition());
252 rec.Instantiation = module.Blobs.Add(spec);
253 return 0x2B000000 | module.MethodSpec.FindOrAddRecord(rec);
257 internal override MethodSignature MethodSignature
259 get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
262 internal override MethodBase BindTypeParameters(Type type)
264 System.Diagnostics.Debug.Assert(methodArgs == null);
265 return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
268 internal override bool HasThis
270 get { return method.HasThis; }
274 sealed class GenericFieldInstance : FieldInfo
276 private readonly Type declaringType;
277 private readonly FieldInfo field;
279 internal GenericFieldInstance(Type declaringType, FieldInfo field)
281 this.declaringType = declaringType;
285 public override bool Equals(object obj)
287 GenericFieldInstance other = obj as GenericFieldInstance;
288 return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
291 public override int GetHashCode()
293 return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
296 public override FieldAttributes Attributes
298 get { return field.Attributes; }
301 public override string Name
303 get { return field.Name; }
306 public override Type DeclaringType
308 get { return declaringType; }
311 public override Module Module
313 get { return declaringType.Module; }
316 public override int MetadataToken
318 get { return field.MetadataToken; }
321 public override object GetRawConstantValue()
323 return field.GetRawConstantValue();
326 public override void __GetDataFromRVA(byte[] data, int offset, int length)
328 field.__GetDataFromRVA(data, offset, length);
331 public override int __FieldRVA
333 get { return field.__FieldRVA; }
336 public override FieldInfo __GetFieldOnTypeDefinition()
341 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
343 return field.GetCustomAttributesData(attributeType);
346 internal override FieldSignature FieldSignature
348 get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
351 internal override int ImportTo(Emit.ModuleBuilder module)
353 return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
356 internal override FieldInfo BindTypeParameters(Type type)
358 return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
362 sealed class GenericParameterInfoImpl : ParameterInfo
364 private readonly GenericMethodInstance method;
365 private readonly ParameterInfo parameterInfo;
367 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
369 this.method = method;
370 this.parameterInfo = parameterInfo;
373 public override string Name
375 get { return parameterInfo.Name; }
378 public override Type ParameterType
380 get { return parameterInfo.ParameterType.BindTypeParameters(method); }
383 public override ParameterAttributes Attributes
385 get { return parameterInfo.Attributes; }
388 public override int Position
390 get { return parameterInfo.Position; }
393 public override object RawDefaultValue
395 get { return parameterInfo.RawDefaultValue; }
398 public override Type[] GetOptionalCustomModifiers()
400 Type[] modifiers = parameterInfo.GetOptionalCustomModifiers();
401 Type.InplaceBindTypeParameters(method, modifiers);
405 public override Type[] GetRequiredCustomModifiers()
407 Type[] modifiers = parameterInfo.GetRequiredCustomModifiers();
408 Type.InplaceBindTypeParameters(method, modifiers);
412 public override MemberInfo Member
414 get { return method; }
417 public override int MetadataToken
419 get { return parameterInfo.MetadataToken; }
422 internal override Module Module
424 get { return method.Module; }
428 sealed class GenericPropertyInfo : PropertyInfo
430 private readonly Type typeInstance;
431 private readonly PropertyInfo property;
433 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
435 this.typeInstance = typeInstance;
436 this.property = property;
439 public override bool Equals(object obj)
441 GenericPropertyInfo other = obj as GenericPropertyInfo;
442 return other != null && other.typeInstance == typeInstance && other.property == property;
445 public override int GetHashCode()
447 return typeInstance.GetHashCode() * 537 + property.GetHashCode();
450 public override PropertyAttributes Attributes
452 get { return property.Attributes; }
455 public override bool CanRead
457 get { return property.CanRead; }
460 public override bool CanWrite
462 get { return property.CanWrite; }
465 private MethodInfo Wrap(MethodInfo method)
471 return new GenericMethodInstance(typeInstance, method, null);
474 public override MethodInfo GetGetMethod(bool nonPublic)
476 return Wrap(property.GetGetMethod(nonPublic));
479 public override MethodInfo GetSetMethod(bool nonPublic)
481 return Wrap(property.GetSetMethod(nonPublic));
484 public override MethodInfo[] GetAccessors(bool nonPublic)
486 MethodInfo[] accessors = property.GetAccessors(nonPublic);
487 for (int i = 0; i < accessors.Length; i++)
489 accessors[i] = Wrap(accessors[i]);
494 public override object GetRawConstantValue()
496 return property.GetRawConstantValue();
499 internal override bool IsPublic
501 get { return property.IsPublic; }
504 internal override bool IsStatic
506 get { return property.IsStatic; }
509 internal override PropertySignature PropertySignature
511 get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
514 public override string Name
516 get { return property.Name; }
519 public override Type DeclaringType
521 get { return typeInstance; }
524 public override Module Module
526 get { return typeInstance.Module; }
529 public override int MetadataToken
531 get { return property.MetadataToken; }
534 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
536 return property.GetCustomAttributesData(attributeType);
539 internal override PropertyInfo BindTypeParameters(Type type)
541 return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
545 sealed class GenericEventInfo : EventInfo
547 private readonly Type typeInstance;
548 private readonly EventInfo eventInfo;
550 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
552 this.typeInstance = typeInstance;
553 this.eventInfo = eventInfo;
556 public override bool Equals(object obj)
558 GenericEventInfo other = obj as GenericEventInfo;
559 return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
562 public override int GetHashCode()
564 return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
567 public override EventAttributes Attributes
569 get { return eventInfo.Attributes; }
572 private MethodInfo Wrap(MethodInfo method)
578 return new GenericMethodInstance(typeInstance, method, null);
581 public override MethodInfo GetAddMethod(bool nonPublic)
583 return Wrap(eventInfo.GetAddMethod(nonPublic));
586 public override MethodInfo GetRaiseMethod(bool nonPublic)
588 return Wrap(eventInfo.GetRaiseMethod(nonPublic));
591 public override MethodInfo GetRemoveMethod(bool nonPublic)
593 return Wrap(eventInfo.GetRemoveMethod(nonPublic));
596 public override MethodInfo[] GetOtherMethods(bool nonPublic)
598 MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
599 for (int i = 0; i < others.Length; i++)
601 others[i] = Wrap(others[i]);
606 public override MethodInfo[] __GetMethods()
608 MethodInfo[] others = eventInfo.__GetMethods();
609 for (int i = 0; i < others.Length; i++)
611 others[i] = Wrap(others[i]);
616 public override Type EventHandlerType
618 get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
621 public override string Name
623 get { return eventInfo.Name; }
626 public override Type DeclaringType
628 get { return typeInstance; }
631 public override Module Module
633 get { return eventInfo.Module; }
636 public override int MetadataToken
638 get { return eventInfo.MetadataToken; }
641 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
643 return eventInfo.GetCustomAttributesData(attributeType);
646 internal override EventInfo BindTypeParameters(Type type)
648 return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
651 internal override bool IsPublic
653 get { return eventInfo.IsPublic; }
656 internal override bool IsStatic
658 get { return eventInfo.IsStatic; }