Skip to content

Commit

Permalink
Handle unary operator on enums (#265)
Browse files Browse the repository at this point in the history
* Handle unary operator on enums
Fixes #261
  • Loading branch information
metoule authored Dec 1, 2022
1 parent 6ed699e commit 25a41f5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/DynamicExpresso.Core/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,11 @@ private Expression GenerateUnary(ExpressionType unaryType, Expression expr)
if (IsDynamicExpression(expr))
return GenerateUnaryDynamic(unaryType, expr);

// enum unary operations are not resolved properly by Linq
var unaryOps = new[] { ExpressionType.OnesComplement };
if (expr.Type.IsEnum && unaryOps.Contains(unaryType))
return GenerateUnaryEnums(unaryType, expr);

// find the overloaded unary operator
string opName;
switch (unaryType)
Expand All @@ -664,6 +669,14 @@ private Expression GenerateUnary(ExpressionType unaryType, Expression expr)
return Expression.MakeUnary(unaryType, expr, null, operatorMethod);
}

private Expression GenerateUnaryEnums(ExpressionType unaryType, Expression expr)
{
var enumType = expr.Type;
var underlyingType = enumType.GetEnumUnderlyingType();
expr = Expression.Convert(expr, underlyingType);
return Expression.MakeUnary(unaryType, expr, enumType);
}

private Expression GenerateUnaryDynamic(ExpressionType unaryType, Expression expr)
{
var binder = Microsoft.CSharp.RuntimeBinder.Binder.UnaryOperation(
Expand Down
15 changes: 15 additions & 0 deletions test/DynamicExpresso.UnitTest/GithubIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,21 @@ public class PageType
public string PageName { get; set; }
public int VisualCount { get; set; }
}

[Test]
public void GitHub_Issue_261()
{
var target = new Interpreter();
target.Reference(typeof(RegexOptions));
target.Reference(typeof(DateTimeKind));

var result = target.Eval<RegexOptions>("~RegexOptions.None");
Assert.AreEqual(~RegexOptions.None, result);

// DateTimeKind doesn't have the Flags attribute: the bitwise operation returns an integer
var result2 = target.Eval<DateTimeKind>("~DateTimeKind.Local");
Assert.AreEqual((DateTimeKind)(-3), result2);
}
}

internal static class GithubIssuesTestExtensionsMethods
Expand Down

0 comments on commit 25a41f5

Please sign in to comment.