Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
dd2247a
Initial plan
Copilot Nov 1, 2025
d1e5054
Fix test method signatures and initial enum comparison fix attempt
Copilot Nov 1, 2025
33ff954
Fix enum comparison for enums with non-int underlying types
Copilot Nov 1, 2025
4f04ada
Remove unused IsIntegralType method
Copilot Nov 1, 2025
b387cf1
Add bitwise operation support for non-int enums and improve long enum…
Copilot Nov 1, 2025
7c61735
Add arithmetic operation support and long enum constant unwrapping
Copilot Nov 1, 2025
c2adcf6
Optimize long constant conversion - 485/521 tests passing
Copilot Nov 1, 2025
3fdd774
Generalize enum conversion logic - remove operation-specific special …
Copilot Nov 1, 2025
ff04bc8
Fix unary NOT and method parameter conversions - 7 failures remaining
Copilot Nov 1, 2025
9117f8d
Fix array initialization and restore NOT optimization - 6 failures re…
Copilot Nov 1, 2025
3ad4d49
Add HasFlag instance type checking - 6 failures remaining
Copilot Nov 1, 2025
86ca5b9
Fix int-based enum nullable conversions - 5 failures remaining
Copilot Nov 1, 2025
7c673e5
Fix nullable enum conversions for byte/short enums - 4 failures remai…
Copilot Nov 1, 2025
feca7fc
Fix HasFlag and most enum conversion issues - 493/521 tests passing (…
Copilot Nov 1, 2025
f236a93
Fix double conversion in enum to long cast - 520/521 tests passing!
Copilot Nov 1, 2025
34fc862
Add enum check to coalesce optimizer - 520/521 tests passing (99.8%)
Copilot Nov 1, 2025
911b584
WIP: Refactor optimizations from Processors to OptimizeExpressionVisi…
Copilot Nov 1, 2025
5105bad
Simplify CallProcessor and move HasFlag logic to minimal required cod…
Copilot Nov 1, 2025
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
70 changes: 35 additions & 35 deletions src/DelegateDecompiler.Tests/ByteEnumTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void TestEnumParameterEqualsEnumConstant()
Expression<Func<TestEnum, bool>> expected1 = x => x == TestEnum.Bar;
Expression<Func<TestEnum, bool>> expected2 = x => (int) x == (int) TestEnum.Bar;
Func<TestEnum, bool> compiled = x => x == TestEnum.Bar;
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
Expand All @@ -37,7 +37,7 @@ public void TestEnumConstantEqualsEnumParameter()
Expression<Func<TestEnum, bool>> expected1 = x => TestEnum.Bar == x;
Expression<Func<TestEnum, bool>> expected2 = x => (int) TestEnum.Bar == (int) x;
Func<TestEnum, bool> compiled = x => TestEnum.Bar == x;
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
Expand All @@ -46,7 +46,7 @@ public void TestEnumPropertyNotEqualsFooOrElseEnumPropertyEqualsBar()
Expression<Func<TestEnum, bool>> expected1 = x => (x != TestEnum.Bar) || (x == TestEnum.Foo);
Expression<Func<TestEnum, bool>> expected2 = x => ((int)x != (int)TestEnum.Bar) || ((int)x == (int)TestEnum.Foo);
Func<TestEnum, bool> compiled = x => (x != TestEnum.Bar) || (x == TestEnum.Foo);
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
Expand All @@ -55,15 +55,15 @@ public void TestEnumPropertyEqualsFooOrElseEnumPropertyEqualsBar()
Expression<Func<TestEnum, bool>> expected1 = x => (x == TestEnum.Bar) || (x == TestEnum.Foo);
Expression<Func<TestEnum, bool>> expected2 = x => ((int)x == (int)TestEnum.Bar) || ((int)x == (int)TestEnum.Foo);
Func<TestEnum, bool> compiled = x => (x == TestEnum.Bar) || (x == TestEnum.Foo);
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
public void TestEnumParametersEqual()
{
Expression<Func<TestEnum, TestEnum, bool>> expected = (x, y) => x == y;
Func<TestEnum, TestEnum, bool> compiled = (x, y) => x == y;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
Expand All @@ -72,7 +72,7 @@ public void TestEnumParameterNotEqualsEnumConstant()
Expression<Func<TestEnum, bool>> expected1 = x => x != TestEnum.Bar;
Expression<Func<TestEnum, bool>> expected2 = x => (int) x != (int) TestEnum.Bar;
Func<TestEnum, bool> compiled = x => x != TestEnum.Bar;
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
Expand All @@ -81,159 +81,159 @@ public void TestEnumConstantNotEqualsEnumParameter()
Expression<Func<TestEnum, bool>> expected1 = x => TestEnum.Bar != x;
Expression<Func<TestEnum, bool>> expected2 = x => (int) TestEnum.Bar != (int) x;
Func<TestEnum, bool> compiled = x => TestEnum.Bar != x;
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
public void TestEnumParametersNotEqual()
{
Expression<Func<TestEnum, TestEnum, bool>> expected = (x, y) => x != y;
Func<TestEnum, TestEnum, bool> compiled = (x, y) => x != y;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumConstantHasFlagEnumParameter()
{
Expression<Func<TestFlagEnum, bool>> expected = x => TestFlagEnum.Bar.HasFlag(x);
Func<TestFlagEnum, bool> compiled = x => TestFlagEnum.Bar.HasFlag(x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterHasFlagEnumConstant()
{
Expression<Func<TestFlagEnum, bool>> expected = x => x.HasFlag(TestFlagEnum.Bar);
Func<TestFlagEnum, bool> compiled = x => x.HasFlag(TestFlagEnum.Bar);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterHasFlagEnumParameter()
{
Expression<Func<TestFlagEnum, bool>> expected = x => x.HasFlag(x);
Func<TestFlagEnum, bool> compiled = x => x.HasFlag(x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumConstantAndEnumParameter()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => TestFlagEnum.Bar & x;
Func<TestFlagEnum, TestFlagEnum> compiled = x => TestFlagEnum.Bar & x;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAndEnumConstant()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => x & TestFlagEnum.Bar ;
Func<TestFlagEnum, TestFlagEnum> compiled = x => x & TestFlagEnum.Bar ;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestNotEnumParameter()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => ~ x;
Func<TestFlagEnum, TestFlagEnum> compiled = x => ~ x;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAndEnumParameter()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => x & x;
Func<TestFlagEnum, TestFlagEnum> compiled = x => x & x ;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumConstantOrEnumParameter()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => TestFlagEnum.Bar | x;
Func<TestFlagEnum, TestFlagEnum> compiled = x => TestFlagEnum.Bar | x;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterOrEnumConstant()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => x | TestFlagEnum.Bar ;
Func<TestFlagEnum, TestFlagEnum> compiled = x => x | TestFlagEnum.Bar ;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterOrEnumParameter()
{
Expression<Func<TestFlagEnum, TestFlagEnum>> expected = x => x | x;
Func<TestFlagEnum, TestFlagEnum> compiled = x => x | x ;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodParameter()
{
Expression<Func<TestEnum, bool>> expected = x => TestEnumMethod(x);
Func<TestEnum, bool> compiled = x => TestEnumMethod(x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithEnumParameter()
{
Expression<Func<TestEnum, bool>> expected = x => EnumMethod(x);
Func<TestEnum, bool> compiled = x => EnumMethod(x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithObjectParameter()
{
Expression<Func<TestEnum, bool>> expected = x => ObjectMethod(x);
Func<TestEnum, bool> compiled = x => ObjectMethod(x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithInt8Parameter()
{
Expression<Func<TestEnum, bool>> expected = x => Int8Method((byte) x);
Func<TestEnum, bool> compiled = x => Int8Method((byte) x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithInt16Parameter()
{
Expression<Func<TestEnum, bool>> expected = x => Int16Method((short) x);
Func<TestEnum, bool> compiled = x => Int16Method((short) x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithInt32Parameter()
{
Expression<Func<TestEnum, bool>> expected = x => Int32Method((int) x);
Func<TestEnum, bool> compiled = x => Int32Method((int) x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsMethodWithInt64Parameter()
{
Expression<Func<TestEnum, bool>> expected = x => Int64Method((long) x);
Func<TestEnum, bool> compiled = x => Int64Method((long) x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumParameterAsGenericMethodParameter()
{
Expression<Func<TestEnum, bool>> expected = x => GenericMethod(x);
Func<TestEnum, bool> compiled = x => GenericMethod(x);
Test(expected, compiled);
Test(compiled, expected);
}

// The following tests check for the insertion of Expression.Convert in the expression tree for compatible types
Expand All @@ -243,55 +243,55 @@ public void TestEnumCastSubtraction()
{
Expression<Func<TestEnum, int>> expected = x => (int)x - 10;
Func<TestEnum, int> compiled = x => (int)x - 10;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumCastMod()
{
Expression<Func<TestEnum, int>> expected = x => (int)x % 10;
Func<TestEnum, int> compiled = x => (int)x % 10;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumCastEquals()
{
Expression<Func<TestEnum, bool>> expected = x => (int)x == 10;
Func<TestEnum, bool> compiled = x => (int)x == 10;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void TestEnumCastGreaterThan()
{
Expression<Func<TestEnum, bool>> expected = x => (int)x > 10;
Func<TestEnum, bool> compiled = x => (int)x > 10;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void Issue61()
{
Expression<Func<decimal, decimal>> expected = x => Decimal.Round(x, 3, MidpointRounding.AwayFromZero);
Func<decimal, decimal> compiled = x => Decimal.Round(x, 3, MidpointRounding.AwayFromZero);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void Issue98A()
{
Expression<Func<TestEnum?, TestEnum, bool>> expected = (x, y) => x == y;
Func<TestEnum?, TestEnum, bool> compiled = (x, y) => x == y;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
public void Issue98B()
{
Expression<Func<TestEnum?, bool>> expected = x => x == TestEnum.Foo;
Func<TestEnum?, bool> compiled = x => x == TestEnum.Foo;
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
Expand All @@ -300,15 +300,15 @@ public void Issue160()
Expression<Func<int?, bool>> expected1 = x => (TestEnum?) x == TestEnum.Bar;
Expression<Func<int?, bool>> expected2 = x => (x.HasValue ? (TestEnum?) (x ?? 0) : null) == TestEnum.Bar;
Func<int?, bool> compiled = x => (TestEnum?) x == TestEnum.Bar;
Test(expected1, expected2, compiled);
Test(compiled, expected1, expected2);
}

[Test]
public void Issue176Array()
{
Expression<Func<TestEnum, bool>> expected = x => new [] {TestEnum.Foo, TestEnum.Bar}.Contains(x);
Func<TestEnum, bool> compiled = x => new[] {TestEnum.Foo, TestEnum.Bar}.Contains(x);
Test(expected, compiled);
Test(compiled, expected);
}

private static bool TestEnumMethod(TestEnum p0)
Expand Down
2 changes: 1 addition & 1 deletion src/DelegateDecompiler.Tests/EnumTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public void TestEnumParameterAsMethodWithInt8Parameter()
{
Expression<Func<TestEnum, bool>> expected = x => Int8Method((byte) x);
Func<TestEnum, bool> compiled = x => Int8Method((byte) x);
Test(expected, compiled);
Test(compiled, expected);
}

[Test]
Expand Down
Loading