in EsentCollections/PredicateExpressionEvaluator.cs [107:182]
private static KeyRange<TKey> GetKeyRangeOfSubtree(Expression expression, MemberInfo keyMemberInfo)
{
switch (expression.NodeType)
{
case ExpressionType.AndAlso:
{
// Intersect the left and right parts
var binaryExpression = (BinaryExpression)expression;
return GetKeyRangeOfSubtree(binaryExpression.Left, keyMemberInfo)
& GetKeyRangeOfSubtree(binaryExpression.Right, keyMemberInfo);
}
case ExpressionType.OrElse:
{
// Union the left and right parts
var binaryExpression = (BinaryExpression)expression;
return GetKeyRangeOfSubtree(binaryExpression.Left, keyMemberInfo)
| GetKeyRangeOfSubtree(binaryExpression.Right, keyMemberInfo);
}
case ExpressionType.Not:
{
var unaryExpression = (UnaryExpression)expression;
return GetNegationOf(unaryExpression.Operand, keyMemberInfo);
}
case ExpressionType.Call:
{
KeyRange<TKey> keyRange;
if (IsComparisonMethod((MethodCallExpression)expression, keyMemberInfo, out keyRange))
{
return keyRange;
}
break;
}
case ExpressionType.Equal:
case ExpressionType.LessThan:
case ExpressionType.LessThanOrEqual:
case ExpressionType.GreaterThan:
case ExpressionType.GreaterThanOrEqual:
{
// Return a range
var binaryExpression = (BinaryExpression)expression;
TKey value;
ExpressionType expressionType;
if (IsConstantComparison(binaryExpression, keyMemberInfo, out value, out expressionType))
{
switch (expressionType)
{
case ExpressionType.Equal:
var key = Key<TKey>.CreateKey(value, true);
return new KeyRange<TKey>(key, key);
case ExpressionType.LessThan:
return new KeyRange<TKey>(null, Key<TKey>.CreateKey(value, false));
case ExpressionType.LessThanOrEqual:
return new KeyRange<TKey>(null, Key<TKey>.CreateKey(value, true));
case ExpressionType.GreaterThan:
return new KeyRange<TKey>(Key<TKey>.CreateKey(value, false), null);
case ExpressionType.GreaterThanOrEqual:
return new KeyRange<TKey>(Key<TKey>.CreateKey(value, true), null);
default:
throw new InvalidOperationException(expressionType.ToString());
}
}
break;
}
default:
break;
}
return KeyRange<TKey>.OpenRange;
}