/// <summary> /// Creates the chain. /// </summary> /// <param name="tree">The nodes.</param> /// <exception cref="System.NotSupportedException">Expression Tree Node not supported.</exception> protected void CreateChain(IRootAware tree) { foreach (var treeRoot in tree.Roots) { switch (treeRoot) { case ConstantNode constantElement when treeRoot.Next is FieldNode fieldElement: { if (!(fieldElement.Next is PropertyNode propertyElement)) { continue; } var root = new RootPropertyObserverNode( propertyElement.PropertyInfo, this.OnAction, fieldElement.FieldInfo.GetValue(constantElement.Value)); this.LoopTree(propertyElement, root); this.RootNodes.Add(root); break; } case ConstantNode constantElement: { if (!(treeRoot.Next is PropertyNode propertyElement)) { continue; } var root = new RootPropertyObserverNode( propertyElement.PropertyInfo, this.OnAction, (INotifyPropertyChanged)constantElement.Value !); this.LoopTree(propertyElement, root); this.RootNodes.Add(root); break; } default: throw new NotSupportedException($"{treeRoot}"); } } }
/// <summary> /// Creates the bindingtree. /// </summary> /// <param name="expressionTree">The tree.</param> /// <param name="bindings">The bindings.</param> /// <param name="node">The node.</param> /// <returns>The binding list.</returns> private static List <IBindingNode> CreateBindingTree( IRootAware expressionTree, IEnumerable <MemberBinding> bindings, MemberInitNode node) { var bindingtree = new List <IBindingNode>(); foreach (var binding in bindings) { switch (binding) { case MemberAssignment memberAssignment: { bindingtree.Add( new MemberAssignmentNode( memberAssignment, GetTree(memberAssignment.Expression, expressionTree, node))); break; } case MemberMemberBinding memberMemberBinding: { var bs = CreateBindingTree(expressionTree, memberMemberBinding.Bindings, node); bindingtree.Add(new MemberMemberBindingNode(memberMemberBinding, bs, node)); break; } case MemberListBinding memberListBinding: { var elementInits = new List <ElementInitNode>(); foreach (var i in memberListBinding.Initializers) { elementInits.Add( new ElementInitNode( i, i.Arguments.Select(a => GetTree(a, expressionTree, node)).ToList())); } bindingtree.Add(new MemberListBindingNode(memberListBinding, elementInits)); break; } } } return(bindingtree); }
/// <summary> /// Initializes a new instance of the <see cref="NodeCollection" /> class. /// </summary> /// <param name="expressionTree">The expression tree.</param> /// <param name="parent">The parent.</param> public NodeCollection([NotNull] IRootAware expressionTree, IExpressionNode?parent) { this.RootAware = expressionTree; this.Parent = parent; }
/// <summary> /// Creates the chain. /// </summary> /// <param name="parameter1">The parameter1.</param> /// <param name="parameter2">The parameter2.</param> /// <param name="nodes">The nodes.</param> /// <exception cref="NotSupportedException">Expression Tree Node not supported.</exception> private void CreateChain(TParameter1 parameter1, TParameter2 parameter2, IRootAware nodes) { foreach (var treeRoot in nodes.Roots) { switch (treeRoot) { case ParameterNode parameterElement: { if (!(parameterElement.Next is PropertyNode propertyElement)) { continue; } var parameterGetter = ExpressionGetter.CreateParameterGetter( parameterElement, this.propertyExpression); var root = new RootPropertyObserverNode( propertyElement.PropertyInfo, this.OnAction, (INotifyPropertyChanged)parameterGetter(parameter1, parameter2)); this.LoopTree(propertyElement, root); this.RootNodes.Add(root); break; } case ConstantNode constantElement when treeRoot.Next is FieldNode fieldElement: { if (!(fieldElement.Next is PropertyNode propertyElement)) { continue; } var root = new RootPropertyObserverNode( propertyElement.PropertyInfo, this.OnAction, (INotifyPropertyChanged)fieldElement.FieldInfo.GetValue(constantElement.Value)); this.LoopTree(propertyElement, root); this.RootNodes.Add(root); break; } case ConstantNode constantElement: { if (!(treeRoot.Next is PropertyNode propertyElement)) { continue; } var root = new RootPropertyObserverNode( propertyElement.PropertyInfo, this.OnAction, (INotifyPropertyChanged)constantElement.Value !); this.LoopTree(propertyElement, root); this.RootNodes.Add(root); break; } default: throw new NotSupportedException(); } } }
/// <summary> /// Gets the tree. /// </summary> /// <param name="expression">The expression.</param> /// <param name="expressionTree">The tree.</param> /// <param name="parent">The parent.</param> /// <returns> /// The expression tree. /// </returns> /// <exception cref="ArgumentNullException"> /// nameof(expression) /// or /// nameof(expression) /// or /// nameof(expression) /// or /// nameof(expression) /// or /// nameof(expression) /// or /// nameof(expression) is null. /// </exception> /// <exception cref="ExpressionObserversException"> /// Expression member is not a PropertyInfo /// or /// Method call has no ReturnParameter /// or /// Expression body is null /// or /// Expression body is not a supportet Expression {expression} type {expression.Type}. /// </exception> public static INodeCollection GetTree( [NotNull] Expression expression, [NotNull] IRootAware expressionTree, IExpressionNode?parent) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (expressionTree == null) { throw new ArgumentNullException(nameof(expressionTree)); } var nodeCollection = new NodeCollection(expressionTree, parent); while (true) { switch (expression) { case MemberExpression { Member: PropertyInfo propertyInfo } memberExpression: { expression = memberExpression.Expression; nodeCollection.AddElement(new PropertyNode(memberExpression, propertyInfo)); break; } case MemberExpression { Member: FieldInfo fieldInfo } memberExpression: { expression = memberExpression.Expression; nodeCollection.AddElement(new FieldNode(memberExpression, fieldInfo)); break; } case MemberExpression _: throw new TreeException("Expression member is not a PropertyInfo"); case ParameterExpression parameterExpression: { var element = new ParameterNode(parameterExpression); var node = nodeCollection.AddElement(element); nodeCollection.Roots.Add(node); return(nodeCollection); } case MethodCallExpression methodCallExpression when methodCallExpression.Method.ReturnParameter == null: throw new TreeException("Method call has no ReturnParameter"); case MethodCallExpression methodCallExpression: expression = methodCallExpression.Object; if (expression != null) { var element = new MethodNode(methodCallExpression); element.Object = GetTree(expression, nodeCollection, element); var arguments = new List <INodeCollection>(); foreach (var argument in methodCallExpression.Arguments) { arguments.Add(GetTree(argument, nodeCollection, element)); } element.Arguments = arguments; nodeCollection.AddElement(element); return(nodeCollection); } else { var element = new FunctionNode(methodCallExpression); var parameters = new List <INodeCollection>(); foreach (var argument in methodCallExpression.Arguments) { parameters.Add(GetTree(argument, nodeCollection, element)); } element.Parameters = parameters; nodeCollection.AddElement(element); return(nodeCollection); } case ConstantExpression constantExpression: { var element = new ConstantNode(constantExpression); var node = nodeCollection.AddElement(element); nodeCollection.Roots.Add(node); return(nodeCollection); } case BinaryExpression binaryExpression: { var element = new BinaryNode(binaryExpression); element.LeftNodes = GetTree(binaryExpression.Left, nodeCollection, element); element.RightNodes = GetTree(binaryExpression.Right, nodeCollection, element); nodeCollection.AddElement(element); return(nodeCollection); } case UnaryExpression unaryExpression: { var element = new UnaryNode(unaryExpression); element.Operand = GetTree(unaryExpression.Operand, nodeCollection, element); nodeCollection.AddElement(element); return(nodeCollection); } case ConditionalExpression conditionalExpression: { var element = new ConditionalNode(conditionalExpression); element.Test = GetTree(conditionalExpression.Test, nodeCollection, element); element.IfTrue = GetTree(conditionalExpression.IfTrue, nodeCollection, element); element.IfFalse = GetTree(conditionalExpression.IfFalse, nodeCollection, element); nodeCollection.AddElement(element); return(nodeCollection); } case NewExpression newExpression: { var element = new ConstructorNode(newExpression); var parameters = new List <INodeCollection>(); foreach (var argument in newExpression.Arguments) { parameters.Add(GetTree(argument, nodeCollection, element)); } element.Parameters = parameters; nodeCollection.AddElement(element); return(nodeCollection); } case MemberInitExpression memberInitExpression: { var element = new MemberInitNode(memberInitExpression); var parameters = new List <INodeCollection>(); foreach (var argument in memberInitExpression.NewExpression.Arguments) { parameters.Add(GetTree(argument, nodeCollection, element)); } element.Parameters = parameters; var bindings = memberInitExpression.Bindings; var bindingtree = CreateBindingTree(nodeCollection, bindings, element); element.Bindings = bindingtree; nodeCollection.AddElement(element); return(nodeCollection); } case null: throw new TreeException("Expression body is null"); default: throw new TreeException( $"Expression body is not a supportet Expression {expression} type {expression.Type}"); } } }