.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

585 lines
8.2 KiB

using System;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public abstract class ReduceNesting
{
public abstract bool B(int i);
public abstract int I(int i);
public void IfIf()
{
if (B(0))
{
Console.WriteLine(0);
return;
}
if (B(1))
{
Console.WriteLine(1);
}
Console.WriteLine("end");
}
public void IfSwitch()
{
if (B(0))
{
Console.WriteLine(0);
return;
}
Console.WriteLine("switch");
switch (I(0))
{
case 0:
Console.WriteLine("case 0");
break;
case 1:
Console.WriteLine("case 1");
break;
default:
Console.WriteLine("end");
break;
}
}
public void IfSwitchSwitch()
{
if (B(0))
{
Console.WriteLine(0);
return;
}
Console.WriteLine("switch 0");
switch (I(1))
{
case 0:
Console.WriteLine("case 0");
return;
case 1:
Console.WriteLine("case 1");
return;
}
Console.WriteLine("switch 1");
switch (I(1))
{
case 0:
Console.WriteLine("case 0");
break;
case 1:
Console.WriteLine("case 1");
break;
default:
Console.WriteLine("end");
break;
}
}
public void IfLoop()
{
if (B(0))
{
Console.WriteLine(0);
return;
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
Console.WriteLine("end");
}
public void LoopContinue()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
if (B(0))
{
Console.WriteLine(0);
continue;
}
if (B(1))
{
Console.WriteLine(1);
}
Console.WriteLine("loop-tail");
}
}
public void LoopBreak()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
if (B(0))
{
Console.WriteLine(0);
continue;
}
if (B(1))
{
Console.WriteLine(1);
break;
}
if (B(2))
{
Console.WriteLine(2);
}
Console.WriteLine("break");
break;
}
Console.WriteLine("end");
}
public void LoopBreakElseIf()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
if (B(0))
{
Console.WriteLine(0);
continue;
}
if (B(1))
{
Console.WriteLine(1);
}
else if (B(2))
{
Console.WriteLine(2);
}
break;
}
Console.WriteLine("end");
}
public void SwitchIf()
{
switch (I(0))
{
case 0:
Console.WriteLine("case 0");
return;
case 1:
Console.WriteLine("case 1");
return;
}
if (B(0))
{
Console.WriteLine(0);
}
Console.WriteLine("end");
}
public void NestedSwitchIf()
{
if (B(0))
{
switch (I(0))
{
case 0:
Console.WriteLine("case 0");
return;
case 1:
Console.WriteLine("case 1");
return;
}
if (B(1))
{
Console.WriteLine(1);
}
}
else
{
Console.WriteLine("else");
}
}
// nesting should not be reduced as maximum nesting level is 1
public void EarlyExit1()
{
if (!B(0))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
Console.WriteLine("end");
}
}
// nesting should be reduced as maximum nesting level is 2
public void EarlyExit2()
{
if (B(0))
{
return;
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
if (i % 2 == 0)
{
Console.WriteLine("even");
}
}
Console.WriteLine("end");
}
// nesting should not be reduced as maximum nesting level is 1 and the else block has no more instructions than any other block
public void BalancedIf()
{
if (B(0))
{
Console.WriteLine("true");
if (B(1))
{
Console.WriteLine(1);
}
}
else
{
if (B(2))
{
Console.WriteLine(2);
}
Console.WriteLine("false");
}
}
public string ComplexCase1(string s)
{
if (B(0))
{
return s;
}
for (int i = 0; i < s.Length; i++)
{
if (B(1))
{
Console.WriteLine(1);
}
else if (B(2))
{
switch (i)
{
case 1:
if (B(3))
{
Console.WriteLine(3);
break;
}
Console.WriteLine("case1");
if (B(4))
{
Console.WriteLine(4);
}
break;
case 2:
case 3:
Console.WriteLine("case23");
break;
}
Console.WriteLine(2);
}
else if (B(5))
{
Console.WriteLine(5);
}
else
{
if (B(6))
{
Console.WriteLine(6);
}
Console.WriteLine("else");
}
}
return s;
}
public void EarlyExitBeforeTry()
{
if (B(0))
{
return;
}
try
{
if (B(1))
{
Console.WriteLine();
}
}
catch
{
}
}
public void EarlyExitInTry()
{
try
{
if (B(0))
{
return;
}
Console.WriteLine();
if (B(1))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
}
catch
{
}
}
public void ContinueLockInLoop()
{
while (B(0))
{
lock (Console.Out)
{
if (B(1))
{
continue;
}
Console.WriteLine();
if (B(2))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
}
}
}
public void BreakLockInLoop()
{
while (B(0))
{
lock (Console.Out)
{
// Before ReduceNestingTransform, the rest of the lock body is nested in if(!B(1)) with a continue;
// the B(1) case falls through to a break outside the lock
if (B(1))
{
break;
}
Console.WriteLine();
if (B(2))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
// the break gets duplicated into the lock (replacing the leave) making the lock 'endpoint unreachable' and the break outside the lock is removed
// After the condition is inverted, ReduceNestingTransform isn't smart enough to then move the continue out of the lock
// Thus the redundant continue;
continue;
}
}
Console.WriteLine();
}
public unsafe void BreakPinnedInLoop(int[] arr)
{
while (B(0))
{
fixed (int* ptr = arr)
{
if (B(1))
{
break;
}
Console.WriteLine();
if (B(2))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(ptr[i]);
}
}
// Same reason as BreakLockInLoop
continue;
}
}
Console.WriteLine();
}
public void CannotEarlyExitInTry()
{
try
{
if (B(0))
{
Console.WriteLine();
if (B(1))
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
}
}
catch
{
}
Console.WriteLine();
}
public void EndpointUnreachableDueToEarlyExit()
{
using (Console.Out)
{
if (B(0))
{
return;
}
do
{
if (B(1))
{
return;
}
} while (B(2));
throw new Exception();
}
}
public void SwitchInTry()
{
try
{
switch (I(0))
{
case 1:
Console.WriteLine(1);
return;
case 2:
Console.WriteLine(2);
return;
}
Console.WriteLine(3);
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
catch
{
throw;
}
}
public void SwitchInTryInLoopReturn()
{
for (int i = 0; i < 10; i++)
{
try
{
switch (I(0))
{
case 1:
Console.WriteLine(1);
return;
case 2:
Console.WriteLine(2);
return;
}
Console.WriteLine(3);
for (int j = 0; j < 10; j++)
{
Console.WriteLine(j);
}
}
catch
{
throw;
}
}
}
public void SwitchInTryInLoopContinue()
{
for (int i = 0; i < 10; i++)
{
try
{
switch (I(0))
{
case 1:
Console.WriteLine(1);
continue;
case 2:
Console.WriteLine(2);
continue;
}
Console.WriteLine(3);
for (int j = 0; j < 10; j++)
{
Console.WriteLine(j);
}
}
catch
{
throw;
}
}
}
private static string ShouldNotDuplicateReturnStatementIntoTry(IDictionary<int, string> dict)
{
string value;
lock (dict)
{
if (!dict.TryGetValue(1, out value))
{
value = "test";
dict.Add(1, value);
}
}
return value;
}
}
}