private void RenewFunction() { Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), Target.Value, Method) as TDelegate; }
protected override Expression VisitMethodCall(MethodCallExpression node) { var attributes = node.Method.GetCustomAttributes(typeof(SetExpressionRewriterAttribute), false); if (attributes != null) { var proxyAttribute = attributes.FirstOrDefault() as SetExpressionRewriterAttribute; if (proxyAttribute != null) { MethodInfo proxyMethod; if (!proxyAttribute.InitializeProxyMethod(node.Method, new Type[] { typeof(MethodCallExpression), typeof(SetExpressionRewriter) }, out proxyMethod)) { throw new InvalidOperationException($"The given expression rewriter method for method {node.Method.Name} has the wrong signature. It must accept parameters of type MethodCallExpression and SetExpressionRewriter."); } else if (proxyMethod != null && proxyMethod.IsStatic && proxyMethod.ReturnType == typeof(Expression)) { var func = ReflectionHelper.CreateDelegate <Func <MethodCallExpression, SetExpressionRewriter, Expression> >(proxyMethod); return(func(node, this)); } } } attributes = node.Method.GetCustomAttributes(typeof(LensPutAttribute), false); if (attributes != null && node.Method.ReturnType != typeof(void) && Value != null) { var lensPutAttribute = attributes.FirstOrDefault() as LensPutAttribute; if (lensPutAttribute != null) { MethodInfo lensMethod; var typeList = new List <Type>(node.Method.GetParameters().Select(p => p.ParameterType)); if (!node.Method.IsStatic) { typeList.Insert(0, node.Object.Type); } typeList.Add(node.Method.ReturnType); if (!lensPutAttribute.InitializeProxyMethod(node.Method, typeList.ToArray(), out lensMethod)) { typeList.RemoveAt(0); if (node.Method.IsStatic || !lensPutAttribute.InitializeProxyMethod(node.Method, typeList.ToArray(), out lensMethod)) { throw new InvalidOperationException($"The lens put method for method {node.Method.Name} has the wrong signature. It must accept the same parameter types as the original method plus the return type of the original method."); } else if (lensMethod != null && !lensMethod.IsStatic) { var args = new List <Expression>(node.Arguments); args.Add(Value); var call = Expression.Call(node.Object, lensMethod, args); if (lensMethod.ReturnType == typeof(void)) { Value = null; } else { Value = call; } return(call); } } else if (lensMethod != null && lensMethod.IsStatic) { var args = new List <Expression>(node.Arguments); args.Add(Value); if (!node.Method.IsStatic) { args.Insert(0, node.Object); } var call = Expression.Call(lensMethod, args); if (lensMethod.ReturnType == typeof(void)) { Value = null; return(call); } else { Value = call; if (node.Method.IsStatic) { return(Visit(node.Arguments[0])); } else { return(Visit(node.Object)); } } } } } return(null); }
public ObservableReversableMemberExpression(MemberExpression expression, ObservableExpressionBinder binder, string name, FieldInfo field) : this(binder.VisitObservable <TTarget>(expression.Expression, true), name, ReflectionHelper.CreateDynamicFieldGetter <TTarget, TMember>(field), ReflectionHelper.CreateDynamicFieldSetter <TTarget, TMember>(field)) { }
public ObservablePropertyMemberBinding(MemberAssignment node, ObservableExpressionBinder binder, INotifyExpression <T> target, FieldInfo field) : this(target, ReflectionHelper.CreateDynamicFieldSetter <T, TMember>(field), binder.VisitObservable <TMember>(node.Expression)) { }
public bool InitializeProxyMethod(MethodInfo sourceMethod, Type[] types, out MethodInfo proxyMethod) { if (types == null) { throw new ArgumentNullException("types"); } var proxyTypeArgs = new List <Type>(); if (ReflectionHelper.IsGenericType(sourceMethod.DeclaringType)) { proxyTypeArgs.AddRange(sourceMethod.DeclaringType.GetGenericArguments()); } if (sourceMethod.IsGenericMethod) { proxyTypeArgs.AddRange(sourceMethod.GetGenericArguments()); } var typeArrayPointer = 0; var proxyType = this.ProxyType; if (proxyType.IsGenericTypeDefinition) { var typeArgs = new Type[proxyType.GetGenericArguments().Length]; for (int i = 0; i < typeArgs.Length; i++) { typeArgs[i] = proxyTypeArgs[typeArrayPointer]; typeArrayPointer++; } proxyType = proxyType.MakeGenericType(typeArgs); } if (proxyTypeArgs.Count > typeArrayPointer) { var methodParamArgs = new Type[proxyTypeArgs.Count - typeArrayPointer]; for (int i = 0; i < methodParamArgs.Length; i++) { methodParamArgs[i] = proxyTypeArgs[i + typeArrayPointer]; } proxyMethod = proxyType.GetMethods().Select(m => { if (m.IsGenericMethodDefinition && m.Name == MethodName) { var methodTypeParameters = m.GetGenericArguments(); if (methodTypeParameters.Length != methodParamArgs.Length) { return(null); } var genericMethod = m.MakeGenericMethod(methodParamArgs); var parameters = genericMethod.GetParameters(); if (parameters.Length != types.Length) { return(null); } for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType != types[i]) { return(null); } } return(genericMethod); } return(null); }).FirstOrDefault(m => m != null); } else { proxyMethod = proxyType.GetMethod(MethodName, types); } return(proxyMethod != null); }
public ObservableBinaryExpression(BinaryExpression node, ObservableExpressionBinder binder) : this(binder.VisitObservable <TLeft>(node.Left), binder.VisitObservable <TRight>(node.Right), ReflectionHelper.CreateDelegate <Func <TLeft, TRight, TResult> >(node.Method)) { }
private bool IsNotifyValue(Type actual, Type spec) { return(ReflectionHelper.IsAssignableFrom(typeof(INotifyValue <>).MakeGenericType(spec), actual)); }
private Expression VisitProperty(MemberExpression node, PropertyInfo property) { object getter; if (!ReflectionHelper.IsValueType(property.DeclaringType)) { getter = ReflectionHelper.CreateDelegate(typeof(Func <,>).MakeGenericType(property.DeclaringType, property.PropertyType), ReflectionHelper.GetGetter(property)); } else { //TODO: This is a bug in the BCL, code here to get out of this shit var param = Expression.Parameter(property.DeclaringType); var expression = Expression.Lambda(Expression.Property(param, property), param); getter = expression.Compile(); } if (property.CanWrite) { var setter = ReflectionHelper.GetSetter(property); if (setter != null) { if (!ReflectionHelper.IsValueType(property.DeclaringType)) { return(System.Activator.CreateInstance(typeof(ObservableReversableMemberExpression <,>).MakeGenericType(property.DeclaringType, property.PropertyType), node, this, property.Name, getter, ReflectionHelper.CreateDelegate(typeof(Action <,>).MakeGenericType(property.DeclaringType, property.PropertyType), setter)) as Expression); } else { var setParam1 = Expression.Parameter(property.DeclaringType); var setParam2 = Expression.Parameter(property.PropertyType); var setExpression = Expression.Lambda(Expression.Assign(Expression.Property(setParam1, property), setParam2), setParam1, setParam2); return(System.Activator.CreateInstance(typeof(ObservableReversableMemberExpression <,>).MakeGenericType(property.DeclaringType, property.PropertyType), node, this, property.Name, getter, setExpression.Compile()) as Expression); } } } return(System.Activator.CreateInstance(typeof(ObservableMemberExpression <,>).MakeGenericType(property.DeclaringType, property.PropertyType), node, this, property.Name, getter) as Expression); }
private static ObservableMemberBinding <T> CreateProperty <T, TMember>(MemberAssignment node, ObservableExpressionBinder binder, INotifyExpression <T> target) { INotifyExpression <TMember> value = binder.VisitObservable <TMember>(node.Expression); var property = node.Member as PropertyInfo; var reversable = value as INotifyReversableExpression <TMember>; if (reversable != null && ReflectionHelper.IsAssignableFrom(typeof(INotifyPropertyChanged), typeof(T))) { return(new ObservableReversablePropertyMemberBinding <T, TMember>(target, node.Member.Name, ReflectionHelper.CreateDelegate(typeof(Func <T, TMember>), ReflectionHelper.GetGetter(property)) as Func <T, TMember>, ReflectionHelper.CreateDelegate(typeof(Action <T, TMember>), ReflectionHelper.GetSetter(property)) as Action <T, TMember>, reversable)); } return(new ObservablePropertyMemberBinding <T, TMember>(target, ReflectionHelper.CreateDelegate(typeof(Action <T, TMember>), ReflectionHelper.GetSetter(property)) as Action <T, TMember>, value)); }