Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions src/DelegateDecompiler.Tests/Employee.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,18 @@ public class Employee
public int To;

[Computed]
public string FullName
{
get { return FirstName + " " + LastName; }
}
public string FullName => FirstName + " " + LastName;

public string FullNameWithoutAttribute
{
get { return FirstName + " " + LastName; }
}
public string FullNameWithoutAttribute => FirstName + " " + LastName;

[Computed]
public string FromTo
{
get { return From + "-" + To; }
}
public string FromTo => From + "-" + To;

[Computed]
public bool IsActive
{
get { return true; }
}
public bool IsActive => true;

[Computed]
public IEmployeeStatus Status => IsActive ? (IEmployeeStatus)new Active() : new Terminated();

[Computed]
public int Count
Expand Down Expand Up @@ -151,4 +142,16 @@ public static string FullName(this Employee e)
return e.FirstName + " " + e.LastName;
}
}

public interface IEmployeeStatus
{
}

public class Active : IEmployeeStatus
{
}

public class Terminated : IEmployeeStatus
{
}
}
16 changes: 16 additions & 0 deletions src/DelegateDecompiler.Tests/QueryableExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -352,5 +352,21 @@ public void Issue78()

AssertAreEqual(expected.Expression, actual.Expression);
}

[Test]
public void Issue127()
{
var employees = new[] { new Employee { FirstName = "Test", LastName = "User" } };

var expected = (from employee in employees.AsQueryable()
where ((IEmployeeStatus)new Active()) is Active
select employee);

var actual = (from employee in employees.AsQueryable()
where employee.Status is Active
select employee).Decompile();

AssertAreEqual(expected.Expression, actual.Expression);
}
}
}
2 changes: 1 addition & 1 deletion src/DelegateDecompiler/Address.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Address Clone(IDictionary<Address, Address> map)
{
if (map.ContainsKey(this))
return map[this];
var result = new Address() { Expression = this.Expression };
var result = new Address { Expression = this.Expression };
map[this] = result;
return result;
}
Expand Down
6 changes: 3 additions & 3 deletions src/DelegateDecompiler/DecompiledQueryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ public virtual IQueryable CreateQuery(Expression expression)

public virtual IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
var decompiled = expression.Decompile();
var decompiled = expression.Decompile().Optimize();
return new DecompiledQueryable<TElement>(this, Inner.CreateQuery<TElement>(decompiled));
}

public object Execute(Expression expression)
{
var decompiled = expression.Decompile();
var decompiled = expression.Decompile().Optimize();
return Inner.Execute(decompiled);
}

public TResult Execute<TResult>(Expression expression)
{
var decompiled = expression.Decompile();
var decompiled = expression.Decompile().Optimize();
return Inner.Execute<TResult>(decompiled);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/DelegateDecompiler/OptimizeExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ protected override Expression VisitConditional(ConditionalExpression node)
var test = Visit(node.Test);
var ifTrue = Visit(node.IfTrue);
var ifFalse = Visit(node.IfFalse);

if (test is ConstantExpression constant && constant.Value is bool boolValue)
{
return boolValue ? ifTrue : ifFalse;
}

if (IsCoalesce(test, ifTrue, out var expression))
{
Expand Down
31 changes: 19 additions & 12 deletions src/DelegateDecompiler/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -955,43 +955,48 @@ internal static Expression AdjustType(Expression expression, Type type)
return expression;
}

var constantExpression = expression as ConstantExpression;
if (constantExpression != null)
if (expression is ConstantExpression constant)
{
if (constantExpression.Value == null)
if (constant.Value == null)
{
return Expression.Constant(null, type);
}

if (constantExpression.Type == typeof(int))
if (constant.Type == typeof(int))
{
if (type.IsEnum)
{
return Expression.Constant(Enum.ToObject(type, constantExpression.Value));
return Expression.Constant(Enum.ToObject(type, constant.Value));
}

if (type == typeof(bool))
{
return Expression.Constant(Convert.ToBoolean(constantExpression.Value));
return Expression.Constant(Convert.ToBoolean(constant.Value));
}

if (type == typeof(byte))
{
return Expression.Constant(Convert.ToByte(constantExpression.Value));
return Expression.Constant(Convert.ToByte(constant.Value));
}

if (type == typeof(sbyte))
{
return Expression.Constant(Convert.ToSByte(constantExpression.Value));
return Expression.Constant(Convert.ToSByte(constant.Value));
}

if (type == typeof(short))
{
return Expression.Constant(Convert.ToInt16(constantExpression.Value));
return Expression.Constant(Convert.ToInt16(constant.Value));
}

if (type == typeof(ushort))
{
return Expression.Constant(Convert.ToUInt16(constantExpression.Value));
return Expression.Constant(Convert.ToUInt16(constant.Value));
}

if (type == typeof(uint))
{
return Expression.Constant(Convert.ToUInt32(constantExpression.Value));
return Expression.Constant(Convert.ToUInt32(constant.Value));
}
}
}
Expand All @@ -1002,6 +1007,7 @@ internal static Expression AdjustType(Expression expression, Type type)
return Expression.NotEqual(expression, Expression.Constant(0));
}
}

if (!type.IsAssignableFrom(expression.Type) && expression.Type.IsEnum && expression.Type.GetEnumUnderlyingType() == type)
{
return Expression.Convert(expression, type);
Expand Down Expand Up @@ -1420,7 +1426,8 @@ static void LdLoc(ProcessorState state, int index)
static void StLoc(ProcessorState state, int index)
{
var info = state.Locals[index];
info.Address = AdjustType(state.Stack.Pop(), info.Type);
var expression = AdjustType(state.Stack.Pop(), info.Type);
info.Address = expression.Type == info.Type ? expression : Expression.Convert(expression, info.Type);
}

static void LdArg(ProcessorState state, int index)
Expand Down