mscorlib(4.0.0.0) API with additions
BinaryExpression.cs
2 using System.Diagnostics;
3 using System.Dynamic.Utils;
4 using System.Reflection;
5 
7 {
9  [DebuggerTypeProxy(typeof(BinaryExpressionProxy))]
10  [global::__DynamicallyInvokable]
12  {
13  private readonly Expression _left;
14 
15  private readonly Expression _right;
16 
19  [global::__DynamicallyInvokable]
20  public override bool CanReduce
21  {
22  [global::__DynamicallyInvokable]
23  get
24  {
25  return IsOpAssignment(NodeType);
26  }
27  }
28 
31  [global::__DynamicallyInvokable]
32  public Expression Right
33  {
34  [global::__DynamicallyInvokable]
35  get
36  {
37  return _right;
38  }
39  }
40 
43  [global::__DynamicallyInvokable]
44  public Expression Left
45  {
46  [global::__DynamicallyInvokable]
47  get
48  {
49  return _left;
50  }
51  }
52 
55  [global::__DynamicallyInvokable]
56  public MethodInfo Method
57  {
58  [global::__DynamicallyInvokable]
59  get
60  {
61  return GetMethod();
62  }
63  }
64 
67  [global::__DynamicallyInvokable]
69  {
70  [global::__DynamicallyInvokable]
71  get
72  {
73  return GetConversion();
74  }
75  }
76 
80  [global::__DynamicallyInvokable]
81  public bool IsLifted
82  {
83  [global::__DynamicallyInvokable]
84  get
85  {
86  if (NodeType == ExpressionType.Coalesce || NodeType == ExpressionType.Assign)
87  {
88  return false;
89  }
90  if (_left.Type.IsNullableType())
91  {
92  MethodInfo method = GetMethod();
93  if (!(method == null))
94  {
95  return !TypeUtils.AreEquivalent(method.GetParametersCached()[0].ParameterType.GetNonRefType(), _left.Type);
96  }
97  return true;
98  }
99  return false;
100  }
101  }
102 
106  [global::__DynamicallyInvokable]
107  public bool IsLiftedToNull
108  {
109  [global::__DynamicallyInvokable]
110  get
111  {
112  if (IsLifted)
113  {
114  return Type.IsNullableType();
115  }
116  return false;
117  }
118  }
119 
120  internal bool IsLiftedLogical
121  {
122  get
123  {
124  Type type = _left.Type;
125  Type type2 = _right.Type;
126  MethodInfo method = GetMethod();
127  ExpressionType nodeType = NodeType;
128  if ((nodeType == ExpressionType.AndAlso || nodeType == ExpressionType.OrElse) && TypeUtils.AreEquivalent(type2, type) && type.IsNullableType() && method != null)
129  {
130  return TypeUtils.AreEquivalent(method.ReturnType, type.GetNonNullableType());
131  }
132  return false;
133  }
134  }
135 
136  internal bool IsReferenceComparison
137  {
138  get
139  {
140  Type type = _left.Type;
141  Type type2 = _right.Type;
142  MethodInfo method = GetMethod();
143  ExpressionType nodeType = NodeType;
144  if ((nodeType == ExpressionType.Equal || nodeType == ExpressionType.NotEqual) && method == null && !type.IsValueType)
145  {
146  return !type2.IsValueType;
147  }
148  return false;
149  }
150  }
151 
152  internal BinaryExpression(Expression left, Expression right)
153  {
154  _left = left;
155  _right = right;
156  }
157 
158  private static bool IsOpAssignment(ExpressionType op)
159  {
160  switch (op)
161  {
162  case ExpressionType.AddAssign:
163  case ExpressionType.AndAssign:
164  case ExpressionType.DivideAssign:
165  case ExpressionType.ExclusiveOrAssign:
166  case ExpressionType.LeftShiftAssign:
167  case ExpressionType.ModuloAssign:
168  case ExpressionType.MultiplyAssign:
169  case ExpressionType.OrAssign:
170  case ExpressionType.PowerAssign:
171  case ExpressionType.RightShiftAssign:
172  case ExpressionType.SubtractAssign:
173  case ExpressionType.AddAssignChecked:
174  case ExpressionType.MultiplyAssignChecked:
175  case ExpressionType.SubtractAssignChecked:
176  return true;
177  default:
178  return false;
179  }
180  }
181 
182  internal virtual MethodInfo GetMethod()
183  {
184  return null;
185  }
186 
192  [global::__DynamicallyInvokable]
194  {
195  if (left == Left && right == Right && conversion == Conversion)
196  {
197  return this;
198  }
199  if (IsReferenceComparison)
200  {
201  if (NodeType == ExpressionType.Equal)
202  {
203  return Expression.ReferenceEqual(left, right);
204  }
205  return Expression.ReferenceNotEqual(left, right);
206  }
207  return Expression.MakeBinary(NodeType, left, right, IsLiftedToNull, Method, conversion);
208  }
209 
212  [global::__DynamicallyInvokable]
213  public override Expression Reduce()
214  {
215  if (IsOpAssignment(NodeType))
216  {
217  switch (_left.NodeType)
218  {
219  case ExpressionType.MemberAccess:
220  return ReduceMember();
221  case ExpressionType.Index:
222  return ReduceIndex();
223  default:
224  return ReduceVariable();
225  }
226  }
227  return this;
228  }
229 
230  private static ExpressionType GetBinaryOpFromAssignmentOp(ExpressionType op)
231  {
232  switch (op)
233  {
234  case ExpressionType.AddAssign:
235  return ExpressionType.Add;
236  case ExpressionType.AddAssignChecked:
237  return ExpressionType.AddChecked;
238  case ExpressionType.SubtractAssign:
239  return ExpressionType.Subtract;
240  case ExpressionType.SubtractAssignChecked:
241  return ExpressionType.SubtractChecked;
242  case ExpressionType.MultiplyAssign:
243  return ExpressionType.Multiply;
244  case ExpressionType.MultiplyAssignChecked:
245  return ExpressionType.MultiplyChecked;
246  case ExpressionType.DivideAssign:
247  return ExpressionType.Divide;
248  case ExpressionType.ModuloAssign:
249  return ExpressionType.Modulo;
250  case ExpressionType.PowerAssign:
251  return ExpressionType.Power;
252  case ExpressionType.AndAssign:
253  return ExpressionType.And;
254  case ExpressionType.OrAssign:
255  return ExpressionType.Or;
256  case ExpressionType.RightShiftAssign:
257  return ExpressionType.RightShift;
258  case ExpressionType.LeftShiftAssign:
259  return ExpressionType.LeftShift;
260  case ExpressionType.ExclusiveOrAssign:
261  return ExpressionType.ExclusiveOr;
262  default:
263  throw Error.InvalidOperation("op");
264  }
265  }
266 
267  private Expression ReduceVariable()
268  {
269  ExpressionType binaryOpFromAssignmentOp = GetBinaryOpFromAssignmentOp(NodeType);
270  Expression expression = Expression.MakeBinary(binaryOpFromAssignmentOp, _left, _right, liftToNull: false, Method);
271  LambdaExpression conversion = GetConversion();
272  if (conversion != null)
273  {
274  expression = Expression.Invoke(conversion, expression);
275  }
276  return Expression.Assign(_left, expression);
277  }
278 
279  private Expression ReduceMember()
280  {
281  MemberExpression memberExpression = (MemberExpression)_left;
282  if (memberExpression.Expression == null)
283  {
284  return ReduceVariable();
285  }
286  ParameterExpression parameterExpression = Expression.Variable(memberExpression.Expression.Type, "temp1");
287  Expression expression = Expression.Assign(parameterExpression, memberExpression.Expression);
288  ExpressionType binaryOpFromAssignmentOp = GetBinaryOpFromAssignmentOp(NodeType);
289  Expression expression2 = Expression.MakeBinary(binaryOpFromAssignmentOp, Expression.MakeMemberAccess(parameterExpression, memberExpression.Member), _right, liftToNull: false, Method);
290  LambdaExpression conversion = GetConversion();
291  if (conversion != null)
292  {
293  expression2 = Expression.Invoke(conversion, expression2);
294  }
295  ParameterExpression parameterExpression2 = Expression.Variable(expression2.Type, "temp2");
296  expression2 = Expression.Assign(parameterExpression2, expression2);
297  Expression expression3 = Expression.Assign(Expression.MakeMemberAccess(parameterExpression, memberExpression.Member), parameterExpression2);
298  Expression expression4 = parameterExpression2;
299  return Expression.Block(new ParameterExpression[2]
300  {
301  parameterExpression,
302  parameterExpression2
303  }, expression, expression2, expression3, expression4);
304  }
305 
306  private Expression ReduceIndex()
307  {
308  IndexExpression indexExpression = (IndexExpression)_left;
309  List<ParameterExpression> list = new List<ParameterExpression>(indexExpression.Arguments.Count + 2);
310  List<Expression> list2 = new List<Expression>(indexExpression.Arguments.Count + 3);
311  ParameterExpression parameterExpression = Expression.Variable(indexExpression.Object.Type, "tempObj");
312  list.Add(parameterExpression);
313  list2.Add(Expression.Assign(parameterExpression, indexExpression.Object));
314  List<Expression> list3 = new List<Expression>(indexExpression.Arguments.Count);
315  foreach (Expression argument in indexExpression.Arguments)
316  {
317  ParameterExpression parameterExpression2 = Expression.Variable(argument.Type, "tempArg" + list3.Count);
318  list.Add(parameterExpression2);
319  list3.Add(parameterExpression2);
320  list2.Add(Expression.Assign(parameterExpression2, argument));
321  }
322  IndexExpression left = Expression.MakeIndex(parameterExpression, indexExpression.Indexer, list3);
323  ExpressionType binaryOpFromAssignmentOp = GetBinaryOpFromAssignmentOp(NodeType);
324  Expression expression = Expression.MakeBinary(binaryOpFromAssignmentOp, left, _right, liftToNull: false, Method);
325  LambdaExpression conversion = GetConversion();
326  if (conversion != null)
327  {
328  expression = Expression.Invoke(conversion, expression);
329  }
330  ParameterExpression parameterExpression3 = Expression.Variable(expression.Type, "tempValue");
331  list.Add(parameterExpression3);
332  list2.Add(Expression.Assign(parameterExpression3, expression));
333  list2.Add(Expression.Assign(left, parameterExpression3));
334  return Expression.Block(list, list2);
335  }
336 
337  internal virtual LambdaExpression GetConversion()
338  {
339  return null;
340  }
341 
345  [global::__DynamicallyInvokable]
346  protected internal override Expression Accept(ExpressionVisitor visitor)
347  {
348  return visitor.VisitBinary(this);
349  }
350 
351  internal static Expression Create(ExpressionType nodeType, Expression left, Expression right, Type type, MethodInfo method, LambdaExpression conversion)
352  {
353  if (nodeType == ExpressionType.Assign)
354  {
355  return new AssignBinaryExpression(left, right);
356  }
357  if (conversion != null)
358  {
359  return new CoalesceConversionBinaryExpression(left, right, conversion);
360  }
361  if (method != null)
362  {
363  return new MethodBinaryExpression(nodeType, left, right, type, method);
364  }
365  if (type == typeof(bool))
366  {
367  return new LogicalBinaryExpression(nodeType, left, right);
368  }
369  return new SimpleBinaryExpression(nodeType, left, right, type);
370  }
371 
372  internal Expression ReduceUserdefinedLifted()
373  {
374  ParameterExpression parameterExpression = Expression.Parameter(_left.Type, "left");
375  ParameterExpression parameterExpression2 = Expression.Parameter(Right.Type, "right");
376  string name = (NodeType == ExpressionType.AndAlso) ? "op_False" : "op_True";
377  MethodInfo booleanOperator = TypeUtils.GetBooleanOperator(Method.DeclaringType, name);
378  return Expression.Block(new ParameterExpression[1]
379  {
380  parameterExpression
381  }, Expression.Assign(parameterExpression, _left), Expression.Condition(Expression.Property(parameterExpression, "HasValue"), Expression.Condition(Expression.Call(booleanOperator, Expression.Call(parameterExpression, "GetValueOrDefault", null)), parameterExpression, Expression.Block(new ParameterExpression[1]
382  {
383  parameterExpression2
384  }, Expression.Assign(parameterExpression2, _right), Expression.Condition(Expression.Property(parameterExpression2, "HasValue"), Expression.Convert(Expression.Call(Method, Expression.Call(parameterExpression, "GetValueOrDefault", null), Expression.Call(parameterExpression2, "GetValueOrDefault", null)), Type), Expression.Constant(null, Type)))), Expression.Constant(null, Type)));
385  }
386  }
387 }
Expression Right
Gets the right operand of the binary operation.
int Count
Gets the number of elements contained in the T:System.Collections.Generic.List`1.
Definition: List.cs:296
Discovers the attributes of a method and provides access to method metadata.
Definition: MethodInfo.cs:13
Definition: __Canon.cs:3
virtual Type ReturnType
Gets the return type of this method.
Definition: MethodInfo.cs:23
BinaryExpression Update(Expression left, LambdaExpression conversion, Expression right)
Creates a new expression that is like this one, but using the supplied children. If all of the childr...
bool IsLiftedToNull
Gets a value that indicates whether the expression tree node represents a lifted call to an operator ...
void Add(T item)
Adds an object to the end of the T:System.Collections.Generic.List`1.
Definition: List.cs:510
Provides the base class from which the classes that represent expression tree nodes are derived....
Definition: Expression.cs:17
bool IsLifted
Gets a value that indicates whether the expression tree node represents a lifted call to an operator.
MethodInfo Method
Gets the implementing method for the binary operation.
LambdaExpression Conversion
Gets the type conversion function that is used by a coalescing or compound assignment operation.
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
Type DeclaringType
Provides COM objects with version-independent access to the P:System.Reflection.MemberInfo....
Definition: _MethodInfo.cs:31
ExpressionType
Describes the node types for the nodes of an expression tree.
virtual internal Expression VisitBinary(BinaryExpression node)
Visits the children of the T:System.Linq.Expressions.BinaryExpression.
internal override Expression Accept(ExpressionVisitor visitor)
Dispatches to the specific visit method for this node type. For example, T:System....
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition: List.cs:14
override Expression Reduce()
Reduces the binary expression node to a simpler expression.
override bool CanReduce
Gets a value that indicates whether the expression tree node can be reduced.
Describes a lambda expression. This captures a block of code that is similar to a ....
Represents an expression that has a binary operator.
Expression Left
Gets the left operand of the binary operation.
Represents a visitor or rewriter for expression trees.