You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

279 lines
7.9 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Globalization;
using ILRuntime.CLR.Method;
using ILRuntime.CLR.TypeSystem;
namespace ILRuntime.Reflection
{
public class ILRuntimePropertyInfo : PropertyInfo
{
ILMethod getter, setter;
ILType dType;
Mono.Cecil.PropertyDefinition definition;
ILRuntime.Runtime.Enviorment.AppDomain appdomain;
ILRuntimeParameterInfo[] parameters;
Attribute[] customAttributes;
Type[] attributeTypes;
public ILMethod Getter
{
get { return getter; }
set
{
getter = value;
}
}
public ILMethod Setter
{
get { return setter; }
set
{
setter = value;
}
}
public bool IsPublic
{
get
{
if (getter != null)
return getter.Definition.IsPublic;
else
return setter.Definition.IsPublic;
}
}
public bool IsStatic
{
get
{
if (getter != null)
return getter.IsStatic;
else
return setter.IsStatic;
}
}
public ILRuntimePropertyInfo(Mono.Cecil.PropertyDefinition definition, ILType dType)
{
this.definition = definition;
this.dType = dType;
appdomain = dType.AppDomain;
parameters = new ILRuntimeParameterInfo[definition.Parameters.Count];
for (int i = 0; i < definition.Parameters.Count; i++)
{
var pd = definition.Parameters[i];
var parameterType = dType.AppDomain.GetType(pd.ParameterType, null, null);
parameters[i] = new ILRuntimeParameterInfo(pd, parameterType, this, appdomain);
}
}
void InitializeCustomAttribute()
{
customAttributes = new Attribute[definition.CustomAttributes.Count];
attributeTypes = new Type[customAttributes.Length];
for (int i = 0; i < definition.CustomAttributes.Count; i++)
{
var attribute = definition.CustomAttributes[i];
var at = appdomain.GetType(attribute.AttributeType, null, null);
try
{
Attribute ins = attribute.CreateInstance(at, appdomain) as Attribute;
attributeTypes[i] = at.ReflectionType;
customAttributes[i] = ins;
}
catch
{
attributeTypes[i] = typeof(Attribute);
}
}
}
public override string Name
{
get
{
return definition.Name;
}
}
public override Type ReflectedType
{
get
{
return dType.ReflectionType;
}
}
public override PropertyAttributes Attributes
{
get
{
return PropertyAttributes.None;
}
}
public override bool CanRead
{
get
{
return getter != null;
}
}
public override bool CanWrite
{
get
{
return setter != null;
}
}
public override Type PropertyType
{
get
{
if (getter != null)
return getter.ReturnType.ReflectionType;
else
{
return setter.Parameters[0].ReflectionType;
}
}
}
public ILRuntime.Mono.Cecil.TypeReference Definition
{
get
{
return definition.GetMethod != null ? definition.GetMethod.ReturnType : definition.SetMethod.Parameters[0].ParameterType;
}
}
public override Type DeclaringType
{
get
{
return dType.ReflectionType;
}
}
public override object[] GetCustomAttributes(bool inherit)
{
if (customAttributes == null)
InitializeCustomAttribute();
return customAttributes;
}
public override object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (customAttributes == null)
InitializeCustomAttribute();
List<object> res = new List<object>();
for (int i = 0; i < customAttributes.Length; i++)
{
if (attributeTypes[i].Equals(attributeType))
{
res.Add(customAttributes[i]);
}
}
return res.ToArray();
}
public override bool IsDefined(Type attributeType, bool inherit)
{
if (customAttributes == null)
InitializeCustomAttribute();
for (int i = 0; i < customAttributes.Length; i++)
{
if (attributeTypes[i].Equals(attributeType))
{
return true;
}
}
return false;
}
public override MethodInfo[] GetAccessors(bool nonPublic)
{
throw new NotImplementedException();
}
public override MethodInfo GetGetMethod(bool nonPublic)
{
if (getter != null)
return getter.ReflectionMethodInfo;
return null;
}
public override ParameterInfo[] GetIndexParameters()
{
return parameters;
}
public override MethodInfo GetSetMethod(bool nonPublic)
{
if (setter != null)
return setter.ReflectionMethodInfo;
return null;
}
public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
{
var indexCnt = index != null ? index.Length : 0;
if (getter.ParameterCount <= indexCnt)
{
using (var ctx = appdomain.BeginInvoke(getter))
{
if (!IsStatic)
ctx.PushObject(obj);
for (int i = 0; i < getter.ParameterCount; i++)
{
ctx.PushObject(index[i], !getter.Parameters[i].IsValueType);
}
ctx.Invoke();
return ctx.ReadObject(getter.ReturnType.TypeForCLR);
}
}
else
throw new ArgumentException("Index count mismatch");
}
public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
{
var indexCnt = index != null ? index.Length : 0;
if (setter.ParameterCount <= indexCnt + 1)
{
using (var ctx = appdomain.BeginInvoke(setter))
{
if (!IsStatic)
ctx.PushObject(obj);
for (int i = 0; i < setter.ParameterCount - 1; i++)
{
ctx.PushObject(index[i], !setter.Parameters[i].IsValueType);
}
ctx.PushObject(value, !setter.Parameters[setter.ParameterCount - 1].IsValueType);
ctx.Invoke();
}
}
else
throw new ArgumentException("Index count mismatch");
}
public override string ToString()
{
return definition == null ? base.ToString() : definition.ToString();
}
}
}