Skip to content

Commit

Permalink
Handle unary operator on enums
Browse files Browse the repository at this point in the history
  • Loading branch information
metoule committed Nov 27, 2022
1 parent 6ed699e commit a91ed74
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
14 changes: 14 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,15 @@ 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(result, ~RegexOptions.None);

// 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 a91ed74

Please sign in to comment.