public static Expression FoldBinary(BinaryExpression inputExpression) { Expression left = ConstantFolding.Fold(inputExpression.Left); Expression right = ConstantFolding.Fold(inputExpression.Right); LambdaExpression conversion = ConstantFolding.FoldLambda(inputExpression.Conversion); Expression resultExpression; if (left != inputExpression.Left || right != inputExpression.Right || conversion != inputExpression.Conversion) { if (inputExpression.NodeType == ExpressionType.Coalesce) { resultExpression = Expression.Coalesce(left, right, conversion); } else { resultExpression = Expression.MakeBinary(inputExpression.NodeType, left, right, inputExpression.IsLiftedToNull, inputExpression.Method); } } else { resultExpression = inputExpression; } if (IsConstant(left) && inputExpression.NodeType == ExpressionType.Coalesce) { object leftValue = ExpressionSimplifier.Evaluate(left); if (leftValue == null) { resultExpression = right; } else { resultExpression = Expression.Constant(leftValue); } } else if (IsConstant(left) && IsConstant(right)) { resultExpression = ExpressionSimplifier.EvaluateToExpression(resultExpression); } return(resultExpression); }
public static Expression Fold(Expression inputExpression) { if (inputExpression == null) { return(inputExpression); } switch (inputExpression.NodeType) { case ExpressionType.Negate: case ExpressionType.NegateChecked: case ExpressionType.Not: case ExpressionType.Convert: case ExpressionType.ConvertChecked: case ExpressionType.ArrayLength: case ExpressionType.Quote: case ExpressionType.TypeAs: case ExpressionType.UnaryPlus: case ExpressionType.OnesComplement: case ExpressionType.Increment: case ExpressionType.Decrement: return(ConstantFolding.FoldUnary((UnaryExpression)inputExpression)); case ExpressionType.Add: case ExpressionType.AddChecked: case ExpressionType.Subtract: case ExpressionType.SubtractChecked: case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: case ExpressionType.Divide: case ExpressionType.Modulo: case ExpressionType.And: case ExpressionType.AndAlso: case ExpressionType.Or: case ExpressionType.OrElse: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.Coalesce: case ExpressionType.ArrayIndex: case ExpressionType.RightShift: case ExpressionType.LeftShift: case ExpressionType.ExclusiveOr: return(ConstantFolding.FoldBinary((BinaryExpression)inputExpression)); case ExpressionType.TypeIs: return(ConstantFolding.FoldTypeIs((TypeBinaryExpression)inputExpression)); case ExpressionType.Conditional: return(ConstantFolding.FoldConditional((ConditionalExpression)inputExpression)); case ExpressionType.Constant: return(inputExpression); case ExpressionType.Parameter: return(ConstantFolding.FoldParameter((ParameterExpression)inputExpression)); case ExpressionType.MemberAccess: return(ConstantFolding.FoldMemberAccess((MemberExpression)inputExpression)); case ExpressionType.Call: return(ConstantFolding.FoldMethodCall((MethodCallExpression)inputExpression)); case ExpressionType.Lambda: return(ConstantFolding.FoldLambda((LambdaExpression)inputExpression)); case ExpressionType.New: return(ConstantFolding.FoldNew((NewExpression)inputExpression)); case ExpressionType.NewArrayInit: case ExpressionType.NewArrayBounds: return(ConstantFolding.FoldNewArray((NewArrayExpression)inputExpression)); case ExpressionType.Invoke: return(ConstantFolding.FoldInvocation((InvocationExpression)inputExpression)); case ExpressionType.MemberInit: return(ConstantFolding.FoldMemberInit((MemberInitExpression)inputExpression)); case ExpressionType.ListInit: return(ConstantFolding.FoldListInit((ListInitExpression)inputExpression)); default: throw new DocumentQueryException(string.Format(CultureInfo.CurrentUICulture, "Unhandled expression type: '{0}'", inputExpression.NodeType)); } }