diff options
author | jfrijters <jfrijters> | 2010-01-25 08:29:31 +0300 |
---|---|---|
committer | jfrijters <jfrijters> | 2010-01-25 08:29:31 +0300 |
commit | 198c9d70eac5d6d88718bfedee19314edf77661b (patch) | |
tree | cf6e13cb042f93d214c145fd405fefc19cb21b59 /reflect/GenericWrappers.cs | |
parent | 2966abd1dcb1eaa8fe692094f657943a9f2d21be (diff) |
New IKVM.Reflection implementation.
Diffstat (limited to 'reflect/GenericWrappers.cs')
-rw-r--r-- | reflect/GenericWrappers.cs | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/reflect/GenericWrappers.cs b/reflect/GenericWrappers.cs new file mode 100644 index 00000000..f8de11e3 --- /dev/null +++ b/reflect/GenericWrappers.cs @@ -0,0 +1,557 @@ +/* + Copyright (C) 2009 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace IKVM.Reflection +{ + // this represents both generic method instantiations and non-generic methods on generic type instantations + // (this means that it can be a generic method declaration as well as a generic method instance) + sealed class GenericMethodInstance : MethodInfo + { + private readonly Type declaringType; + private readonly MethodInfo method; + private readonly Type[] methodArgs; + private readonly MethodSignature signature; + + internal GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs) + { + this.declaringType = declaringType; + this.method = method; + this.methodArgs = methodArgs; + this.signature = method.MethodSignature.Bind(declaringType, methodArgs); + } + + public override bool Equals(object obj) + { + GenericMethodInstance other = obj as GenericMethodInstance; + return other != null + && other.method.Equals(method) + && other.declaringType.Equals(declaringType) + && Util.ArrayEquals(other.methodArgs, methodArgs); + } + + public override int GetHashCode() + { + return declaringType.GetHashCode() * 33 ^ method.GetHashCode() ^ Util.GetHashCode(methodArgs); + } + + public override Type ReturnType + { + get { return method.ReturnType.BindTypeParameters(this); } + } + + public override ParameterInfo ReturnParameter + { + get { return new GenericParameterInfoImpl(this, this, method.ReturnParameter); } + } + + public override ParameterInfo[] GetParameters() + { + ParameterInfo[] parameters = method.GetParameters(); + WrapGenericParameterInfos(this, this, parameters); + return parameters; + } + + internal override int ParameterCount + { + get { return method.ParameterCount; } + } + + public override CallingConventions CallingConvention + { + get { return method.CallingConvention; } + } + + public override MethodAttributes Attributes + { + get { return method.Attributes; } + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + return method.GetMethodImplementationFlags(); + } + + public override string Name + { + get { return method.Name; } + } + + public override Type DeclaringType + { + get { return declaringType; } + } + + public override Module Module + { + get { return method.Module; } + } + + public override int MetadataToken + { + get { return method.MetadataToken; } + } + + public override MethodBody GetMethodBody() + { + IKVM.Reflection.Reader.MethodDefImpl md = method as IKVM.Reflection.Reader.MethodDefImpl; + if (md != null) + { + return md.GetMethodBody(this); + } + throw new NotSupportedException(); + } + + public override MethodInfo MakeGenericMethod(params Type[] typeArguments) + { + return new GenericMethodInstance(declaringType, method, typeArguments); + } + + public override bool IsGenericMethod + { + get { return method.IsGenericMethod; } + } + + public override bool IsGenericMethodDefinition + { + get { return method.IsGenericMethodDefinition && methodArgs == null; } + } + + public override bool ContainsGenericParameters + { + get + { + if (declaringType.ContainsGenericParameters) + { + return true; + } + if (methodArgs != null) + { + foreach (Type type in methodArgs) + { + if (type.ContainsGenericParameters) + { + return true; + } + } + } + return false; + } + } + + public override MethodInfo GetGenericMethodDefinition() + { + if (this.IsGenericMethod) + { + if (this.IsGenericMethodDefinition) + { + return this; + } + else + { + return method.GetGenericMethodDefinition(); + } + } + throw new InvalidOperationException(); + } + + public override Type[] GetGenericArguments() + { + if (methodArgs == null) + { + return method.GetGenericArguments(); + } + else + { + return (Type[])methodArgs.Clone(); + } + } + + internal override Type GetGenericMethodArgument(int index) + { + if (methodArgs == null) + { + return method.GetGenericMethodArgument(index); + } + else + { + return methodArgs[index]; + } + } + + internal override int GetGenericMethodArgumentCount() + { + return method.GetGenericMethodArgumentCount(); + } + + internal override IList<CustomAttributeData> GetCustomAttributesData() + { + return method.GetCustomAttributesData(); + } + + internal override MethodInfo GetMethodOnTypeDefinition() + { + return method.GetMethodOnTypeDefinition(); + } + + internal override int ImportTo(Emit.ModuleBuilder module) + { + if (methodArgs == null) + { + return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature); + } + else + { + Writer.ByteBuffer spec = new Writer.ByteBuffer(10); + Signature.WriteMethodSpec(module, spec, methodArgs); + return module.ImportMethodSpec(method, spec); + } + } + + internal override MethodSignature MethodSignature + { + get { return signature; } + } + } + + sealed class GenericFieldInstance : FieldInfo + { + private readonly Type declaringType; + private readonly FieldInfo field; + + internal GenericFieldInstance(Type declaringType, FieldInfo field) + { + this.declaringType = declaringType; + this.field = field; + } + + public override bool Equals(object obj) + { + GenericFieldInstance other = obj as GenericFieldInstance; + return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field); + } + + public override int GetHashCode() + { + return declaringType.GetHashCode() * 3 ^ field.GetHashCode(); + } + + public override FieldAttributes Attributes + { + get { return field.Attributes; } + } + + public override string Name + { + get { return field.Name; } + } + + public override Type DeclaringType + { + get { return declaringType; } + } + + public override Module Module + { + get { return declaringType.Module; } + } + + public override int MetadataToken + { + get { return field.MetadataToken; } + } + + public override object GetRawConstantValue() + { + return field.GetRawConstantValue(); + } + + public override void __GetDataFromRVA(byte[] data) + { + field.__GetDataFromRVA(data); + } + + internal override IList<CustomAttributeData> GetCustomAttributesData() + { + return field.GetCustomAttributesData(); + } + + internal override FieldSignature FieldSignature + { + get { return field.FieldSignature.ExpandTypeParameters(declaringType); } + } + + internal override int ImportTo(Emit.ModuleBuilder module) + { + return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature); + } + } + + sealed class GenericParameterInfoImpl : ParameterInfo + { + private readonly MemberInfo member; + private readonly IGenericBinder binder; + private readonly ParameterInfo parameterInfo; + + internal GenericParameterInfoImpl(MemberInfo member, IGenericBinder binder, ParameterInfo parameterInfo) + { + this.member = member; + this.binder = binder; + this.parameterInfo = parameterInfo; + } + + public override string Name + { + get { return parameterInfo.Name; } + } + + public override Type ParameterType + { + get { return parameterInfo.ParameterType.BindTypeParameters(binder); } + } + + public override ParameterAttributes Attributes + { + get { return parameterInfo.Attributes; } + } + + public override int Position + { + get { return parameterInfo.Position; } + } + + public override object RawDefaultValue + { + get { return parameterInfo.RawDefaultValue; } + } + + public override Type[] GetOptionalCustomModifiers() + { + Type[] modifiers = parameterInfo.GetOptionalCustomModifiers(); + Type.InplaceBindTypeParameters(binder, modifiers); + return modifiers; + } + + public override Type[] GetRequiredCustomModifiers() + { + Type[] modifiers = parameterInfo.GetRequiredCustomModifiers(); + Type.InplaceBindTypeParameters(binder, modifiers); + return modifiers; + } + + public override MemberInfo Member + { + get { return member; } + } + + public override int MetadataToken + { + get { return parameterInfo.MetadataToken; } + } + + internal override Module Module + { + get { return member.Module; } + } + } + + sealed class GenericPropertyInfo : PropertyInfo + { + private readonly Type typeInstance; + private readonly PropertyInfo property; + + internal GenericPropertyInfo(Type typeInstance, PropertyInfo property) + { + this.typeInstance = typeInstance; + this.property = property; + } + + public override PropertyAttributes Attributes + { + get { return property.Attributes; } + } + + public override bool CanRead + { + get { return property.CanRead; } + } + + public override bool CanWrite + { + get { return property.CanWrite; } + } + + private MethodInfo Wrap(MethodInfo method) + { + if (method == null) + { + return null; + } + return new GenericMethodInstance(typeInstance, method, null); + } + + public override MethodInfo GetGetMethod(bool nonPublic) + { + return Wrap(property.GetGetMethod(nonPublic)); + } + + public override MethodInfo GetSetMethod(bool nonPublic) + { + return Wrap(property.GetSetMethod(nonPublic)); + } + + public override MethodInfo[] GetAccessors(bool nonPublic) + { + MethodInfo[] accessors = property.GetAccessors(nonPublic); + for (int i = 0; i < accessors.Length; i++) + { + accessors[i] = Wrap(accessors[i]); + } + return accessors; + } + + public override object GetRawConstantValue() + { + return property.GetRawConstantValue(); + } + + internal override bool IsPublic + { + get { return property.IsPublic; } + } + + internal override PropertySignature PropertySignature + { + get { return property.PropertySignature.ExpandTypeParameters(typeInstance); } + } + + public override string Name + { + get { return property.Name; } + } + + public override Type DeclaringType + { + get { return typeInstance; } + } + + public override Module Module + { + get { return typeInstance.Module; } + } + + public override int MetadataToken + { + get { return property.MetadataToken; } + } + + internal override IList<CustomAttributeData> GetCustomAttributesData() + { + return property.GetCustomAttributesData(); + } + } + + sealed class GenericEventInfo : EventInfo + { + private readonly Type typeInstance; + private readonly EventInfo eventInfo; + + internal GenericEventInfo(Type typeInstance, EventInfo eventInfo) + { + this.typeInstance = typeInstance; + this.eventInfo = eventInfo; + } + + public override EventAttributes Attributes + { + get { return eventInfo.Attributes; } + } + + private MethodInfo Wrap(MethodInfo method) + { + if (method == null) + { + return null; + } + return new GenericMethodInstance(typeInstance, method, null); + } + + public override MethodInfo GetAddMethod(bool nonPublic) + { + return Wrap(eventInfo.GetAddMethod(nonPublic)); + } + + public override MethodInfo GetRaiseMethod(bool nonPublic) + { + return Wrap(eventInfo.GetRaiseMethod(nonPublic)); + } + + public override MethodInfo GetRemoveMethod(bool nonPublic) + { + return Wrap(eventInfo.GetRemoveMethod(nonPublic)); + } + + public override MethodInfo[] GetOtherMethods(bool nonPublic) + { + MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic); + for (int i = 0; i < others.Length; i++) + { + others[i] = Wrap(others[i]); + } + return others; + } + + public override Type EventHandlerType + { + get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); } + } + + public override string Name + { + get { return eventInfo.Name; } + } + + public override Type DeclaringType + { + get { return typeInstance; } + } + + public override Module Module + { + get { return eventInfo.Module; } + } + + public override int MetadataToken + { + get { return eventInfo.MetadataToken; } + } + + internal override IList<CustomAttributeData> GetCustomAttributesData() + { + return eventInfo.GetCustomAttributesData(); + } + } +} |