Exemplo n.º 1
0
        /// <summary>
        /// Reduces the expression node to a simpler expression.
        /// </summary>
        /// <returns>The reduced expression.</returns>
        public override Expression Reduce()
        {
            var functionalOp = new Func <Expression, Expression>(lhs =>
            {
                var operation = default(ExpressionType);

                switch (OperationNodeType)
                {
                case CSharpExpressionType.PreIncrementAssign:
                case CSharpExpressionType.PreIncrementAssignChecked:
                case CSharpExpressionType.PostIncrementAssign:
                case CSharpExpressionType.PostIncrementAssignChecked:
                    operation = ExpressionType.Increment;
                    break;

                case CSharpExpressionType.PreDecrementAssign:
                case CSharpExpressionType.PreDecrementAssignChecked:
                case CSharpExpressionType.PostDecrementAssign:
                case CSharpExpressionType.PostDecrementAssignChecked:
                    operation = ExpressionType.Decrement;
                    break;

                default:
                    throw ContractUtils.Unreachable;
                }

                var args = new[]
                {
                    CSharpArgumentInfo.Create(Operand.Flags, null)
                };

                var binder  = Binder.UnaryOperation(Flags, operation, Context, args);
                var dynamic = DynamicHelpers.MakeDynamic(typeof(object), binder, new[] { lhs }, new[] { lhs.Type });

                // NB: no conversion needed in the unary case

                return(dynamic);
            });

            var flags = Flags | CSharpBinderFlags.ValueFromCompoundAssignment;

            var res = DynamicHelpers.ReduceDynamicAssignment(Operand, functionalOp, flags, IsPrefix);

            return(res);
        }
        private Expression ReduceCore(DynamicCSharpArgument left)
        {
            var functionalOp = new Func <Expression, Expression>(lhs =>
            {
                var operation = default(ExpressionType);

                switch (OperationNodeType)
                {
                case CSharpExpressionType.AddAssign:
                case CSharpExpressionType.AddAssignChecked:
                    operation = ExpressionType.AddAssign;
                    break;

                case CSharpExpressionType.SubtractAssign:
                case CSharpExpressionType.SubtractAssignChecked:
                    operation = ExpressionType.SubtractAssign;
                    break;

                case CSharpExpressionType.MultiplyAssign:
                case CSharpExpressionType.MultiplyAssignChecked:
                    operation = ExpressionType.MultiplyAssign;
                    break;

                case CSharpExpressionType.DivideAssign:
                    operation = ExpressionType.DivideAssign;
                    break;

                case CSharpExpressionType.ModuloAssign:
                    operation = ExpressionType.ModuloAssign;
                    break;

                case CSharpExpressionType.AndAssign:
                    operation = ExpressionType.AndAssign;
                    break;

                case CSharpExpressionType.OrAssign:
                    operation = ExpressionType.OrAssign;
                    break;

                case CSharpExpressionType.ExclusiveOrAssign:
                    operation = ExpressionType.ExclusiveOrAssign;
                    break;

                case CSharpExpressionType.LeftShiftAssign:
                    operation = ExpressionType.LeftShiftAssign;
                    break;

                case CSharpExpressionType.RightShiftAssign:
                    operation = ExpressionType.RightShiftAssign;
                    break;

                default:
                    throw ContractUtils.Unreachable;
                }

                var args = new[]
                {
                    CSharpArgumentInfo.Create(GetArgumentInfoFlags(Left), null),
                    CSharpArgumentInfo.Create(GetArgumentInfoFlags(Right), null),
                };

                var binder  = Binder.BinaryOperation(Flags, operation, Context, args);
                var dynamic = DynamicHelpers.MakeDynamic(typeof(object), binder, new[] { lhs, Right.Expression }, new[] { lhs.Type, Right.Expression.Type });

                var leftType = Left.Expression.Type;
                if (leftType != dynamic.Type)
                {
                    var convert = Binder.Convert(CSharpBinderFlags.ConvertExplicit, leftType, Context);
                    dynamic     = DynamicHelpers.MakeDynamic(leftType, convert, new[] { dynamic }, null);
                }

                return(dynamic);
            });

            var flags = Flags | CSharpBinderFlags.ValueFromCompoundAssignment;

            var res = DynamicHelpers.ReduceDynamicAssignment(left, functionalOp, flags);

            return(res);
        }