예제 #1
0
 private void RenewFunction()
 {
     Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), Target.Value, Method) as TDelegate;
 }
예제 #2
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);
        }
 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))
 {
 }
예제 #4
0
 public ObservablePropertyMemberBinding(MemberAssignment node, ObservableExpressionBinder binder, INotifyExpression <T> target, FieldInfo field)
     : this(target, ReflectionHelper.CreateDynamicFieldSetter <T, TMember>(field), binder.VisitObservable <TMember>(node.Expression))
 {
 }
예제 #5
0
        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);
        }
예제 #6
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))
 {
 }
 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));
        }