예제 #1
0
 internal BinaryDynamicCSharpExpression(Type context, CSharpBinderFlags binderFlags, ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right)
     : base(context, binderFlags)
 {
     OperationNodeType = binaryType;
     Left  = left;
     Right = right;
 }
예제 #2
0
        private static int CopyArguments(Expression receiver, ReadOnlyCollection <DynamicCSharpArgument> arguments, bool prefix, out DynamicCSharpArgument[] args, out Expression[] block, out ParameterExpression[] temps)
        {
            var n = arguments.Count;

            args  = new DynamicCSharpArgument[n];
            block = new Expression[n + (prefix ? 2 : 4)];
            temps = new ParameterExpression[n + (prefix ? 1 : 2)];

            // ISSUE: If `receiver` is a value type, we're creating a copy here. How do we capture it
            //        as a `ref` instead? See https://github.com/dotnet/corefx/issues/4984 for this issue
            //        in the LINQ API as well.

            var i = 0;

            temps[i] = Expression.Parameter(receiver.Type, "__object");
            block[i] = Expression.Assign(temps[i], receiver);
            i++;

            while (i <= n)
            {
                var arg = arguments[i - 1];
                temps[i]    = Expression.Parameter(arg.Expression.Type, "__arg" + i);
                args[i - 1] = arg.Update(temps[i]);
                block[i]    = Expression.Assign(temps[i], arg.Expression);
                i++;
            }

            return(i);
        }
 internal AssignBinaryDynamicCSharpExpression(Type context, CSharpBinderFlags binderFlags, CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right)
     : base(context, binderFlags)
 {
     OperationNodeType = binaryType;
     Left = left;
     Right = right;
 }
        internal GetIndexDynamicCSharpExpression TransformToLhs(List <ParameterExpression> temps, List <Expression> stores)
        {
            var obj = Expression.Parameter(Object.Type, "__obj");

            temps.Add(obj);
            stores.Add(Expression.Assign(obj, Object));

            int n = Arguments.Count;

            var newArgs = new DynamicCSharpArgument[n];

            for (int i = 0; i < n; i++)
            {
                var arg = Arguments[i];

                if (Helpers.IsPure(arg.Expression))
                {
                    newArgs[i] = arg;
                }
                else
                {
                    var tmp = Expression.Parameter(arg.Expression.Type, "__arg" + i);

                    temps.Add(tmp);
                    stores.Add(Expression.Assign(tmp, arg.Expression));

                    newArgs[i] = arg.Update(tmp);
                }
            }

            return(Update(obj, newArgs));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="left">The <see cref="Left" /> property of the result.</param>
        /// <param name="right">The <see cref="Right" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public BinaryDynamicCSharpExpression Update(DynamicCSharpArgument left, DynamicCSharpArgument right)
        {
            if (left == Left && right == Right)
            {
                return(this);
            }

            return(DynamicCSharpExpression.MakeDynamicBinary(OperationNodeType, left, right, Flags, Context));
        }
예제 #6
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="operand">The <see cref="Operand" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public AssignUnaryDynamicCSharpExpression Update(DynamicCSharpArgument operand)
        {
            if (operand == Operand)
            {
                return(this);
            }

            return(DynamicCSharpExpression.MakeDynamicUnaryAssign(OperationNodeType, operand, Flags, Context));
        }
예제 #7
0
        public static Expression ReduceDynamicAssignment(DynamicCSharpArgument left, Func <Expression, Expression> functionalOp, CSharpBinderFlags flags, bool prefix = true)
        {
            var lhs = MakeWriteable(left.Expression);

            return(lhs switch
            {
                GetMemberDynamicCSharpExpression dynamicMember => ReduceDynamicMember(dynamicMember, functionalOp, flags, prefix),
                GetIndexDynamicCSharpExpression dynamicIndex => ReduceDynamicIndex(dynamicIndex, functionalOp, flags, prefix),
                _ => Helpers.ReduceAssignment(lhs, functionalOp, prefix),
            });
        public static Expression ReduceDynamicAssignment(DynamicCSharpArgument left, Func <Expression, Expression> functionalOp, CSharpBinderFlags flags, bool prefix = true)
        {
            var lhs = MakeWriteable(left.Expression);

            switch (lhs)
            {
            case GetMemberDynamicCSharpExpression dynamicMember:
                return(ReduceDynamicMember(dynamicMember, functionalOp, flags, prefix));

            case GetIndexDynamicCSharpExpression dynamicIndex:
                return(ReduceDynamicIndex(dynamicIndex, functionalOp, flags, prefix));
            }

            return(Helpers.ReduceAssignment(lhs, functionalOp, prefix));
        }
예제 #9
0
        public static Expression ReduceDynamicAssignment(DynamicCSharpArgument left, Func<Expression, Expression> functionalOp, CSharpBinderFlags flags, bool prefix = true)
        {
            var lhs = MakeWriteable(left.Expression);

            var dynamicMember = lhs as GetMemberDynamicCSharpExpression;
            if (dynamicMember != null)
            {
                return ReduceDynamicMember(dynamicMember, functionalOp, flags, prefix);
            }

            var dynamicIndex = lhs as GetIndexDynamicCSharpExpression;
            if (dynamicIndex != null)
            {
                return ReduceDynamicIndex(dynamicIndex, functionalOp, flags, prefix);
            }

            return Helpers.ReduceAssignment(lhs, functionalOp, prefix);
        }
예제 #10
0
        public static Expression ReduceDynamicAssignment(DynamicCSharpArgument left, Func <Expression, Expression> functionalOp, CSharpBinderFlags flags, bool prefix = true)
        {
            var lhs = MakeWriteable(left.Expression);

            var dynamicMember = lhs as GetMemberDynamicCSharpExpression;

            if (dynamicMember != null)
            {
                return(ReduceDynamicMember(dynamicMember, functionalOp, flags, prefix));
            }

            var dynamicIndex = lhs as GetIndexDynamicCSharpExpression;

            if (dynamicIndex != null)
            {
                return(ReduceDynamicIndex(dynamicIndex, functionalOp, flags, prefix));
            }

            return(Helpers.ReduceAssignment(lhs, functionalOp, prefix));
        }
예제 #11
0
        protected internal override DynamicCSharpArgument VisitDynamicArgument(DynamicCSharpArgument node)
        {
            var expr = Visit(node.Expression);

            var args = new List <object>();

            if (node.Name != null)
            {
                args.Add(new XAttribute(nameof(node.Name), node.Name));
            }

            if (node.Flags != CSharpArgumentInfoFlags.None)
            {
                args.Add(new XAttribute(nameof(node.Flags), node.Flags));
            }

            args.Add(new XElement(nameof(node.Expression), expr));

            var res = new XElement(nameof(DynamicCSharpArgument), args);

            _nodes.Push(res);

            return(node);
        }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation with the specified binder flags.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression MakeDynamicBinaryAssign(CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags)
 {
     return MakeDynamicBinaryAssign(binaryType, left, right, binderFlags, null);
 }
        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;
        }
 public static AssignBinaryDynamicCSharpExpression DynamicRightShiftAssign(DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.RightShiftAssign, left, right, binderFlags);
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary operation.
 /// </summary>
 /// <param name="unaryType">The type of the unary operation to perform.</param>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound unary operation.</returns>
 public static UnaryDynamicCSharpExpression MakeDynamicUnary(ExpressionType unaryType, DynamicCSharpArgument operand) =>
 MakeDynamicUnary(unaryType, operand, CSharpBinderFlags.None, context: null);
 protected internal virtual DynamicCSharpArgument VisitDynamicArgument(DynamicCSharpArgument node)
 {
     return node.Update(Visit(node.Expression));
 }
예제 #17
0
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary operation.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static BinaryDynamicCSharpExpression MakeDynamicBinary(ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return(MakeDynamicBinary(binaryType, left, right, CSharpBinderFlags.None, null));
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary operation.
 /// </summary>
 /// <param name="unaryType">The type of the unary operation to perform.</param>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound unary operation.</returns>
 public static UnaryDynamicCSharpExpression MakeDynamicUnary(ExpressionType unaryType, DynamicCSharpArgument operand)
 {
     return(MakeDynamicUnary(unaryType, operand, CSharpBinderFlags.None, null));
 }
 public static AssignUnaryDynamicCSharpExpression DynamicPreIncrementAssignChecked(DynamicCSharpArgument operand, CSharpBinderFlags binderFlags, Type context)
 {
     return MakeDynamicUnaryAssign(CSharpExpressionType.PreIncrementAssignChecked, operand, binderFlags, context);
 }
        /// <summary>
        /// Creates a new expression representing a dynamically bound binary operation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="binaryType">The type of the binary operation to perform.</param>
        /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
        /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound binary operation.</returns>
        public static BinaryDynamicCSharpExpression MakeDynamicBinary(ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(left, nameof(left));
            ContractUtils.RequiresNotNull(right, nameof(right));

            CheckBinary(binaryType);

            switch (binaryType)
            {
                case ExpressionType.AddChecked:
                case ExpressionType.MultiplyChecked:
                case ExpressionType.SubtractChecked:
                    binderFlags |= CSharpBinderFlags.CheckedContext;
                    break;
                case ExpressionType.AndAlso:
                case ExpressionType.OrElse:
                    binderFlags |= CSharpBinderFlags.BinaryOperationLogical;
                    break;
            }

            return new BinaryDynamicCSharpExpression(context, binderFlags, binaryType, left, right);
        }
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary 'PreDecrementAssign' operation.
 /// </summary>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound unary 'PreDecrementAssign' operation.</returns>
 public static AssignUnaryDynamicCSharpExpression DynamicPreDecrementAssign(DynamicCSharpArgument operand)
 {
     return MakeDynamicUnaryAssign(CSharpExpressionType.PreDecrementAssign, operand);
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary operation.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static BinaryDynamicCSharpExpression MakeDynamicBinary(ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return MakeDynamicBinary(binaryType, left, right, CSharpBinderFlags.None, null);
 }
 public static AssignUnaryDynamicCSharpExpression DynamicPostDecrementAssignChecked(DynamicCSharpArgument operand, CSharpBinderFlags binderFlags)
 {
     return MakeDynamicUnaryAssign(CSharpExpressionType.PostDecrementAssignChecked, operand, binderFlags);
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary 'PostIncrementAssignChecked' operation.
 /// </summary>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound unary 'PostIncrementAssignChecked' operation.</returns>
 public static AssignUnaryDynamicCSharpExpression DynamicPostIncrementAssignChecked(DynamicCSharpArgument operand)
 {
     return MakeDynamicUnaryAssign(CSharpExpressionType.PostIncrementAssignChecked, operand);
 }
예제 #25
0
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation with the specified binder flags and the specified type context.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicAssign(DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
 {
     return(MakeDynamicBinaryAssign(CSharpExpressionType.Assign, left, right, binderFlags, context));
 }
        /// <summary>
        /// Creates a new expression representing a dynamically bound unary operation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="unaryType">The type of the unary operation to perform.</param>
        /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound unary operation.</returns>
        public static UnaryDynamicCSharpExpression MakeDynamicUnary(ExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(operand, nameof(operand));

            CheckUnary(unaryType);

            switch (unaryType)
            {
            case ExpressionType.NegateChecked:
                binderFlags |= CSharpBinderFlags.CheckedContext;
                break;
            }

            return(new UnaryDynamicCSharpExpression(context, binderFlags, unaryType, operand));
        }
        /// <summary>
        /// Creates a new expression representing a dynamically bound unary operation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="unaryType">The type of the unary operation to perform.</param>
        /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound unary operation.</returns>
        public static UnaryDynamicCSharpExpression MakeDynamicUnary(ExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(operand, nameof(operand));

            CheckUnary(unaryType);

            switch (unaryType)
            {
                case ExpressionType.NegateChecked:
                    binderFlags |= CSharpBinderFlags.CheckedContext;
                    break;
            }

            return new UnaryDynamicCSharpExpression(context, binderFlags, unaryType, operand);
        }
 public static AssignBinaryDynamicCSharpExpression DynamicSubtractAssignChecked(DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.SubtractAssignChecked, left, right, binderFlags);
 }
예제 #29
0
 protected internal virtual DynamicCSharpArgument VisitDynamicArgument(DynamicCSharpArgument node) =>
 node.Update(
     Visit(node.Expression)
     );
 /// <summary>
 /// Creates a new expression representing a dynamically bound constructor invocation.
 /// </summary>
 /// <param name="type">The type of the object to instantiate.</param>
 /// <param name="arguments">An array of expressions dynamic arguments the arguments passed to the constructor upon object creation.</param>
 /// <returns>A new expression representing a dynamically bound constructor invocation.</returns>
 public static InvokeConstructorDynamicCSharpExpression DynamicInvokeConstructor(Type type, DynamicCSharpArgument[] arguments)
 {
     return DynamicInvokeConstructor(type, arguments, CSharpBinderFlags.None, null);
 }
        public static AssignUnaryDynamicCSharpExpression MakeDynamicUnaryAssign(CSharpExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(operand, nameof(operand));

            RequiresCanRead(operand.Expression, nameof(operand));
            RequiresCanWrite(operand.Expression, nameof(operand));

            CheckUnaryAssign(unaryType);

            switch (unaryType)
            {
                case CSharpExpressionType.PreIncrementAssignChecked:
                case CSharpExpressionType.PreDecrementAssignChecked:
                case CSharpExpressionType.PostIncrementAssignChecked:
                case CSharpExpressionType.PostDecrementAssignChecked:
                    binderFlags |= CSharpBinderFlags.CheckedContext;
                    break;
            }

            return new AssignUnaryDynamicCSharpExpression(context, binderFlags, unaryType, operand);
        }
예제 #32
0
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary assignment operation with the specified binder flags.
 /// </summary>
 /// <param name="unaryType">The type of the unary operation to perform.</param>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound unary assignment operation.</returns>
 public static AssignUnaryDynamicCSharpExpression MakeDynamicUnaryAssign(CSharpExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags)
 {
     return(MakeDynamicUnaryAssign(unaryType, operand, binderFlags, null));
 }
예제 #33
0
        private static int CopyArguments(Expression receiver, ReadOnlyCollection<DynamicCSharpArgument> arguments, bool prefix, out DynamicCSharpArgument[] args, out Expression[] block, out ParameterExpression[] temps)
        {
            var n = arguments.Count;

            args = new DynamicCSharpArgument[n];
            block = new Expression[n + (prefix ? 2 : 4)];
            temps = new ParameterExpression[n + (prefix ? 1 : 2)];

            // ISSUE: If `receiver` is a value type, we're creating a copy here. How do we capture it
            //        as a `ref` instead? See https://github.com/dotnet/corefx/issues/4984 for this issue
            //        in the LINQ API as well.

            var i = 0;
            temps[i] = Expression.Parameter(receiver.Type, "__object");
            block[i] = Expression.Assign(temps[i], receiver);
            i++;

            while (i <= n)
            {
                var arg = arguments[i - 1];
                temps[i] = Expression.Parameter(arg.Expression.Type, "__arg" + i);
                args[i - 1] = arg.Update(temps[i]);
                block[i] = Expression.Assign(temps[i], arg.Expression);
                i++;
            }

            return i;
        }
 /// <summary>
 /// Creates a new expression representing a dynamically bound member invocation.
 /// </summary>
 /// <param name="object">The expression representing the object to invoke the member on.</param>
 /// <param name="name">The name of the member to invoke.</param>
 /// <param name="arguments">An array of dynamic arguments representing the arguments passed to the member upon invocation.</param>
 /// <returns>A new expression representing a dynamically bound member invocation.</returns>
 public static InvokeMemberDynamicCSharpExpression DynamicInvokeMember(Expression @object, string name, DynamicCSharpArgument[] arguments)
 {
     return DynamicInvokeMember(@object, name, null, arguments, CSharpBinderFlags.None, null);
 }
 private static CSharpArgumentInfoFlags GetArgumentInfoFlags(DynamicCSharpArgument argument)
 {
     // TODO: Can we infer UseCompileTimeType?
     return argument.Flags;
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound (possibly generic) member invocation.
 /// </summary>
 /// <param name="type">The type containing the static member to invoke.</param>
 /// <param name="name">The name of the member to invoke.</param>
 /// <param name="typeArguments">An enumerable sequence of type arguments to pass to the generic member. (Specify null for non-generic members.)</param>
 /// <param name="arguments">An array of dynamic arguments representing the arguments passed to the member upon invocation.</param>
 /// <returns>A new expression representing a dynamically bound member invocation.</returns>
 public static InvokeMemberDynamicCSharpExpression DynamicInvokeMember(Type type, string name, IEnumerable<Type> typeArguments, DynamicCSharpArgument[] arguments)
 {
     return DynamicInvokeMember(type, name, typeArguments, arguments, CSharpBinderFlags.None, null);
 }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="left">The <see cref="Left" /> property of the result.</param>
        /// <param name="right">The <see cref="Right" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public AssignBinaryDynamicCSharpExpression Update(DynamicCSharpArgument left, DynamicCSharpArgument right)
        {
            if (left == this.Left && right == this.Right)
            {
                return this;
            }

            return DynamicCSharpExpression.MakeDynamicBinaryAssign(OperationNodeType, left, right, Flags, Context);
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="operand">The <see cref="Operand" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public UnaryDynamicCSharpExpression Update(DynamicCSharpArgument operand)
        {
            if (operand == this.Operand)
            {
                return this;
            }

            return DynamicCSharpExpression.MakeDynamicUnary(OperationNodeType, operand, Flags, Context);
        }
        public static AssignBinaryDynamicCSharpExpression MakeDynamicBinaryAssign(CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(left, nameof(left));
            ContractUtils.RequiresNotNull(right, nameof(right));

            RequiresCanWrite(left.Expression, nameof(left));
            RequiresCanRead(right.Expression, nameof(right));

            CheckBinaryAssign(binaryType);

            switch (binaryType)
            {
                case CSharpExpressionType.AddAssignChecked:
                case CSharpExpressionType.SubtractAssignChecked:
                case CSharpExpressionType.MultiplyAssignChecked:
                    binderFlags |= CSharpBinderFlags.CheckedContext;
                    break;
            }

            return new AssignBinaryDynamicCSharpExpression(context, binderFlags, binaryType, left, right);
        }
        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);
        }
예제 #41
0
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicAssign(DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return(MakeDynamicBinaryAssign(CSharpExpressionType.Assign, left, right, CSharpBinderFlags.None, null));
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation with the specified binder flags.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression MakeDynamicBinaryAssign(CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags)
 {
     return(MakeDynamicBinaryAssign(binaryType, left, right, binderFlags, null));
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary operation with the specified binder flags.
 /// </summary>
 /// <param name="unaryType">The type of the unary operation to perform.</param>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound unary operation.</returns>
 public static UnaryDynamicCSharpExpression MakeDynamicUnary(ExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags)
 {
     return MakeDynamicUnary(unaryType, operand, binderFlags, null);
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary 'MultiplyAssignChecked' operation.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary 'MultiplyAssignChecked' operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicMultiplyAssignChecked(DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.MultiplyAssignChecked, left, right);
 }
 internal UnaryDynamicCSharpExpression(Type context, CSharpBinderFlags binderFlags, ExpressionType unaryType, DynamicCSharpArgument operand)
     : base(context, binderFlags)
 {
     OperationNodeType = unaryType;
     Operand = operand;
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary 'AndAssign' operation.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary 'AndAssign' operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicAndAssign(DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.AndAssign, left, right);
 }
 public DynamicCSharpArgumentProxy(DynamicCSharpArgument node)
 {
     _node = node;
 }
예제 #48
0
 public XNode GetDebugView(DynamicCSharpArgument argument)
 {
     return(Visit(argument));
 }
 private static CSharpArgumentInfoFlags GetArgumentInfoFlags(DynamicCSharpArgument argument)
 {
     // TODO: Can we infer UseCompileTimeType?
     return(argument.Flags);
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary operation with the specified binder flags.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static BinaryDynamicCSharpExpression MakeDynamicBinary(ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags) =>
 MakeDynamicBinary(binaryType, left, right, binderFlags, context: null);
        public static AssignBinaryDynamicCSharpExpression MakeDynamicBinaryAssign(CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(left, nameof(left));
            ContractUtils.RequiresNotNull(right, nameof(right));

            RequiresCanWrite(left.Expression, nameof(left));
            RequiresCanRead(right.Expression, nameof(right));

            CheckBinaryAssign(binaryType);

            switch (binaryType)
            {
            case CSharpExpressionType.AddAssignChecked:
            case CSharpExpressionType.SubtractAssignChecked:
            case CSharpExpressionType.MultiplyAssignChecked:
                binderFlags |= CSharpBinderFlags.CheckedContext;
                break;
            }

            return(new AssignBinaryDynamicCSharpExpression(context, binderFlags, binaryType, left, right));
        }
예제 #52
0
        public static AssignUnaryDynamicCSharpExpression MakeDynamicUnaryAssign(CSharpExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags, Type context)
        {
            RequiresNotNull(operand, nameof(operand));

            RequiresCanRead(operand.Expression, nameof(operand));
            RequiresCanWrite(operand.Expression, nameof(operand));

            CheckUnaryAssign(unaryType);

            switch (unaryType)
            {
            case CSharpExpressionType.PreIncrementAssignChecked:
            case CSharpExpressionType.PreDecrementAssignChecked:
            case CSharpExpressionType.PostIncrementAssignChecked:
            case CSharpExpressionType.PostDecrementAssignChecked:
                binderFlags |= CSharpBinderFlags.CheckedContext;
                break;
            }

            return(new AssignUnaryDynamicCSharpExpression(context, binderFlags, unaryType, operand));
        }
예제 #53
0
 private XNode Visit(DynamicCSharpArgument node)
 {
     VisitDynamicArgument(node);
     return(_nodes.Pop());
 }
 public DynamicCSharpArgumentProxy(DynamicCSharpArgument node)
 {
     _node = node;
 }
        /// <summary>
        /// Creates a new expression representing a dynamically bound binary operation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="binaryType">The type of the binary operation to perform.</param>
        /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
        /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound binary operation.</returns>
        public static BinaryDynamicCSharpExpression MakeDynamicBinary(ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
        {
            RequiresNotNull(left, nameof(left));
            RequiresNotNull(right, nameof(right));

            CheckBinary(binaryType);

            switch (binaryType)
            {
            case ExpressionType.AddChecked:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.SubtractChecked:
                binderFlags |= CSharpBinderFlags.CheckedContext;
                break;

            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
                binderFlags |= CSharpBinderFlags.BinaryOperationLogical;
                break;
            }

            return(new BinaryDynamicCSharpExpression(context, binderFlags, binaryType, left, right));
        }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicAssign(DynamicCSharpArgument left, DynamicCSharpArgument right)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.Assign, left, right, CSharpBinderFlags.None, null);
 }
예제 #57
0
 /// <summary>
 /// Creates a new expression representing a dynamically bound unary assignment operation with the specified binder flags.
 /// </summary>
 /// <param name="unaryType">The type of the unary operation to perform.</param>
 /// <param name="operand">The dynamic argument representing the operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <returns>A new expression representing a dynamically bound unary assignment operation.</returns>
 public static AssignUnaryDynamicCSharpExpression MakeDynamicUnaryAssign(CSharpExpressionType unaryType, DynamicCSharpArgument operand, CSharpBinderFlags binderFlags) =>
 MakeDynamicUnaryAssign(unaryType, operand, binderFlags, context: null);
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation with the specified binder flags and the specified type context.
 /// </summary>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
 /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression DynamicAssign(DynamicCSharpArgument left, DynamicCSharpArgument right, CSharpBinderFlags binderFlags, Type context)
 {
     return MakeDynamicBinaryAssign(CSharpExpressionType.Assign, left, right, binderFlags, context);
 }
예제 #59
0
 internal AssignUnaryDynamicCSharpExpression(Type context, CSharpBinderFlags binderFlags, CSharpExpressionType unaryType, DynamicCSharpArgument operand)
     : base(context, binderFlags)
 {
     OperationNodeType = unaryType;
     Operand           = operand;
 }
 /// <summary>
 /// Creates a new expression representing a dynamically bound binary assignment operation.
 /// </summary>
 /// <param name="binaryType">The type of the binary operation to perform.</param>
 /// <param name="left">The dynamic argument representing the left operand of the operation.</param>
 /// <param name="right">The dynamic argument representing the right operand of the operation.</param>
 /// <returns>A new expression representing a dynamically bound binary operation.</returns>
 public static AssignBinaryDynamicCSharpExpression MakeDynamicBinaryAssign(CSharpExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right) =>
 MakeDynamicBinaryAssign(binaryType, left, right, CSharpBinderFlags.None, context: null);