private static Expression TryRemoveNullCheck(ConditionalExpression node) { var binaryTest = node.Test as BinaryExpression; if (binaryTest == null || !(binaryTest.NodeType == ExpressionType.Equal || binaryTest.NodeType == ExpressionType.NotEqual)) { return(null); } var leftConstant = binaryTest.Left as ConstantExpression; var isLeftNullConstant = leftConstant != null && leftConstant.Value == null; var rightConstant = binaryTest.Right as ConstantExpression; var isRightNullConstant = rightConstant != null && rightConstant.Value == null; if (isLeftNullConstant == isRightNullConstant) { return(null); } if (binaryTest.NodeType == ExpressionType.Equal) { var ifTrueConstant = node.IfTrue as ConstantExpression; if (ifTrueConstant == null || ifTrueConstant.Value != null) { return(null); } } else { var ifFalseConstant = node.IfFalse as ConstantExpression; if (ifFalseConstant == null || ifFalseConstant.Value != null) { return(null); } } var testExpression = isLeftNullConstant ? binaryTest.Right : binaryTest.Left; var resultExpression = binaryTest.NodeType == ExpressionType.Equal ? node.IfFalse : node.IfTrue; var nullCheckRemovalTestingVisitor = new NullCheckRemovalTestingVisitor(); if (nullCheckRemovalTestingVisitor.CanRemoveNullCheck(testExpression, resultExpression)) { return(resultExpression); } return(null); }
/// <summary> /// Visits a conditional expression. /// </summary> /// <param name="expression"> The expression to visit. </param> /// <returns> /// An Expression. /// </returns> protected override Expression VisitConditional(ConditionalExpression expression) { Check.NotNull(expression, nameof(expression)); if (expression.IsNullPropagationCandidate(out var testExpression, out var resultExpression) && _nullCheckRemovalTestingVisitor.CanRemoveNullCheck(testExpression, resultExpression)) { return(Visit(resultExpression)); } var test = Visit(expression.Test); if (test?.IsSimpleExpression() == true) { test = Expression.Equal(test, Expression.Constant(true, typeof(bool))); } var ifTrue = Visit(expression.IfTrue); var ifFalse = Visit(expression.IfFalse); if (test != null && ifTrue != null && ifFalse != null) { // 'test ? new { ... } : null' case can't be translated if (ifTrue.Type == typeof(Expression[]) || ifFalse.Type == typeof(Expression[])) { return(null); } if (ifTrue.IsComparisonOperation() || ifFalse.IsComparisonOperation()) { var invertedTest = Invert(test); if (invertedTest != null) { return(Expression.OrElse( Expression.AndAlso(test, ifTrue), Expression.AndAlso(invertedTest, ifFalse))); } } return(expression.Update(test, ifTrue, ifFalse)); } return(null); }
private Expression TryRemoveNullCheck(ConditionalExpression node) { var binaryTest = node.Test as BinaryExpression; if (binaryTest == null || !(binaryTest.NodeType == ExpressionType.Equal || binaryTest.NodeType == ExpressionType.NotEqual)) { return(null); } var isLeftNullConstant = binaryTest.Left.IsNullConstantExpression(); var isRightNullConstant = binaryTest.Right.IsNullConstantExpression(); if (isLeftNullConstant == isRightNullConstant) { return(null); } if (binaryTest.NodeType == ExpressionType.Equal) { var ifTrueConstant = node.IfTrue as ConstantExpression; if (ifTrueConstant == null || ifTrueConstant.Value != null) { return(null); } } else { var ifFalseConstant = node.IfFalse as ConstantExpression; if (ifFalseConstant == null || ifFalseConstant.Value != null) { return(null); } } var testExpression = isLeftNullConstant ? binaryTest.Right : binaryTest.Left; var resultExpression = binaryTest.NodeType == ExpressionType.Equal ? node.IfFalse : node.IfTrue; var nullCheckRemovalTestingVisitor = new NullCheckRemovalTestingVisitor(_queryModelVisitor.QueryCompilationContext); return(nullCheckRemovalTestingVisitor.CanRemoveNullCheck(testExpression, resultExpression) ? resultExpression : null); }