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();