protected override Expression VisitBinary(BinaryExpression node) { // Note that we're turning shortcutting operators into, well, not. switch (node.NodeType) { case ExpressionType.And: case ExpressionType.AndAlso: if (node.Left.Type == typeof(bool) && node.Right.Type == typeof(bool)) { return(this.Visit(LdapExpressionFactory.And(new[] { node.Left, node.Right }))); } break; case ExpressionType.Or: case ExpressionType.OrElse: if (node.Left.Type == typeof(bool) && node.Right.Type == typeof(bool)) { return(this.Visit(LdapExpressionFactory.Or(new[] { node.Left, node.Right }))); } break; default: break; } return(base.VisitBinary(node)); }
protected override Expression VisitNary(NaryExpression node) { Expression result = base.VisitNary(node); node = result as NaryExpression; if (node == null) { return(result); } switch ((LdapExpressionType)node.NodeType) { case LdapExpressionType.And: // (& X, false) -> false if (node.Clauses.Any(c => c.IsConstant(false))) { return(False); } // If any of the sub-clauses is true, then the 'and' is not affected by them. var andClauses = node.Clauses.Where(c => !c.IsConstant(true)); switch (andClauses.Count()) { case 0: // This is trivially true. // (& true) -> true return(True); case 1: // Just return the sub-clause. // (& true, X) -> X return(andClauses.First()); default: if (andClauses.Count() == node.Clauses.Count) { // No changes // (& X, Y) -> (& X, Y) return(node); } else { // (& true, X, Y) -> (& X, Y) //return node.Update( andClauses ); return(LdapExpressionFactory.And(andClauses)); } } case LdapExpressionType.Or: // (| X, true) -> true if (node.Clauses.Any(c => c.IsConstant(true))) { return(True); } // If any of the sub-clauses is false, then the 'or' is not affected by them. var orClauses = node.Clauses.Where(c => !c.IsConstant(false)); switch (orClauses.Count()) { case 0: // This is trivially false // (| false) -> false return(False); case 1: // Just return the sub-clause. // (| false, X) -> X return(orClauses.First()); default: if (orClauses.Count() == node.Clauses.Count) { // No changes // (| X, Y) -> (| X, Y) return(node); } else { // (| X, Y, false) -> (| X, Y) //return node.Update( orClauses ); return(LdapExpressionFactory.And(orClauses)); } } default: // Some other type of Nary expression... return(node); } }