Skip to content

Commit

Permalink
Better behavior when using nullable enums
Browse files Browse the repository at this point in the history
  • Loading branch information
ayende committed Aug 28, 2013
1 parent 12f50d0 commit daba8dd
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
Expand Up @@ -143,10 +143,11 @@ public static Type BaseType(this Type type)

public static bool IsEnum(this Type type)
{
type = Nullable.GetUnderlyingType(type) ?? type;
#if !NETFX_CORE
return type.IsEnum;
return type.IsEnum;
#else
return type.GetTypeInfo().IsEnum;
return type.GetTypeInfo().IsEnum;
#endif
}

Expand Down
44 changes: 36 additions & 8 deletions Raven.Client.Lightweight/Indexes/ExpressionStringBuilder.cs
Expand Up @@ -655,14 +655,23 @@ private void FixupEnumBinaryExpression(ref Expression left, ref Expression right
var expression = ((UnaryExpression)left).Operand;
if (expression.Type.IsEnum() == false)
return;
var constantExpression = right as ConstantExpression;

var constantExpression = SkipConvertExpressions(right) as ConstantExpression;
if (constantExpression == null)
return;
left = expression;
right = convention.SaveEnumsAsIntegers ?
Expression.Constant((int)constantExpression.Value) :
Expression.Constant(Enum.ToObject(expression.Type, constantExpression.Value).ToString());
break;
if (constantExpression.Value == null)
{
right = Expression.Constant(null);
}
else
{
right = convention.SaveEnumsAsIntegers
? Expression.Constant((int) constantExpression.Value)
: Expression.Constant(Enum.ToObject(expression.Type, constantExpression.Value).ToString());

}
break;
}

while (true)
Expand All @@ -679,6 +688,18 @@ private void FixupEnumBinaryExpression(ref Expression left, ref Expression right
}
}

private Expression SkipConvertExpressions(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.ConvertChecked:
case ExpressionType.Convert:
return SkipConvertExpressions(((UnaryExpression) expression).Operand);
default:
return expression;
}
}

/// <summary>
/// Visits the children of the <see cref = "T:System.Linq.Expressions.BlockExpression" />.
/// </summary>
Expand Down Expand Up @@ -999,7 +1020,7 @@ private bool TypeExistsOnServer(Type type)
if (type.Assembly() == typeof(object).Assembly()) // mscorlib
return true;

if (type.Assembly() == typeof (HashSet<>).Assembly()) // System.Core
if (type.Assembly() == typeof(HashSet<>).Assembly()) // System.Core
return true;

if (type.Assembly() == typeof(RavenJObject).Assembly())
Expand Down Expand Up @@ -1298,6 +1319,13 @@ protected override Expression VisitLoop(LoopExpression node)
/// </returns>
protected override Expression VisitMember(MemberExpression node)
{

if (Nullable.GetUnderlyingType(node.Member.DeclaringType) != null && node.Member.Name == "Value")
{
Visit(node.Expression);
return node; // we don't have nullable type on the server side, we can safely ignore this.
}

OutMember(node.Expression, node.Member, node.Expression == null ? node.Type : node.Expression.Type);
return node;
}
Expand Down Expand Up @@ -1426,7 +1454,7 @@ protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBind
protected override Expression VisitMethodCall(MethodCallExpression node)
{
var constantExpression = node.Object as ConstantExpression;
if (constantExpression != null && node.Type == typeof(Delegate))
if (constantExpression != null && node.Type == typeof(Delegate))
{
var methodInfo = constantExpression.Value as MethodInfo;
if (methodInfo != null && methodInfo.DeclaringType == typeof(AbstractCommonApiForIndexesAndTransformers))// a delegate call
Expand Down Expand Up @@ -1488,7 +1516,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
}
else if (node.Method.IsStatic && IsExtensionMethod(node) == false)
{
if (node.Method.DeclaringType == typeof (Enumerable) && node.Method.Name == "Cast")
if (node.Method.DeclaringType == typeof(Enumerable) && node.Method.Name == "Cast")
{
Out("new Raven.Abstractions.Linq.DynamicList(");
Visit(node.Arguments[0]);
Expand Down
2 changes: 1 addition & 1 deletion Raven.Database/Linq/DynamicViewCompiler.cs
Expand Up @@ -119,7 +119,7 @@ private void HandleMapFunctions(ConstructorDeclaration ctor)
}
catch (InvalidOperationException ex)
{
throw new IndexCompilationException(ex.Message, ex)
throw new IndexCompilationException(ex.Message + Environment.NewLine + map, ex)
{
IndexDefinitionProperty = "Maps",
ProblematicText = map
Expand Down
1 change: 1 addition & 0 deletions Raven.Tests/Bugs/MultiMap/MultiMapWithNullableEnum.cs
Expand Up @@ -24,6 +24,7 @@ public void Can_create_index()
new MySearchIndexTask().Execute(store);

WaitForIndexing(store);
WaitForUserToContinueTheTest(store);

Assert.Empty(store.DocumentDatabase.Statistics.Errors);

Expand Down

0 comments on commit daba8dd

Please sign in to comment.