예제 #1
0
        /// <summary>
        /// Gets the tree.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="tree">The tree.</param>
        /// <param name="parent">The parent.</param>
        /// <returns></returns>
        /// <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 NodeCollection GetTree([NotNull] Expression expression, [NotNull] ITree tree,
                                             [CanBeNull] IExpressionNode parent)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }
            var nodeCollection = new NodeCollection(tree, parent);

            while (true)
            {
                switch (expression)
                {
                case MemberExpression memberExpression when memberExpression.Member is PropertyInfo propertyInfo:
                {
                    expression = memberExpression.Expression;
                    nodeCollection.AddElement(new PropertyNode(memberExpression, propertyInfo));
                    break;
                }

                case MemberExpression memberExpression when memberExpression.Member is FieldInfo fieldInfo:
                    expression = memberExpression.Expression;
                    nodeCollection.AddElement(new FieldNode(memberExpression, fieldInfo));
                    break;

                case MemberExpression _:
                    throw new ExpressionObserversException("Expression member is not a PropertyInfo");

                case ParameterExpression parameterExpression:
                {
                    var element = (new ParameterNode(parameterExpression));
                    nodeCollection.AddElement(element);
                    nodeCollection.Roots.Add(element);
                    return(nodeCollection);
                }

                case MethodCallExpression methodCallExpression
                    when methodCallExpression.Method.ReturnParameter == null:
                    throw new ExpressionObserversException("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 <NodeCollection>();
                        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 <NodeCollection>();
                        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);
                    nodeCollection.AddElement(element);
                    nodeCollection.Roots.Add(element);
                    return(nodeCollection);
                }

                case BinaryExpression binaryExpression:
                {
                    var element = new BinaryNode(binaryExpression);
                    element.LeftNodes = GetTree(binaryExpression.Left, nodeCollection, element);
                    element.Righttree = 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 <NodeCollection>();
                    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 <NodeCollection>();
                    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 ExpressionObserversException("Expression body is null");

                default:
                    throw new ExpressionObserversException(
                              $"Expression body is not a supportet Expression {expression} type {expression.Type}");
                }
            }
        }