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