コード例 #1
0
        private Expression WithEventCheck(GetMemberDynamicCSharpExpression member, string accessor)
        {
            var obj  = member.Object;
            var name = member.Name;
            var args = member.Arguments;

            Debug.Assert(args.Count == 0);

            var lhs  = Expression.Parameter(obj.Type, "__objTemp");
            var left = Left.Update(member.Update(lhs, args));

            var isEventBinder = Binder.IsEvent(CSharpBinderFlags.None, name, Context);
            var isEventCheck  = DynamicHelpers.MakeDynamic(typeof(bool), isEventBinder, new[] { lhs }, null);

            var accessorName = accessor + name;
            var accessorArgs = new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            };

            var invokeAccessorBinder = Binder.InvokeMember(CSharpBinderFlags.InvokeSpecialName | CSharpBinderFlags.ResultDiscarded, accessorName, null, Context, accessorArgs);
            var invokeAccessor       = DynamicHelpers.MakeDynamic(typeof(object), invokeAccessorBinder, new[] { lhs, Right.Expression }, null);

            var ifNotEvent = ReduceCore(left);

            var res =
                Expression.Block(
                    new[] { lhs },
                    Expression.Assign(lhs, obj),
                    Expression.Condition(isEventCheck, invokeAccessor, ifNotEvent)
                    );

            return(res);
        }
コード例 #2
0
        internal Expression ReduceAssignment(Expression value, CSharpBinderFlags flags, CSharpArgumentInfoFlags leftFlags = CSharpArgumentInfoFlags.None, CSharpArgumentInfoFlags rightFlags = CSharpArgumentInfoFlags.None)
        {
            var binder        = default(CallSiteBinder);
            var arguments     = default(IEnumerable <Expression>);
            var argumentTypes = default(Type[]);

            ReduceAssignment(value, flags, leftFlags, rightFlags, out binder, out arguments, out argumentTypes);

            return(DynamicHelpers.MakeDynamic(Type, binder, arguments, argumentTypes));
        }
コード例 #3
0
        /// <summary>
        /// Reduces the expression node to a simpler expression.
        /// </summary>
        /// <returns>The reduced expression.</returns>
        public override Expression Reduce()
        {
            var binder        = default(CallSiteBinder);
            var arguments     = default(IEnumerable <Expression>);
            var argumentTypes = default(Type[]);

            ReduceDynamic(out binder, out arguments, out argumentTypes);

            return(DynamicHelpers.MakeDynamic(Type, binder, arguments, argumentTypes));
        }
コード例 #4
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 Unreachable;
                }

                var args = new[]
                {
                    CSharpArgumentInfo.Create(Operand.Flags, name: 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 = ReduceDynamicAssignment(Operand, functionalOp, flags, IsPrefix);

            return(res);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        /// <summary>
        /// Reduces the expression node to a simpler expression.
        /// </summary>
        /// <returns>The reduced expression.</returns>
        public override Expression Reduce()
        {
            ReduceDynamic(out CallSiteBinder binder, out IEnumerable <Expression> arguments, out Type[] argumentTypes);

            return(DynamicHelpers.MakeDynamic(Type, binder, arguments, argumentTypes));
        }