예제 #1
0
 public ObservableReversableBinaryExpression(BinaryExpression node, ObservableExpressionBinder binder, MethodInfo leftReverser, MethodInfo rightReverser)
     : this(
         binder.VisitObservable <TLeft>(node.Left),
         binder.VisitObservable <TRight>(node.Right),
         ReflectionHelper.CreateDelegate <Func <TLeft, TRight, TResult> >(node.Method),
         rightReverser != null ? ReflectionHelper.CreateDelegate <Func <TResult, TRight, TLeft> >(rightReverser) : null,
         leftReverser != null ? ReflectionHelper.CreateDelegate <Func <TResult, TLeft, TRight> >(leftReverser) : null)
 {
 }
예제 #2
0
        public ObservableStaticMethodBase(MethodInfo method)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), method) as TDelegate;
        }
        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));
        }
예제 #4
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var rewriterAttributes = ReflectionHelper.GetCustomAttributes <ExpressionCompileRewriterAttribute>(node.Method, false);

            if (rewriterAttributes != null && rewriterAttributes.Length == 1)
            {
                var        rewriteAtt = rewriterAttributes[0];
                MethodInfo rewriter;
                if (!rewriteAtt.InitializeProxyMethod(node.Method, new Type[] { typeof(MethodCallExpression) }, out rewriter))
                {
                    throw new InvalidOperationException("The rewriter method had the wrong signature. It must be a method taking a MethodCallExpression as parameter.");
                }
                var rewriterDelegate = ReflectionHelper.CreateDelegate <Func <MethodCallExpression, Expression> >(rewriter);
                return(rewriterDelegate.Invoke(node));
            }
            return(base.VisitMethodCall(node));
        }
예제 #5
0
        public ObservableListInitializer(INotifyExpression <T> target, INotifyExpression <TElement> value, MethodInfo addMethod)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (addMethod == null)
            {
                throw new ArgumentNullException("addMethod");
            }

            Target = target;
            Value  = value;

            AddAction = ReflectionHelper.CreateDelegate <Action <T, TElement> >(addMethod);
            var removeMethod = ReflectionHelper.GetRemoveMethod(typeof(T), typeof(TElement));

            if (removeMethod == null)
            {
                throw new InvalidOperationException("Could not find appropriate Remove method for " + addMethod.Name);
            }
            if (removeMethod.ReturnType == typeof(void))
            {
                RemoveAction = ReflectionHelper.CreateDelegate <Action <T, TElement> >(removeMethod);
            }
            else if (removeMethod.ReturnType == typeof(bool))
            {
                var tempAction = ReflectionHelper.CreateDelegate <Func <T, TElement, bool> >(removeMethod);
                RemoveAction = (o, i) => tempAction(o, i);
            }
            else
            {
                throw new NotSupportedException();
            }
        }
        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);
        }
예제 #7
0
        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(string.Format("The given expression rewriter method for method {0} has the wrong signature. It must accept parameters of type MethodCallExpression and SetExpressionRewriter.", node.Method.Name));
                    }
                    else if (proxyMethod != null && proxyMethod.IsStatic && proxyMethod.ReturnType == typeof(Expression))
                    {
                        var func = ReflectionHelper.CreateDelegate <Func <MethodCallExpression, SetExpressionRewriter, Expression> >(proxyMethod);
                        return(func(node, this));
                    }
                }
            }
            return(null);
        }
예제 #8
0
 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))
 {
 }
예제 #9
0
 private void RenewFunction()
 {
     Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), Target.Value, Method) as TDelegate;
 }
예제 #10
0
 public ObservableUnaryExpression(UnaryExpression node, ObservableExpressionBinder binder)
     : this(binder.VisitObservable <TInner>(node.Operand), ReflectionHelper.CreateDelegate <Func <TInner, TOuter> >(node.Method))
 {
 }
예제 #11
0
        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);
        }