示例#1
0
        private static void InsertEndValueExpression(
            Type resultType,
            IList <Expression> expressions,
            VaribalesCollection variables,
            Expression source,
            IExpressionNode node,
            Expression ifNull,
            LabelTarget returnTarget)
        {
            switch (node)
            {
            case MethodNode method:
                MethodLastElement(expressions, variables, resultType, method, ifNull, returnTarget);
                break;

            case PropertyNode property:
                PropertyLastElement(expressions, source, resultType, property, ifNull, returnTarget);
                break;

            case FieldNode field:
                FieldLastElement(expressions, source, resultType, field, returnTarget);
                break;

            default:
                throw new ArgumentOutOfRangeException($"{node}");
            }
        }
示例#2
0
 private static void MethodLastElement(
     IList <Expression> expressions,
     VaribalesCollection variables,
     Type resultType,
     MethodNode method,
     Expression ifNull,
     LabelTarget returnTarget) =>
 expressions.Add(Expression.Return(returnTarget,
                                   Expression.Convert(MethodMakeExpression(expressions, variables, method, ifNull),
                                                      resultType)));
示例#3
0
        private static Expression ConstructorMakeExpression(
            IList <Expression> expressions,
            VaribalesCollection variables,
            ConstructorNode constructor,
            Expression ifNull)
        {
            var args = constructor.Parameters.Select(argument =>
                                                     CreateVariableExpressions(expressions, variables, argument, ifNull))
                       .ToList();

            return(Expression.New(constructor.Constructor, args));
        }
示例#4
0
        private static void CreateValueChainExpressions(
            Type resultType,
            IList <Expression> expressions,
            VaribalesCollection variables,
            NodeCollection nodes,
            Expression ifNull,
            LabelTarget returnTarget)
        {
            var target = CreateVariableInnerExpressions(expressions, variables, nodes, ifNull);

            InsertEndValueExpression(resultType, expressions, variables, target, nodes.First(), ifNull,
                                     returnTarget);
        }
示例#5
0
        private static Expression MethodMakeExpression(
            IList <Expression> expressions,
            VaribalesCollection variables,
            MethodNode method,
            Expression ifNull)
        {
            var @object = CreateVariableExpressions(expressions, variables, method.Object, ifNull);

            var args = method.Arguments.Select(argument =>
                                               CreateVariableExpressions(expressions, variables, argument, ifNull))
                       .ToList();

            return(Expression.Call(@object, method.MethodInfo, args));
        }
示例#6
0
        private static void InsertExpression(
            IList <Expression> expressions,
            VaribalesCollection variables,
            Expression source,
            IExpressionNode node,
            Expression ifNull,
            Expression target)
        {
            switch (node)
            {
            case ParameterNode parameter:
                ParameterNextParameter(expressions, target, parameter, ifNull);
                break;

            case ConstantNode constant:
                ConstantNextElement(expressions, target, constant, ifNull);
                break;

            case FunctionNode function:
                FunctionNextElement(expressions, variables, target, function, ifNull);
                break;

            case MethodNode method:
                MethodNextElement(expressions, variables, target, method, ifNull);
                break;

            case PropertyNode property:
                PropertyNextElement(expressions, source, target, property, ifNull);
                break;

            case FieldNode field:
                FieldNextElement(expressions, source, target, field, ifNull);
                break;

            case BinaryNode binary:
                BinaryNextElement(expressions, variables, target, binary, ifNull);
                break;

            case UnaryNode unary:
                UnaryNextElement(expressions, variables, target, unary, ifNull);
                break;

            case ConditionalNode conditional:
                ConditionalNextElement(expressions, variables, target, conditional, ifNull);
                break;

            default:
                throw new ArgumentOutOfRangeException($"{node}");
            }
        }
示例#7
0
        private static BlockExpression CreateValueBlock(
            Type resultType,
            Tree nodes,
            LabelTarget returnTarget)
        {
            var expressions = new List <Expression>();
            var variables   = new VaribalesCollection();
            var ifNull      = Expression.Return(returnTarget, NullExpressionOf(resultType));

            CreateValueExpressions(resultType, nodes.Nodes, expressions, variables, ifNull, returnTarget);

            expressions.Add(Expression.Label(returnTarget, NullExpressionOf(resultType)));
            var body = Expression.Block(variables, expressions);

            return(body);
        }
示例#8
0
        private static void ConstructorNextElement(IList <Expression> expressions,
                                                   VaribalesCollection variables,
                                                   Expression targetParameter,
                                                   ConstructorNode constructor,
                                                   Expression ifNull)
        {
            expressions.Add(Expression.Assign(targetParameter,
                                              ConstructorMakeExpression(expressions, variables, constructor, ifNull)));

            if (constructor.Type.IsValueType && !constructor.Type.IsNullable())
            {
                return;
            }

            expressions.Add(Expression.IfThen(
                                Expression.Equal(targetParameter, NullExpressionOf(constructor.Type)),
                                ifNull));
        }
示例#9
0
        private static void MemberInitNextElement(IList <Expression> expressions,
                                                  VaribalesCollection variables,
                                                  Expression targetParameter,
                                                  MemberInitNode memberInit,
                                                  Expression ifNull)
        {
            expressions.Add(Expression.Assign(targetParameter,
                                              MemberInitMakeExpression(expressions, variables, memberInit, ifNull)));

            if (memberInit.Type.IsValueType && !memberInit.Type.IsNullable())
            {
                return;
            }

            expressions.Add(Expression.IfThen(
                                Expression.Equal(targetParameter, NullExpressionOf(memberInit.Type)),
                                ifNull));
        }
示例#10
0
        private static void CreateValueSingleExpressions(Type resultType,
                                                         IList <Expression> expressions,
                                                         VaribalesCollection variables,
                                                         NodeCollection nodes,
                                                         Expression ifNull,
                                                         LabelTarget returnTarget)
        {
            var element = nodes.First();

            switch (element)
            {
            case FunctionNode function:
                FunctionLastElement(expressions, variables, resultType, function, ifNull, returnTarget);
                break;

            case ConstantNode constant:
                ConstantLastElement(expressions, resultType, constant, returnTarget);
                break;

            case ParameterNode parameter:
                ParametertLastElement(expressions, resultType, parameter, returnTarget);
                break;

            case MethodNode method:
                MethodLastElement(expressions, variables, resultType, method, ifNull, returnTarget);
                break;

            case BinaryNode binary:
                BineryLastElement(expressions, variables, resultType, binary, ifNull, returnTarget);
                break;

            case UnaryNode unary:
                UnaryLastElement(expressions, variables, resultType, unary, ifNull, returnTarget);
                break;

            case ConditionalNode conditional:
                ConditionalLastElement(expressions, variables, resultType, conditional, ifNull, returnTarget);
                break;

            default:
                throw new ArgumentOutOfRangeException($"{element}");
            }
        }
示例#11
0
        private static MemberBinding CreateBindingExpressions(
            IList <Expression> expressions,
            VaribalesCollection variables,
            IBindingNode binding,
            Expression ifNull)
        {
            switch (binding)
            {
            case MemberAssignmentNode memberAssignment:
            {
                var expression = CreateVariableExpressions(expressions, variables, memberAssignment.Nodes, ifNull);
                return(Expression.Bind(memberAssignment.Binding.Member, expression));
            }

            case MemberListBindingNode memberListBinding:
            {
                var memberInitCollection = new List <ElementInit>();
                foreach (var initializer in memberListBinding.Initializers)
                {
                    var args = new List <Expression>();
                    foreach (var argument in initializer.Arguments)
                    {
                        var expression = CreateVariableExpressions(expressions, variables, argument, ifNull);
                        args.Add(expression);
                    }

                    memberInitCollection.Add(Expression.ElementInit(initializer.ElementInit.AddMethod, args));
                }

                return(Expression.ListBind(memberListBinding.Binding.Member, memberInitCollection));
            }

            case MemberMemberBindingNode memberMemberBindingElement:
            {
                var m = memberMemberBindingElement.Bindings.Select(s =>
                                                                   CreateBindingExpressions(expressions, variables, s, ifNull));
                return(Expression.MemberBind(memberMemberBindingElement.MemberMemberBinding.Member, m));
            }

            default:
                throw new ArgumentOutOfRangeException($"{binding}");
            }
        }
示例#12
0
        private static Expression CreateVariableExpressions(
            IList <Expression> expressions,
            VaribalesCollection variables,
            NodeCollection nodes,
            Expression ifNull)
        {
            var source = CreateVariableInnerExpressions(expressions, variables, nodes, ifNull);

            if (nodes.Count == 1)
            {
                return(source);
            }

            var target = Expression.Variable(nodes.First().Type, $"value{variables.GetNextIndex()}");

            variables.Add(target);
            InsertExpression(expressions, variables, source, nodes.First(), ifNull, target);
            return(target);
        }
示例#13
0
        private static void CreateValueExpressions(
            Type resultType,
            NodeCollection nodes,
            IList <Expression> expressions,
            VaribalesCollection variables,
            Expression ifNull,
            LabelTarget returnTarget)
        {
            switch (nodes.Count)
            {
            case 0:
                throw new NotSupportedException();

            case 1:
                CreateValueSingleExpressions(resultType, expressions, variables, nodes, ifNull, returnTarget);
                break;

            default:
                CreateValueChainExpressions(resultType, expressions, variables, nodes, ifNull, returnTarget);
                break;
            }
        }
示例#14
0
 private static void ConditionalLastElement(
     IList <Expression> expressions,
     VaribalesCollection variables,
     Type resultType,
     in ConditionalNode conditional,
示例#15
0
        private static Expression MemberInitMakeExpression(IList <Expression> expressions, VaribalesCollection variables,
                                                           MemberInitNode memberInit, Expression ifNull)
        {
            var args = memberInit.Parameters.Select(argument =>
                                                    CreateVariableExpressions(expressions, variables, argument, ifNull))
                       .ToList();
            var bindings = memberInit.Bindings.Select(binding =>
                                                      CreateBindingExpressions(expressions, variables, binding, ifNull));

            return(Expression.MemberInit(
                       Expression.New(memberInit.MemberInitExpression.NewExpression.Constructor, args), bindings));
        }
示例#16
0
        private static Expression CreateVariableInnerExpressions(
            IList <Expression> expressions,
            VaribalesCollection variables,
            NodeCollection nodes,
            Expression ifNull)
        {
            var list = nodes.ToList();

            list.Reverse();
            var        i = 1;
            Expression target;
            var        element = list.First();
            {
                switch (element)
                {
                case ParameterNode parameter:
                {
                    var p = parameter.Expression;
                    target = p;
                    ParameterNextParameter(expressions, target, parameter, ifNull);
                    break;
                }

                case ConstantNode constant:
                    target = constant.Expression;
                    break;

                case MethodNode method:
                {
                    var p = Expression.Variable(method.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    MethodNextElement(expressions, variables, target, method, ifNull);
                    break;
                }

                case ConstructorNode constructor:
                {
                    var p = Expression.Variable(constructor.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    ConstructorNextElement(expressions, variables, target, constructor, ifNull);
                    break;
                }

                case FunctionNode function:
                {
                    var p = Expression.Variable(function.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    FunctionNextElement(expressions, variables, target, function, ifNull);
                    break;
                }

                case BinaryNode binary:
                {
                    var p = Expression.Variable(binary.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    BinaryNextElement(expressions, variables, target, binary, ifNull);
                    break;
                }

                case UnaryNode unary:
                {
                    var p = Expression.Variable(unary.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    UnaryNextElement(expressions, variables, target, unary, ifNull);
                    break;
                }

                case ConditionalNode conditional:
                {
                    var p = Expression.Variable(conditional.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    ConditionalNextElement(expressions, variables, target, conditional, ifNull);
                    break;
                }

                case MemberInitNode memberInit:
                {
                    var p = Expression.Variable(memberInit.Type, $"value{variables.GetNextIndex()}");
                    target = p;
                    variables.Add(p);
                    MemberInitNextElement(expressions, variables, target, memberInit, ifNull);
                    break;
                }

                default:
                {
                    throw new ArgumentOutOfRangeException($"{element}");
                }
                }
            }

            var count = list.Count;

            if (count == 1)
            {
                return(target);
            }

            var source = target;

            for (; i < count - 1; i++)
            {
                element = list[i];
                var p = Expression.Variable(element.Type, $"value{variables.GetNextIndex()}");
                variables.Add(p);
                target = p;
                InsertExpression(expressions, variables, source, element, ifNull, p);
                source = target;
            }

            return(target);
        }