Browse Source

Add FlattenSwitchBlocks transform + update test cases.

pull/887/head
Siegfried Pammer 8 years ago
parent
commit
7ae44fcdc6
  1. 512
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 6
      ICSharpCode.Decompiler/CSharp/Transforms/FlattenSwitchBlocks.cs
  4. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

512
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs

@ -43,154 +43,117 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("SparseIntegerSwitch: " + i); Console.WriteLine("SparseIntegerSwitch: " + i);
switch (i) { switch (i) {
case -10000000: { case -10000000:
return "-10 mln"; return "-10 mln";
} case -100:
case -100: { return "-hundred";
return "-hundred"; case -1:
} return "-1";
case -1: { case 0:
return "-1"; return "0";
} case 1:
case 0: { return "1";
return "0"; case 2:
} return "2";
case 1: { case 4:
return "1"; return "4";
} case 100:
case 2: { return "hundred";
return "2"; case 10000:
} return "ten thousand";
case 4: { case 10001:
return "4"; return "ten thousand and one";
} case 2147483647:
case 100: { return "int.MaxValue";
return "hundred"; default:
} return "something else";
case 10000: {
return "ten thousand";
}
case 10001: {
return "ten thousand and one";
}
case 2147483647: {
return "int.MaxValue";
}
default: {
return "something else";
}
} }
} }
public static string SwitchOverNullableInt(int? i) public static string SwitchOverNullableInt(int? i)
{ {
switch (i) { switch (i) {
case null: { case null:
return "null"; return "null";
} case 0:
case 0: { return "zero";
return "zero"; case 5:
} return "five";
case 5: { case 10:
return "five"; return "ten";
} default:
case 10: { return "large";
return "ten";
}
default: {
return "large";
}
} }
} }
public static string SwitchOverNullableIntShifted(int? i) public static string SwitchOverNullableIntShifted(int? i)
{ {
switch (i + 5) { switch (i + 5) {
case null: { case null:
return "null"; return "null";
} case 0:
case 0: { return "zero";
return "zero"; case 5:
} return "five";
case 5: { case 10:
return "five"; return "ten";
} default:
case 10: { return "large";
return "ten";
}
default: {
return "large";
}
} }
} }
public static string SwitchOverNullableIntNoNullCase(int? i) public static string SwitchOverNullableIntNoNullCase(int? i)
{ {
switch (i) { switch (i) {
case 0: { case 0:
return "zero"; return "zero";
} case 5:
case 5: { return "five";
return "five"; case 10:
} return "ten";
case 10: { default:
return "ten"; return "other";
}
default: {
return "other";
}
} }
} }
public static string SwitchOverNullableIntNoNullCaseShifted(int? i) public static string SwitchOverNullableIntNoNullCaseShifted(int? i)
{ {
switch (i + 5) { switch (i + 5) {
case 0: { case 0:
return "zero"; return "zero";
} case 5:
case 5: { return "five";
return "five"; case 10:
} return "ten";
case 10: { default:
return "ten"; return "other";
}
default: {
return "other";
}
} }
} }
public static void SwitchOverInt(int i) public static void SwitchOverInt(int i)
{ {
switch (i) { switch (i) {
case 0: { case 0:
Console.WriteLine("zero"); Console.WriteLine("zero");
break; break;
} case 5:
case 5: { Console.WriteLine("five");
Console.WriteLine("five"); break;
break; case 10:
} Console.WriteLine("ten");
case 10: { break;
Console.WriteLine("ten"); case 15:
break; Console.WriteLine("fifteen");
} break;
case 15: { case 20:
Console.WriteLine("fifteen"); Console.WriteLine("twenty");
break; break;
} case 25:
case 20: { Console.WriteLine("twenty-five");
Console.WriteLine("twenty"); break;
break; case 30:
} Console.WriteLine("thirty");
case 25: { break;
Console.WriteLine("twenty-five");
break;
}
case 30: {
Console.WriteLine("thirty");
break;
}
} }
} }
@ -198,18 +161,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("ShortSwitchOverString: " + text); Console.WriteLine("ShortSwitchOverString: " + text);
switch (text) { switch (text) {
case "First case": { case "First case":
return "Text1"; return "Text1";
} case "Second case":
case "Second case": { return "Text2";
return "Text2"; case "Third case":
} return "Text3";
case "Third case": { default:
return "Text3"; return "Default";
}
default: {
return "Default";
}
} }
} }
@ -217,18 +176,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("ShortSwitchOverStringWithNullCase: " + text); Console.WriteLine("ShortSwitchOverStringWithNullCase: " + text);
switch (text) { switch (text) {
case "First case": { case "First case":
return "Text1"; return "Text1";
} case "Second case":
case "Second case": { return "Text2";
return "Text2"; case null:
} return "null";
case null: { default:
return "null"; return "Default";
}
default: {
return "Default";
}
} }
} }
@ -236,31 +191,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("SwitchOverString1: " + text); Console.WriteLine("SwitchOverString1: " + text);
switch (text) { switch (text) {
case "First case": { case "First case":
return "Text1"; return "Text1";
}
case "Second case": case "Second case":
case "2nd case": { case "2nd case":
return "Text2"; return "Text2";
} case "Third case":
case "Third case": { return "Text3";
return "Text3"; case "Fourth case":
} return "Text4";
case "Fourth case": { case "Fifth case":
return "Text4"; return "Text5";
} case "Sixth case":
case "Fifth case": { return "Text6";
return "Text5"; case null:
} return null;
case "Sixth case": { default:
return "Text6"; return "Default";
}
case null: {
return null;
}
default: {
return "Default";
}
} }
} }
@ -268,42 +215,30 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("SwitchOverString2:"); Console.WriteLine("SwitchOverString2:");
switch (Environment.UserName) { switch (Environment.UserName) {
case "First case": { case "First case":
return "Text1"; return "Text1";
} case "Second case":
case "Second case": { return "Text2";
return "Text2"; case "Third case":
} return "Text3";
case "Third case": { case "Fourth case":
return "Text3"; return "Text4";
} case "Fifth case":
case "Fourth case": { return "Text5";
return "Text4"; case "Sixth case":
} return "Text6";
case "Fifth case": { case "Seventh case":
return "Text5"; return "Text7";
} case "Eighth case":
case "Sixth case": { return "Text8";
return "Text6"; case "Ninth case":
} return "Text9";
case "Seventh case": { case "Tenth case":
return "Text7"; return "Text10";
} case "Eleventh case":
case "Eighth case": { return "Text11";
return "Text8"; default:
} return "Default";
case "Ninth case": {
return "Text9";
}
case "Tenth case": {
return "Text10";
}
case "Eleventh case": {
return "Text11";
}
default: {
return "Default";
}
} }
} }
@ -311,15 +246,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("SwitchOverBool: " + b.ToString()); Console.WriteLine("SwitchOverBool: " + b.ToString());
switch (b) { switch (b) {
case true: { case true:
return bool.TrueString; return bool.TrueString;
} case false:
case false: { return bool.FalseString;
return bool.FalseString; default:
} return null;
default: {
return null;
}
} }
} }
@ -328,27 +260,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine("SwitchInLoop: " + i); Console.WriteLine("SwitchInLoop: " + i);
while (true) { while (true) {
switch (i) { switch (i) {
case 1: { case 1:
Console.WriteLine("one"); Console.WriteLine("one");
break; break;
} case 2:
case 2: { Console.WriteLine("two");
Console.WriteLine("two"); break;
break; //case 3:
}
//case 3: {
// Console.WriteLine("three"); // Console.WriteLine("three");
// continue; // continue;
// } case 4:
case 4: { Console.WriteLine("four");
Console.WriteLine("four"); return;
return; default:
} Console.WriteLine("default");
default: { Console.WriteLine("more code");
Console.WriteLine("default"); return;
Console.WriteLine("more code");
return;
}
} }
i++; i++;
} }
@ -358,26 +285,21 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Console.WriteLine("SwitchWithGoto: " + i); Console.WriteLine("SwitchWithGoto: " + i);
switch (i) { switch (i) {
case 1: { case 1:
Console.WriteLine("one"); Console.WriteLine("one");
goto default; goto default;
} case 2:
case 2: { Console.WriteLine("two");
Console.WriteLine("two"); goto case 3;
goto case 3; case 3:
} Console.WriteLine("three");
case 3: { break;
Console.WriteLine("three"); case 4:
break; Console.WriteLine("four");
} return;
case 4: { default:
Console.WriteLine("four"); Console.WriteLine("default");
return; break;
}
default: {
Console.WriteLine("default");
break;
}
} }
Console.WriteLine("End of method"); Console.WriteLine("End of method");
} }
@ -395,35 +317,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
for (int i = 0; i < properties.Length; i++) { for (int i = 0; i < properties.Length; i++) {
SetProperty setProperty = properties[i]; SetProperty setProperty = properties[i];
switch (setProperty.Property.Name) { switch (setProperty.Property.Name) {
case "Name1": { case "Name1":
setProperty.Set = 1; setProperty.Set = 1;
list.Add(setProperty); list.Add(setProperty);
break; break;
} case "Name2":
case "Name2": { setProperty.Set = 2;
setProperty.Set = 2; list.Add(setProperty);
list.Add(setProperty); break;
break; case "Name3":
} setProperty.Set = 3;
case "Name3": { list.Add(setProperty);
setProperty.Set = 3; break;
list.Add(setProperty); case "Name4":
break; setProperty.Set = 4;
} list.Add(setProperty);
case "Name4": { break;
setProperty.Set = 4;
list.Add(setProperty);
break;
}
case "Name5": case "Name5":
case "Name6": { case "Name6":
list.Add(setProperty); list.Add(setProperty);
break; break;
} default:
default: { list2.Add(setProperty);
list2.Add(setProperty); break;
break;
}
} }
} }
} }
@ -431,22 +347,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public static void SwitchWithComplexCondition(string[] args) public static void SwitchWithComplexCondition(string[] args)
{ {
switch ((args.Length == 0) ? "dummy" : args[0]) { switch ((args.Length == 0) ? "dummy" : args[0]) {
case "a": { case "a":
Console.WriteLine("a"); Console.WriteLine("a");
break; break;
} case "b":
case "b": { Console.WriteLine("b");
Console.WriteLine("b"); break;
break; case "c":
} Console.WriteLine("c");
case "c": { break;
Console.WriteLine("c"); case "d":
break; Console.WriteLine("d");
} break;
case "d": {
Console.WriteLine("d");
break;
}
} }
Console.WriteLine("end"); Console.WriteLine("end");
} }
@ -454,22 +366,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public static void SwitchWithArray(string[] args) public static void SwitchWithArray(string[] args)
{ {
switch (args[0]) { switch (args[0]) {
case "a": { case "a":
Console.WriteLine("a"); Console.WriteLine("a");
break; break;
} case "b":
case "b": {
Console.WriteLine("b"); Console.WriteLine("b");
break; break;
} case "c":
case "c": {
Console.WriteLine("c"); Console.WriteLine("c");
break; break;
} case "d":
case "d": {
Console.WriteLine("d"); Console.WriteLine("d");
break; break;
}
} }
Console.WriteLine("end"); Console.WriteLine("end");
} }

2
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -144,7 +144,7 @@ namespace ICSharpCode.Decompiler.CSharp
new IntroduceExtensionMethods(), // must run after IntroduceUsingDeclarations new IntroduceExtensionMethods(), // must run after IntroduceUsingDeclarations
new IntroduceQueryExpressions(), // must run after IntroduceExtensionMethods new IntroduceQueryExpressions(), // must run after IntroduceExtensionMethods
new CombineQueryExpressions(), new CombineQueryExpressions(),
//new FlattenSwitchBlocks(), new FlattenSwitchBlocks(),
new FixNameCollisions(), new FixNameCollisions(),
new AddXmlDocumentationTransform(), new AddXmlDocumentationTransform(),
}; };

6
ICSharpCode.Decompiler/CSharp/Transforms/FlattenSwitchBlocks.cs

@ -2,15 +2,15 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.Decompiler.CSharp.Syntax;
namespace ICSharpCode.Decompiler.CSharp.Transforms namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
class FlattenSwitchBlocks : IAstTransform class FlattenSwitchBlocks : IAstTransform
{ {
public void Run(AstNode compilationUnit) public void Run(AstNode rootNode, TransformContext context)
{ {
foreach (var switchSection in compilationUnit.Descendants.OfType<SwitchSection>()) foreach (var switchSection in rootNode.Descendants.OfType<SwitchSection>())
{ {
if (switchSection.Statements.Count != 1) if (switchSection.Statements.Count != 1)
continue; continue;

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -224,6 +224,7 @@
<Compile Include="CSharp\Resolver\RenameCallbackArguments.cs" /> <Compile Include="CSharp\Resolver\RenameCallbackArguments.cs" />
<Compile Include="CSharp\Resolver\TypeInference.cs" /> <Compile Include="CSharp\Resolver\TypeInference.cs" />
<Compile Include="CSharp\Transforms\CombineQueryExpressions.cs" /> <Compile Include="CSharp\Transforms\CombineQueryExpressions.cs" />
<Compile Include="CSharp\Transforms\FlattenSwitchBlocks.cs" />
<Compile Include="CSharp\Transforms\IntroduceExtensionMethods.cs" /> <Compile Include="CSharp\Transforms\IntroduceExtensionMethods.cs" />
<Compile Include="CSharp\Transforms\IntroduceQueryExpressions.cs" /> <Compile Include="CSharp\Transforms\IntroduceQueryExpressions.cs" />
<Compile Include="CSharp\Transforms\PrettifyAssignments.cs" /> <Compile Include="CSharp\Transforms\PrettifyAssignments.cs" />

Loading…
Cancel
Save