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.IsGenericTypeInstance)
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 IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
229 return method.GetCustomAttributesData(attributeType);
232 internal override MethodInfo GetMethodOnTypeDefinition()
234 return method.GetMethodOnTypeDefinition();
237 internal override int ImportTo(Emit.ModuleBuilder module)
239 if (methodArgs == null)
241 return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
245 Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
246 Signature.WriteMethodSpec(module, spec, methodArgs);
247 Metadata.MethodSpecTable.Record rec = new Metadata.MethodSpecTable.Record();
248 Emit.MethodBuilder mb = method as Emit.MethodBuilder;
249 if (mb != null && mb.ModuleBuilder == module && !declaringType.IsGenericType)
251 rec.Method = mb.MetadataToken;
255 rec.Method = module.ImportMember(GetGenericMethodDefinition());
257 rec.Instantiation = module.Blobs.Add(spec);
258 return 0x2B000000 | module.MethodSpec.FindOrAddRecord(rec);
262 internal override MethodSignature MethodSignature
264 get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
267 internal override MethodBase BindTypeParameters(Type type)
269 System.Diagnostics.Debug.Assert(methodArgs == null);
270 return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
273 internal override bool HasThis
275 get { return method.HasThis; }
279 sealed class GenericFieldInstance : FieldInfo
281 private readonly Type declaringType;
282 private readonly FieldInfo field;
284 internal GenericFieldInstance(Type declaringType, FieldInfo field)
286 this.declaringType = declaringType;
290 public override bool Equals(object obj)
292 GenericFieldInstance other = obj as GenericFieldInstance;
293 return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
296 public override int GetHashCode()
298 return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
301 public override FieldAttributes Attributes
303 get { return field.Attributes; }
306 public override string Name
308 get { return field.Name; }
311 public override Type DeclaringType
313 get { return declaringType; }
316 public override Module Module
318 get { return declaringType.Module; }
321 public override int MetadataToken
323 get { return field.MetadataToken; }
326 public override object GetRawConstantValue()
328 return field.GetRawConstantValue();
331 public override void __GetDataFromRVA(byte[] data, int offset, int length)
333 field.__GetDataFromRVA(data, offset, length);
336 public override int __FieldRVA
338 get { return field.__FieldRVA; }
341 public override FieldInfo __GetFieldOnTypeDefinition()
346 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
348 return field.GetCustomAttributesData(attributeType);
351 internal override FieldSignature FieldSignature
353 get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
356 internal override int ImportTo(Emit.ModuleBuilder module)
358 return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
361 internal override FieldInfo BindTypeParameters(Type type)
363 return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
367 sealed class GenericParameterInfoImpl : ParameterInfo
369 private readonly GenericMethodInstance method;
370 private readonly ParameterInfo parameterInfo;
372 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
374 this.method = method;
375 this.parameterInfo = parameterInfo;
378 public override string Name
380 get { return parameterInfo.Name; }
383 public override Type ParameterType
385 get { return parameterInfo.ParameterType.BindTypeParameters(method); }
388 public override ParameterAttributes Attributes
390 get { return parameterInfo.Attributes; }
393 public override int Position
395 get { return parameterInfo.Position; }
398 public override object RawDefaultValue
400 get { return parameterInfo.RawDefaultValue; }
403 public override CustomModifiers __GetCustomModifiers()
405 return parameterInfo.__GetCustomModifiers().Bind(method);
408 public override MemberInfo Member
410 get { return method; }
413 public override int MetadataToken
415 get { return parameterInfo.MetadataToken; }
418 internal override Module Module
420 get { return method.Module; }
424 sealed class GenericPropertyInfo : PropertyInfo
426 private readonly Type typeInstance;
427 private readonly PropertyInfo property;
429 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
431 this.typeInstance = typeInstance;
432 this.property = property;
435 public override bool Equals(object obj)
437 GenericPropertyInfo other = obj as GenericPropertyInfo;
438 return other != null && other.typeInstance == typeInstance && other.property == property;
441 public override int GetHashCode()
443 return typeInstance.GetHashCode() * 537 + property.GetHashCode();
446 public override PropertyAttributes Attributes
448 get { return property.Attributes; }
451 public override bool CanRead
453 get { return property.CanRead; }
456 public override bool CanWrite
458 get { return property.CanWrite; }
461 private MethodInfo Wrap(MethodInfo method)
467 return new GenericMethodInstance(typeInstance, method, null);
470 public override MethodInfo GetGetMethod(bool nonPublic)
472 return Wrap(property.GetGetMethod(nonPublic));
475 public override MethodInfo GetSetMethod(bool nonPublic)
477 return Wrap(property.GetSetMethod(nonPublic));
480 public override MethodInfo[] GetAccessors(bool nonPublic)
482 MethodInfo[] accessors = property.GetAccessors(nonPublic);
483 for (int i = 0; i < accessors.Length; i++)
485 accessors[i] = Wrap(accessors[i]);
490 public override object GetRawConstantValue()
492 return property.GetRawConstantValue();
495 internal override bool IsPublic
497 get { return property.IsPublic; }
500 internal override bool IsStatic
502 get { return property.IsStatic; }
505 internal override PropertySignature PropertySignature
507 get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
510 public override string Name
512 get { return property.Name; }
515 public override Type DeclaringType
517 get { return typeInstance; }
520 public override Module Module
522 get { return typeInstance.Module; }
525 public override int MetadataToken
527 get { return property.MetadataToken; }
530 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
532 return property.GetCustomAttributesData(attributeType);
535 internal override PropertyInfo BindTypeParameters(Type type)
537 return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
541 sealed class GenericEventInfo : EventInfo
543 private readonly Type typeInstance;
544 private readonly EventInfo eventInfo;
546 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
548 this.typeInstance = typeInstance;
549 this.eventInfo = eventInfo;
552 public override bool Equals(object obj)
554 GenericEventInfo other = obj as GenericEventInfo;
555 return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
558 public override int GetHashCode()
560 return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
563 public override EventAttributes Attributes
565 get { return eventInfo.Attributes; }
568 private MethodInfo Wrap(MethodInfo method)
574 return new GenericMethodInstance(typeInstance, method, null);
577 public override MethodInfo GetAddMethod(bool nonPublic)
579 return Wrap(eventInfo.GetAddMethod(nonPublic));
582 public override MethodInfo GetRaiseMethod(bool nonPublic)
584 return Wrap(eventInfo.GetRaiseMethod(nonPublic));
587 public override MethodInfo GetRemoveMethod(bool nonPublic)
589 return Wrap(eventInfo.GetRemoveMethod(nonPublic));
592 public override MethodInfo[] GetOtherMethods(bool nonPublic)
594 MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
595 for (int i = 0; i < others.Length; i++)
597 others[i] = Wrap(others[i]);
602 public override MethodInfo[] __GetMethods()
604 MethodInfo[] others = eventInfo.__GetMethods();
605 for (int i = 0; i < others.Length; i++)
607 others[i] = Wrap(others[i]);
612 public override Type EventHandlerType
614 get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
617 public override string Name
619 get { return eventInfo.Name; }
622 public override Type DeclaringType
624 get { return typeInstance; }
627 public override Module Module
629 get { return eventInfo.Module; }
632 public override int MetadataToken
634 get { return eventInfo.MetadataToken; }
637 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
639 return eventInfo.GetCustomAttributesData(attributeType);
642 internal override EventInfo BindTypeParameters(Type type)
644 return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
647 internal override bool IsPublic
649 get { return eventInfo.IsPublic; }
652 internal override bool IsStatic
654 get { return eventInfo.IsStatic; }