Exemplo n.º 1
0
        public static PropertyAccessTree Analyze <T, TResult>(Expression <Func <T, TResult> > expression, Predicate <Type> type_filter)
        {
            if (!type_filter(typeof(T)))
            {
                return(null);
            }

            PropertyAccessTree tree = AnalyzeLambda(expression, type_filter);

            return(tree);
        }
Exemplo n.º 2
0
            public PropertyAccessTreeSubscriberINotifyPropertyChanging(PropertyAccessTree propertyAccessTree, Action <TListener, object> subscriberCallback)
            {
                _subscriptions = new List <RootSubscription>();

                _propertyAccessTree = propertyAccessTree;

                foreach (PropertyAccessTreeNode t in propertyAccessTree.Children)
                {
                    var rootSubscription = new RootSubscription(subscriberCallback, t);
                    _subscriptions.Add(rootSubscription);
                }
            }
Exemplo n.º 3
0
        private static PropertyAccessTree AnalyzeLambda(LambdaExpression expression, Predicate <Type> type_filter)
        {
            PropertyAccessTree tree = new PropertyAccessTree();

            //This is done to ensure that the tree has all the parameters and in the same order.
            for (int i = 0; i < expression.Parameters.Count; i++)
            {
                ParameterExpression parameterExpression = expression.Parameters[0];
                tree.Children.Add(new ParameterNode(parameterExpression.Type, parameterExpression.Name));
            }
            BuildUnoptimizedTree(tree, expression.Body, type_filter);

            RemoveRedundantNodesFromTree(tree.Children);
            ApplyTypeFilter(tree.Children, type_filter);

            return(tree);
        }
Exemplo n.º 4
0
        private static void AddBranch(PropertyAccessTree tree, Stack <PropertyAccessTreeNode> currentNodeBranch)
        {
            if (currentNodeBranch.Count == 0)
            {
                return;
            }

            PropertyAccessTreeNode currentNode = currentNodeBranch.Pop();

            tree.Children.Add(currentNode);

            while (currentNodeBranch.Count != 0)
            {
                PropertyAccessTreeNode nextNode = currentNodeBranch.Pop();
                currentNode.Children.Add(nextNode);
                currentNode = nextNode;
            }
        }
Exemplo n.º 5
0
        public DependencyMethod <T> OnChanged <TResult>(Expression <Func <T, TResult> > propertyAccessor)
        {
            PropertyAccessTree property_access_tree = ExpressionPropertyAnalyzer.Analyze(propertyAccessor);

            if (!property_access_tree.DoesEntireTreeSupportINotifyPropertyChanging)
            {
                throw new ArgumentException("All objects must implement INotifyPropertyChanging");
            }

            if (property_change_subscribers == null)
            {
                property_change_subscribers = new List <IPropertyAccessTreeSubscriber <DependencyMethod <T> > >();
            }

            var subscriber = property_access_tree.CreateCallbackSubscription <DependencyMethod <T> >(OnAnyPropertyInSubscriptionChanges);

            property_change_subscribers.Add(subscriber);

            return(this);
        }
Exemplo n.º 6
0
        private static void BuildBranches(Expression expression, PropertyAccessTree tree, Stack <PropertyAccessTreeNode> current_node_branch, Predicate <Type> type_filter)
        {
            BinaryExpression binaryExpression = expression as BinaryExpression;

            if (binaryExpression != null)
            {
                BuildBranches(binaryExpression.Left, tree, current_node_branch, type_filter);
                BuildBranches(binaryExpression.Right, tree, current_node_branch, type_filter);
                return;
            }

            UnaryExpression unaryExpression = expression as UnaryExpression;

            if (unaryExpression != null)
            {
                BuildBranches(unaryExpression.Operand, tree, current_node_branch, type_filter);
                return;
            }

            MethodCallExpression methodCallExpression = expression as MethodCallExpression;

            if (methodCallExpression != null)
            {
                foreach (Expression argument in methodCallExpression.Arguments)
                {
                    BuildBranches(argument, tree, current_node_branch, type_filter);
                }
                return;
            }

            ConditionalExpression conditionalExpression = expression as ConditionalExpression;

            if (conditionalExpression != null)
            {
                BuildBranches(conditionalExpression.Test, tree, current_node_branch, type_filter);
                BuildBranches(conditionalExpression.IfTrue, tree, current_node_branch, type_filter);
                BuildBranches(conditionalExpression.IfFalse, tree, current_node_branch, type_filter);
                return;
            }

            InvocationExpression invocationExpression = expression as InvocationExpression;

            if (invocationExpression != null)
            {
                foreach (Expression argument in invocationExpression.Arguments)
                {
                    BuildBranches(argument, tree, current_node_branch, type_filter);
                }
                BuildBranches(invocationExpression.Expression, tree, current_node_branch, type_filter);
                return;
            }

            switch (expression.NodeType)
            {
            case ExpressionType.MemberAccess:
                MemberExpression memberExpression = (MemberExpression)expression;

                PropertyInfo property  = memberExpression.Member as PropertyInfo;
                FieldInfo    fieldInfo = memberExpression.Member as FieldInfo;
                if (property != null)
                {
                    PropertyAccessNode node = new PropertyAccessNode(property);
                    current_node_branch.Push(node);

                    BuildBranches(memberExpression.Expression, tree, current_node_branch, type_filter);
                }
                else if (fieldInfo != null)
                {
                    if (type_filter(fieldInfo.FieldType))
                    {
                        ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
                        if (constantExpression.Value != null)
                        {
                            object       value        = fieldInfo.GetValue(constantExpression.Value);
                            ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)value);
                            current_node_branch.Push(constantNode);
                            AddBranch(tree, current_node_branch);
                        }
                    }
                    else
                    {
                        current_node_branch.Clear();
                    }
                }
                else
                {
                    BuildBranches(memberExpression.Expression, tree, current_node_branch, type_filter);
                }

                break;

            case ExpressionType.Parameter:
                ParameterExpression parameterExpression = (ParameterExpression)expression;
                ParameterNode       parameterNode       = new ParameterNode(expression.Type, parameterExpression.Name);
                current_node_branch.Push(parameterNode);
                AddBranch(tree, current_node_branch);
                break;

            case ExpressionType.Constant:
            {
                ConstantExpression constantExpression = (ConstantExpression)expression;
                if (type_filter(constantExpression.Type) &&
                    constantExpression.Value != null)
                {
                    ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)constantExpression.Value);
                    current_node_branch.Push(constantNode);
                    AddBranch(tree, current_node_branch);
                }
                else
                {
                    current_node_branch.Clear();
                }
            }
            break;

            case ExpressionType.New:
            {
                NewExpression newExpression = (NewExpression)expression;
                foreach (Expression argument in newExpression.Arguments)
                {
                    BuildBranches(argument, tree, current_node_branch, type_filter);
                }
            }
            break;

            case ExpressionType.MemberInit:
            {
                MemberInitExpression memberInitExpression = (MemberInitExpression)expression;
                BuildBranches(memberInitExpression.NewExpression, tree, current_node_branch, type_filter);
                foreach (var memberBinding in memberInitExpression.Bindings)
                {
                    MemberAssignment assignment = memberBinding as MemberAssignment;
                    if (assignment != null)
                    {
                        BuildBranches(assignment.Expression, tree, current_node_branch, type_filter);
                    }
                }
            }
            break;

            default:
                throw new InvalidProgramException(string.Format("CLINQ does not support expressions of type: {0}", expression.NodeType));
            }
        }
Exemplo n.º 7
0
        private static void BuildUnoptimizedTree(PropertyAccessTree tree, Expression expression, Predicate <Type> type_filter)
        {
            var currentNodeBranch = new Stack <PropertyAccessTreeNode>();

            BuildBranches(expression, tree, currentNodeBranch, type_filter);
        }
Exemplo n.º 8
0
        public static PropertyAccessTree Analyze <T0, T1, TResult>(Expression <Func <T0, T1, TResult> > expression)
        {
            PropertyAccessTree tree = AnalyzeLambda(expression, DoesTypeImplementINotifyPropertyChanged);

            return(tree);
        }