Browse Source

Add basic unit tests for ref returns, locals and conditional

pull/1087/head
Siegfried Pammer 7 years ago
parent
commit
704eec86ae
  1. 6
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 1
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 79
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/RefLocalsAndReturns.cs
  4. 16
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  5. 2
      ICSharpCode.Decompiler/Semantics/MemberResolveResult.cs

6
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -190,6 +190,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -190,6 +190,12 @@ namespace ICSharpCode.Decompiler.Tests
RunCS(options: options);
}
[Test]
public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void BitNot([Values(false, true)] bool force32Bit)
{

1
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -63,6 +63,7 @@ @@ -63,6 +63,7 @@
<ItemGroup>
<Compile Include="DataFlowTest.cs" />
<Compile Include="TestCases\Correctness\RefLocalsAndReturns.cs" />
<Compile Include="VBPrettyTestRunner.cs" />
<Compile Include="TestCases\VBPretty\Async.cs" />
<Compile Include="UglyTestRunner.cs" />

79
ICSharpCode.Decompiler.Tests/TestCases/Correctness/RefLocalsAndReturns.cs

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
class RefLocalsAndReturns
{
static int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };
static string[] strings = { "Hello", "World" };
static string NullString = "";
static int DefaultInt = 0;
public delegate ref TReturn RefFunc<T1, TReturn>(T1 param1);
public static TReturn Invoker<T1, TReturn>(RefFunc<T1, TReturn> action, T1 value)
{
return action(value);
}
public static ref int FindNumber(int target)
{
for (int ctr = 0; ctr < numbers.Length; ctr++) {
if (numbers[ctr] >= target)
return ref numbers[ctr];
}
return ref numbers[0];
}
public static ref int LastNumber()
{
return ref numbers[numbers.Length - 1];
}
public static ref int ElementAtOrDefault(int index)
{
return ref index < 0 || index >= numbers.Length ? ref DefaultInt : ref numbers[index];
}
public static ref int LastOrDefault()
{
return ref numbers.Length > 0 ? ref numbers[numbers.Length - 1] : ref DefaultInt;
}
public static void DoubleNumber(ref int num)
{
Console.WriteLine("old: " + num);
num *= 2;
Console.WriteLine("new: " + num);
}
public static ref string GetOrSetString(int index)
{
if (index < 0 || index >= strings.Length)
return ref NullString;
return ref strings[index];
}
public static void Main(string[] args)
{
DoubleNumber(ref FindNumber(32));
Console.WriteLine(string.Join(", ", numbers));
DoubleNumber(ref LastNumber());
Console.WriteLine(string.Join(", ", numbers));
Console.WriteLine(GetOrSetString(0));
GetOrSetString(0) = "Goodbye";
Console.WriteLine(string.Join(" ", strings));
GetOrSetString(5) = "Here I mutated the null value!?";
Console.WriteLine(GetOrSetString(-5));
Console.WriteLine(Invoker(x => ref numbers[x], 0));
Console.WriteLine(LastOrDefault());
LastOrDefault() = 10000;
Console.WriteLine(ElementAtOrDefault(-5));
}
}
}

16
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1359,12 +1359,22 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1359,12 +1359,22 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitCall(Call inst, TranslationContext context)
{
return new CallBuilder(this, typeSystem, settings).Build(inst);
return WrapInRef(new CallBuilder(this, typeSystem, settings).Build(inst), inst.Method.ReturnType);
}
protected internal override TranslatedExpression VisitCallVirt(CallVirt inst, TranslationContext context)
{
return new CallBuilder(this, typeSystem, settings).Build(inst);
return WrapInRef(new CallBuilder(this, typeSystem, settings).Build(inst), inst.Method.ReturnType);
}
TranslatedExpression WrapInRef(TranslatedExpression expr, IType type)
{
if (type.Kind == TypeKind.ByReference) {
return new DirectionExpression(FieldDirection.Ref, expr.Expression)
.WithoutILInstruction()
.WithRR(new ByReferenceResolveResult(expr.ResolveResult, isOut: false));
}
return expr;
}
internal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function)

2
ICSharpCode.Decompiler/Semantics/MemberResolveResult.cs

@ -76,6 +76,8 @@ namespace ICSharpCode.Decompiler.Semantics @@ -76,6 +76,8 @@ namespace ICSharpCode.Decompiler.Semantics
return new PointerType(member.ReturnType);
break;
}
if (member.ReturnType.Kind == TypeKind.ByReference)
return ((ByReferenceType)member.ReturnType).ElementType;
return member.ReturnType;
}

Loading…
Cancel
Save