Skip to content

Commit

Permalink
Add support for array of enums
Browse files Browse the repository at this point in the history
Fixes #176

+semver:bug
  • Loading branch information
hazzik committed Feb 5, 2021
1 parent 41f4e1f commit 1114d17
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
9 changes: 9 additions & 0 deletions src/DelegateDecompiler.Tests/EnumTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using NUnit.Framework;

Expand Down Expand Up @@ -294,6 +295,14 @@ public void Issue160()
Test(expected1, expected2, compiled);
}

[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);
}

private static bool TestEnumMethod(TestEnum p0)
{
throw new NotImplementedException();
Expand Down
40 changes: 25 additions & 15 deletions src/DelegateDecompiler/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,7 @@ Expression Process()
{
var operand = (Type) state.Instruction.Operand;
var expression = state.Stack.Pop();
var size = expression.Expression as ConstantExpression;
if (size != null && (int) size.Value == 0) // optimization
if (expression.Expression is ConstantExpression size && (int) size.Value == 0) // optimization
state.Stack.Push(Expression.NewArrayInit(operand));
else
state.Stack.Push(Expression.NewArrayBounds(operand, expression));
Expand Down Expand Up @@ -1018,38 +1017,49 @@ static void StElem(ProcessorState state)
var index = state.Stack.Pop();
var array = state.Stack.Pop();

var newArray = array.Expression as NewArrayExpression;
if (newArray != null)
if (array.Expression is NewArrayExpression newArray)
{
var expressions = CreateArrayInitExpressions(newArray, value, index);
var newArrayInit = Expression.NewArrayInit(array.Type.GetElementType(), expressions);
array.Expression = newArrayInit;
var elementType = array.Type.GetElementType();
var expressions = CreateArrayInitExpressions(elementType, newArray, value, index);
array.Expression = Expression.NewArrayInit(elementType, expressions);
}
else
{
throw new NotImplementedException();
}
}

static IEnumerable<Expression> CreateArrayInitExpressions(NewArrayExpression newArray, Expression valueExpression, Expression indexExpression)
static IEnumerable<Expression> CreateArrayInitExpressions(
Type elementType, NewArrayExpression newArray, Expression valueExpression, Expression indexExpression)
{
var indexGetter = (Func<int>) Expression.Lambda(indexExpression).Compile();
var index = indexGetter();

Expression[] expressions;
if (newArray.NodeType == ExpressionType.NewArrayInit)
{
var indexGetter = (Func<int>) Expression.Lambda(indexExpression).Compile();
var index = indexGetter();
var expressions = newArray.Expressions.ToArray();

expressions = newArray.Expressions.ToArray();
if (index >= newArray.Expressions.Count)
{
Array.Resize(ref expressions, index + 1);
}

expressions[index] = valueExpression;
}
else if (newArray.NodeType == ExpressionType.NewArrayBounds)
{
var sizeExpression = newArray.Expressions.Single();
var sizeGetter = (Func<int>) Expression.Lambda(sizeExpression).Compile();
var getter = sizeGetter();

return expressions;
expressions = Enumerable.Repeat(ExpressionHelper.Default(elementType), getter).ToArray();
}
else
{
throw new NotSupportedException();
}

return new[] {valueExpression};
expressions[index] = AdjustType(valueExpression, elementType);
return expressions;
}

static void LdC(ProcessorState state, int i)
Expand Down

0 comments on commit 1114d17

Please sign in to comment.