private bool BoolAgainstBool(Expression node, out Expression reduced) { var binary = node as BinaryExpression; if (binary != null) { if (ExpressionHelpers.IsBool(binary.Left) && ExpressionHelpers.IsBool(binary.Right)) { //We have some kind of boolean expression like true != false. //Evaluate it and replace it with its resulting value var l = SubstituteExpression.Strip(binary.Left); var r = SubstituteExpression.Strip(binary.Right); var b = Expression.MakeBinary(node.NodeType, l, r); var lambda = Expression.Lambda(b); var result = lambda.Compile().DynamicInvoke(); reduced = Expression.Constant(result); return(true); } } reduced = null; return(false); }
private bool DifferentEnumTypesInternal(Expression node, Expression first, Expression second, out Expression outExpr) { var firstUnwrapped = SubstituteExpression.Strip(ExpressionHelpers.UnwrapCast(first)); var secondUnwrapped = SubstituteExpression.Strip(ExpressionHelpers.UnwrapCast(second)); if (IsEnum(firstUnwrapped) && IsEnum(secondUnwrapped)) { var property = ExpressionSearcher.Search(firstUnwrapped, p => p is PropertyExpression).FirstOrDefault(); if (property != null) { var comparison = ExpressionSearcher.Search(secondUnwrapped, e => IsEnum(e) && e.NodeType != ExpressionType.Convert && e.NodeType != ExpressionType.ConvertChecked); var firstComparison = comparison.FirstOrDefault(); if (firstComparison != null) { if (firstComparison.Type.IsEnum && firstComparison.Type != property.Type) { if (strict) { throw Error.InvalidEnumComparison(node, firstUnwrapped, secondUnwrapped); } Logger.Log($"Condition {node} compares enums of different types. Reducing to 'True'", Indentation.Six); outExpr = Expression.Constant(true); return(true); } else { var constant = firstComparison as ConstantExpression; if (constant != null) { if (property.Type != constant.Value.GetType()) { Logger.Log($"Condition {node} compares enums of different types. Reducing to 'True'", Indentation.Six); if (strict) { throw Error.InvalidEnumComparison(node, firstUnwrapped, secondUnwrapped); } outExpr = Expression.Constant(true); return(true); } } } } } } outExpr = null; return(false); }
protected override Expression VisitLambda <TNode>(Expression <TNode> lambda) { var body = Visit(lambda.Body); if (body != lambda.Body) { var substituteBody = new SubstituteExpression(lambda.Body, body); return(Expression.Lambda(lambda.Type, substituteBody, lambda.Parameters)); } return(lambda); }
private BinaryExpression ReduceDoubleFalseInternal(BinaryExpression original, BinaryExpression binaryInternal) { var innerLeft = SubstituteExpression.Strip(binaryInternal.Left); var innerRight = SubstituteExpression.Strip(binaryInternal.Right); if (IsFalse(innerLeft, binaryInternal.NodeType)) { return(ReduceDoubleFalseInternalInternal(innerRight)); } if (IsFalse(innerRight, binaryInternal.NodeType)) { return(ReduceDoubleFalseInternalInternal(innerLeft)); } return(original); }
public BinaryExpression ReduceDoubleFalse(BinaryExpression expr) { var left = SubstituteExpression.Strip(expr.Left); var right = SubstituteExpression.Strip(expr.Right); if (IsFalse(left, expr.NodeType) && right is BinaryExpression) { return(ReduceDoubleFalseInternal(expr, (BinaryExpression)right)); } if (IsFalse(right, expr.NodeType) && left is BinaryExpression) { return(ReduceDoubleFalseInternal(expr, (BinaryExpression)left)); } return(expr); }
protected override Expression VisitExtension(Expression node) { var substitute = node as SubstituteExpression; if (substitute != null) { var original = Visit(substitute.Original); var replacement = Visit(substitute.Replacement); if (original != substitute.Original || replacement != substitute.Replacement) { node = new SubstituteExpression(original, replacement); } return(node); } return(base.VisitExtension(node)); }