Skip to content
44 changes: 44 additions & 0 deletions src/DelegateDecompiler.Tests/ThrowIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Linq.Expressions;
using NUnit.Framework;

namespace DelegateDecompiler.Tests
{
[TestFixture]
public class ThrowTests : DecompilerTestsBase
{
[Test]
public void SimpleThrow()
{
Action compiled = () => throw new ArgumentException("test");

// Create expected expression programmatically to match what decompiler produces
var constructor = typeof(ArgumentException).GetConstructor(new[] { typeof(string) });
var messageConstant = Expression.Constant("test");
var newExpression = Expression.New(constructor, messageConstant);
var throwExpression = Expression.Throw(newExpression);
var expectedExpression = Expression.Lambda<Action>(throwExpression);

Test(compiled, expectedExpression);
}

[Test]
public void ConditionalThrowInTernaryOperator()
{
Func<int, string> compiled = x => x > 0 ? "positive" : throw new ArgumentException("negative");

// Create expected expression programmatically for conditional with throw
var parameter = Expression.Parameter(typeof(int), "x");
var positiveConstant = Expression.Constant("positive");
var constructor = typeof(ArgumentException).GetConstructor(new[] { typeof(string) });
var messageConstant = Expression.Constant("negative");
var newExpression = Expression.New(constructor, messageConstant);
var throwExpression = Expression.Throw(newExpression, typeof(string));
var condition = Expression.GreaterThan(parameter, Expression.Constant(0));
var conditionalExpression = Expression.Condition(condition, positiveConstant, throwExpression);
var expectedExpression = Expression.Lambda<Func<int, string>>(conditionalExpression, parameter);

Test(compiled, expectedExpression);
}
}
}
1 change: 1 addition & 0 deletions src/DelegateDecompiler/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public static Expression Process(bool isStatic, VariableInfo[] locals, IList<Add
new StfldProcessor(),
new StsfldProcessor(),
new StelemProcessor(),
new ThrowProcessor(),
// This should be last one
new UnsupportedOpcodeProcessor()
};
Expand Down
19 changes: 19 additions & 0 deletions src/DelegateDecompiler/Processors/ThrowProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Linq.Expressions;
using System.Reflection.Emit;

namespace DelegateDecompiler.Processors;

internal class ThrowProcessor : IProcessor
{
public bool Process(ProcessorState state)
{
if (state.Instruction.OpCode == OpCodes.Throw)
{
var exception = state.Stack.Pop();
state.Stack.Push(Expression.Throw(exception));
return true;
}

return false;
}
}
Loading