internal BinaryDynamicCSharpExpression(Type context, CSharpBinderFlags binderFlags, ExpressionType binaryType, DynamicCSharpArgument left, DynamicCSharpArgument right) : base(context, binderFlags) { OperationNodeType = binaryType; Left = left; Right = right; }
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)); }
/// <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)); }
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)); }
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); }
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)); }
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)); }
/// <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); }
/// <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); }
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); }
/// <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)); }
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); }
/// <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; }
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)); }
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)); }
private XNode Visit(DynamicCSharpArgument node) { VisitDynamicArgument(node); return(_nodes.Pop()); }
/// <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); }
/// <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); }
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);