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; }
278 public override MethodInfo[] __GetMethodImpls()
280 MethodInfo[] methods = method.__GetMethodImpls();
281 for (int i = 0; i < methods.Length; i++)
283 methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType);
289 sealed class GenericFieldInstance : FieldInfo
291 private readonly Type declaringType;
292 private readonly FieldInfo field;
294 internal GenericFieldInstance(Type declaringType, FieldInfo field)
296 this.declaringType = declaringType;
300 public override bool Equals(object obj)
302 GenericFieldInstance other = obj as GenericFieldInstance;
303 return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
306 public override int GetHashCode()
308 return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
311 public override FieldAttributes Attributes
313 get { return field.Attributes; }
316 public override string Name
318 get { return field.Name; }
321 public override Type DeclaringType
323 get { return declaringType; }
326 public override Module Module
328 get { return declaringType.Module; }
331 public override int MetadataToken
333 get { return field.MetadataToken; }
336 public override object GetRawConstantValue()
338 return field.GetRawConstantValue();
341 public override void __GetDataFromRVA(byte[] data, int offset, int length)
343 field.__GetDataFromRVA(data, offset, length);
346 public override int __FieldRVA
348 get { return field.__FieldRVA; }
351 public override FieldInfo __GetFieldOnTypeDefinition()
356 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
358 return field.GetCustomAttributesData(attributeType);
361 internal override FieldSignature FieldSignature
363 get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
366 internal override int ImportTo(Emit.ModuleBuilder module)
368 return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
371 internal override FieldInfo BindTypeParameters(Type type)
373 return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
377 sealed class GenericParameterInfoImpl : ParameterInfo
379 private readonly GenericMethodInstance method;
380 private readonly ParameterInfo parameterInfo;
382 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
384 this.method = method;
385 this.parameterInfo = parameterInfo;
388 public override string Name
390 get { return parameterInfo.Name; }
393 public override Type ParameterType
395 get { return parameterInfo.ParameterType.BindTypeParameters(method); }
398 public override ParameterAttributes Attributes
400 get { return parameterInfo.Attributes; }
403 public override int Position
405 get { return parameterInfo.Position; }
408 public override object RawDefaultValue
410 get { return parameterInfo.RawDefaultValue; }
413 public override CustomModifiers __GetCustomModifiers()
415 return parameterInfo.__GetCustomModifiers().Bind(method);
418 public override MemberInfo Member
420 get { return method; }
423 public override int MetadataToken
425 get { return parameterInfo.MetadataToken; }
428 internal override Module Module
430 get { return method.Module; }
434 sealed class GenericPropertyInfo : PropertyInfo
436 private readonly Type typeInstance;
437 private readonly PropertyInfo property;
439 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
441 this.typeInstance = typeInstance;
442 this.property = property;
445 public override bool Equals(object obj)
447 GenericPropertyInfo other = obj as GenericPropertyInfo;
448 return other != null && other.typeInstance == typeInstance && other.property == property;
451 public override int GetHashCode()
453 return typeInstance.GetHashCode() * 537 + property.GetHashCode();
456 public override PropertyAttributes Attributes
458 get { return property.Attributes; }
461 public override bool CanRead
463 get { return property.CanRead; }
466 public override bool CanWrite
468 get { return property.CanWrite; }
471 private MethodInfo Wrap(MethodInfo method)
477 return new GenericMethodInstance(typeInstance, method, null);
480 public override MethodInfo GetGetMethod(bool nonPublic)
482 return Wrap(property.GetGetMethod(nonPublic));
485 public override MethodInfo GetSetMethod(bool nonPublic)
487 return Wrap(property.GetSetMethod(nonPublic));
490 public override MethodInfo[] GetAccessors(bool nonPublic)
492 MethodInfo[] accessors = property.GetAccessors(nonPublic);
493 for (int i = 0; i < accessors.Length; i++)
495 accessors[i] = Wrap(accessors[i]);
500 public override object GetRawConstantValue()
502 return property.GetRawConstantValue();
505 internal override bool IsPublic
507 get { return property.IsPublic; }
510 internal override bool IsNonPrivate
512 get { return property.IsNonPrivate; }
515 internal override bool IsStatic
517 get { return property.IsStatic; }
520 internal override PropertySignature PropertySignature
522 get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
525 public override string Name
527 get { return property.Name; }
530 public override Type DeclaringType
532 get { return typeInstance; }
535 public override Module Module
537 get { return typeInstance.Module; }
540 public override int MetadataToken
542 get { return property.MetadataToken; }
545 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
547 return property.GetCustomAttributesData(attributeType);
550 internal override PropertyInfo BindTypeParameters(Type type)
552 return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
556 sealed class GenericEventInfo : EventInfo
558 private readonly Type typeInstance;
559 private readonly EventInfo eventInfo;
561 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
563 this.typeInstance = typeInstance;
564 this.eventInfo = eventInfo;
567 public override bool Equals(object obj)
569 GenericEventInfo other = obj as GenericEventInfo;
570 return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
573 public override int GetHashCode()
575 return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
578 public override EventAttributes Attributes
580 get { return eventInfo.Attributes; }
583 private MethodInfo Wrap(MethodInfo method)
589 return new GenericMethodInstance(typeInstance, method, null);
592 public override MethodInfo GetAddMethod(bool nonPublic)
594 return Wrap(eventInfo.GetAddMethod(nonPublic));
597 public override MethodInfo GetRaiseMethod(bool nonPublic)
599 return Wrap(eventInfo.GetRaiseMethod(nonPublic));
602 public override MethodInfo GetRemoveMethod(bool nonPublic)
604 return Wrap(eventInfo.GetRemoveMethod(nonPublic));
607 public override MethodInfo[] GetOtherMethods(bool nonPublic)
609 MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
610 for (int i = 0; i < others.Length; i++)
612 others[i] = Wrap(others[i]);
617 public override MethodInfo[] __GetMethods()
619 MethodInfo[] others = eventInfo.__GetMethods();
620 for (int i = 0; i < others.Length; i++)
622 others[i] = Wrap(others[i]);
627 public override Type EventHandlerType
629 get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
632 public override string Name
634 get { return eventInfo.Name; }
637 public override Type DeclaringType
639 get { return typeInstance; }
642 public override Module Module
644 get { return eventInfo.Module; }
647 public override int MetadataToken
649 get { return eventInfo.MetadataToken; }
652 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
654 return eventInfo.GetCustomAttributesData(attributeType);
657 internal override EventInfo BindTypeParameters(Type type)
659 return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
662 internal override bool IsPublic
664 get { return eventInfo.IsPublic; }
667 internal override bool IsNonPrivate
669 get { return eventInfo.IsNonPrivate; }
672 internal override bool IsStatic
674 get { return eventInfo.IsStatic; }