Browse Source

Add transform for Roslyn Switch-On-Nullable

pull/887/head
Siegfried Pammer 8 years ago
parent
commit
51d13bfefe
  1. 200
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  2. 360
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il
  3. 288
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il
  4. 255
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il
  5. 358
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il
  6. 60
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs

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

@ -82,83 +82,83 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
//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: { case 5: {
// return "five"; return "five";
// } }
// case 10: { case 10: {
// return "ten"; return "ten";
// } }
// default: { default: {
// return "large"; 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: { case 5: {
// return "five"; return "five";
// } }
// case 10: { case 10: {
// return "ten"; return "ten";
// } }
// default: { default: {
// return "large"; 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: { case 10: {
// return "ten"; return "ten";
// } }
// default: { default: {
// return "other"; 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: { case 10: {
// return "ten"; return "ten";
// } }
// default: { default: {
// return "other"; return "other";
// } }
// } }
//} }
public static string ShortSwitchOverString(string text) public static string ShortSwitchOverString(string text)
{ {
@ -302,32 +302,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
//public static void SwitchWithGoto(int i) public static void SwitchWithGoto(int i)
//{ {
// 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: { case 3: {
// Console.WriteLine("three"); Console.WriteLine("three");
// break; break;
// } }
// case 4: { case 4: {
// Console.WriteLine("four"); Console.WriteLine("four");
// return; return;
// } }
// default: { default: {
// Console.WriteLine("default"); Console.WriteLine("default");
// break; break;
// } }
// } }
//} }
private static SetProperty[] GetProperties() private static SetProperty[] GetProperties()
{ {

360
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il

@ -1,6 +1,6 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten.
@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0 .ver 4:0:0:0
} }
.assembly gn0oqkcb .assembly nyniamwr
{ {
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
@ -20,15 +20,15 @@
.hash algorithm 0x00008004 .hash algorithm 0x00008004
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module gn0oqkcb.dll .module nyniamwr.dll
// MVID: {D3E1C722-15E3-49C8-B86B-96413DA7BEEE} // MVID: {95C99B41-CBA3-42E4-A4DE-27E535671AB2}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000 .imagebase 0x10000000
.file alignment 0x00000200 .file alignment 0x00000200
.stackreserve 0x00100000 .stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI .subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY .corflags 0x00000001 // ILONLY
// Image base: 0x00C80000 // Image base: 0x03080000
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
@ -214,6 +214,268 @@
IL_00df: ret IL_00df: ret
} // end of method Switch::SparseIntegerSwitch } // end of method Switch::SparseIntegerSwitch
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 79 (0x4f)
.maxstack 2
.locals init (string V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarga.s i
IL_0003: dup
IL_0004: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0009: stloc.1
IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000f: brfalse.s IL_0020
IL_0011: ldloc.1
IL_0012: ldc.i4.0
IL_0013: beq.s IL_0029
IL_0015: ldloc.1
IL_0016: ldc.i4.5
IL_0017: beq.s IL_0032
IL_0019: ldloc.1
IL_001a: ldc.i4.s 10
IL_001c: beq.s IL_003b
IL_001e: br.s IL_0044
IL_0020: nop
IL_0021: ldstr "null"
IL_0026: stloc.0
IL_0027: br.s IL_004d
IL_0029: nop
IL_002a: ldstr "zero"
IL_002f: stloc.0
IL_0030: br.s IL_004d
IL_0032: nop
IL_0033: ldstr "five"
IL_0038: stloc.0
IL_0039: br.s IL_004d
IL_003b: nop
IL_003c: ldstr "ten"
IL_0041: stloc.0
IL_0042: br.s IL_004d
IL_0044: nop
IL_0045: ldstr "large"
IL_004a: stloc.0
IL_004b: br.s IL_004d
IL_004d: ldloc.0
IL_004e: ret
} // end of method Switch::SwitchOverNullableInt
.method public hidebysig static string
SwitchOverNullableIntShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 117 (0x75)
.maxstack 2
.locals init (string V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloca.s V_1
IL_0005: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000a: brtrue.s IL_0017
IL_000c: ldloca.s V_2
IL_000e: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0014: ldloc.2
IL_0015: br.s IL_0025
IL_0017: ldloca.s V_1
IL_0019: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001e: ldc.i4.5
IL_001f: add
IL_0020: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0025: nop
IL_0026: stloc.2
IL_0027: ldloca.s V_2
IL_0029: dup
IL_002a: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_002f: stloc.3
IL_0030: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0035: brfalse.s IL_0046
IL_0037: ldloc.3
IL_0038: ldc.i4.0
IL_0039: beq.s IL_004f
IL_003b: ldloc.3
IL_003c: ldc.i4.5
IL_003d: beq.s IL_0058
IL_003f: ldloc.3
IL_0040: ldc.i4.s 10
IL_0042: beq.s IL_0061
IL_0044: br.s IL_006a
IL_0046: nop
IL_0047: ldstr "null"
IL_004c: stloc.0
IL_004d: br.s IL_0073
IL_004f: nop
IL_0050: ldstr "zero"
IL_0055: stloc.0
IL_0056: br.s IL_0073
IL_0058: nop
IL_0059: ldstr "five"
IL_005e: stloc.0
IL_005f: br.s IL_0073
IL_0061: nop
IL_0062: ldstr "ten"
IL_0067: stloc.0
IL_0068: br.s IL_0073
IL_006a: nop
IL_006b: ldstr "large"
IL_0070: stloc.0
IL_0071: br.s IL_0073
IL_0073: ldloc.0
IL_0074: ret
} // end of method Switch::SwitchOverNullableIntShifted
.method public hidebysig static string
SwitchOverNullableIntNoNullCase(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 70 (0x46)
.maxstack 2
.locals init (string V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarga.s i
IL_0003: dup
IL_0004: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0009: stloc.1
IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000f: brfalse.s IL_003b
IL_0011: ldloc.1
IL_0012: ldc.i4.0
IL_0013: beq.s IL_0020
IL_0015: ldloc.1
IL_0016: ldc.i4.5
IL_0017: beq.s IL_0029
IL_0019: ldloc.1
IL_001a: ldc.i4.s 10
IL_001c: beq.s IL_0032
IL_001e: br.s IL_003b
IL_0020: nop
IL_0021: ldstr "zero"
IL_0026: stloc.0
IL_0027: br.s IL_0044
IL_0029: nop
IL_002a: ldstr "five"
IL_002f: stloc.0
IL_0030: br.s IL_0044
IL_0032: nop
IL_0033: ldstr "ten"
IL_0038: stloc.0
IL_0039: br.s IL_0044
IL_003b: nop
IL_003c: ldstr "other"
IL_0041: stloc.0
IL_0042: br.s IL_0044
IL_0044: ldloc.0
IL_0045: ret
} // end of method Switch::SwitchOverNullableIntNoNullCase
.method public hidebysig static string
SwitchOverNullableIntNoNullCaseShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 108 (0x6c)
.maxstack 2
.locals init (string V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloca.s V_1
IL_0005: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000a: brtrue.s IL_0017
IL_000c: ldloca.s V_2
IL_000e: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0014: ldloc.2
IL_0015: br.s IL_0025
IL_0017: ldloca.s V_1
IL_0019: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001e: ldc.i4.5
IL_001f: add
IL_0020: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0025: nop
IL_0026: stloc.2
IL_0027: ldloca.s V_2
IL_0029: dup
IL_002a: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_002f: stloc.3
IL_0030: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0035: brfalse.s IL_0061
IL_0037: ldloc.3
IL_0038: ldc.i4.0
IL_0039: beq.s IL_0046
IL_003b: ldloc.3
IL_003c: ldc.i4.5
IL_003d: beq.s IL_004f
IL_003f: ldloc.3
IL_0040: ldc.i4.s 10
IL_0042: beq.s IL_0058
IL_0044: br.s IL_0061
IL_0046: nop
IL_0047: ldstr "zero"
IL_004c: stloc.0
IL_004d: br.s IL_006a
IL_004f: nop
IL_0050: ldstr "five"
IL_0055: stloc.0
IL_0056: br.s IL_006a
IL_0058: nop
IL_0059: ldstr "ten"
IL_005e: stloc.0
IL_005f: br.s IL_006a
IL_0061: nop
IL_0062: ldstr "other"
IL_0067: stloc.0
IL_0068: br.s IL_006a
IL_006a: ldloc.0
IL_006b: ret
} // end of method Switch::SwitchOverNullableIntNoNullCaseShifted
.method public hidebysig static string .method public hidebysig static string
ShortSwitchOverString(string text) cil managed ShortSwitchOverString(string text) cil managed
{ {
@ -298,7 +560,7 @@
IL_0015: brfalse IL_00ef IL_0015: brfalse IL_00ef
IL_001a: volatile. IL_001a: volatile.
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000003-1' IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000007-1'
IL_0021: brtrue.s IL_0084 IL_0021: brtrue.s IL_0084
IL_0023: ldc.i4.7 IL_0023: ldc.i4.7
@ -339,9 +601,9 @@
IL_0078: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_0078: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_007d: volatile. IL_007d: volatile.
IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000003-1' IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000007-1'
IL_0084: volatile. IL_0084: volatile.
IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000003-1' IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000007-1'
IL_008b: ldloc.1 IL_008b: ldloc.1
IL_008c: ldloca.s V_2 IL_008c: ldloca.s V_2
IL_008e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_008e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -424,7 +686,7 @@
IL_0015: brfalse IL_0165 IL_0015: brfalse IL_0165
IL_001a: volatile. IL_001a: volatile.
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000004-1' IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000008-1'
IL_0021: brtrue IL_00ba IL_0021: brtrue IL_00ba
IL_0026: ldc.i4.s 11 IL_0026: ldc.i4.s 11
@ -485,9 +747,9 @@
IL_00ae: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_00ae: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_00b3: volatile. IL_00b3: volatile.
IL_00b5: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000004-1' IL_00b5: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000008-1'
IL_00ba: volatile. IL_00ba: volatile.
IL_00bc: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000004-1' IL_00bc: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x6000008-1'
IL_00c1: ldloc.2 IL_00c1: ldloc.2
IL_00c2: ldloca.s V_3 IL_00c2: ldloca.s V_3
IL_00c4: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_00c4: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -689,6 +951,64 @@
IL_0091: ret IL_0091: ret
} // end of method Switch::SwitchInLoop } // end of method Switch::SwitchInLoop
.method public hidebysig static void SwitchWithGoto(int32 i) cil managed
{
// Code size 122 (0x7a)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldstr "SwitchWithGoto: "
IL_0006: ldarg.0
IL_0007: box [mscorlib]System.Int32
IL_000c: call string [mscorlib]System.String::Concat(object,
object)
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: nop
IL_0017: ldarg.0
IL_0018: stloc.0
IL_0019: ldloc.0
IL_001a: ldc.i4.1
IL_001b: sub
IL_001c: switch (
IL_0033,
IL_0041,
IL_004f,
IL_005d)
IL_0031: br.s IL_006b
IL_0033: nop
IL_0034: ldstr "one"
IL_0039: call void [mscorlib]System.Console::WriteLine(string)
IL_003e: nop
IL_003f: br.s IL_006b
IL_0041: nop
IL_0042: ldstr "two"
IL_0047: call void [mscorlib]System.Console::WriteLine(string)
IL_004c: nop
IL_004d: br.s IL_004f
IL_004f: nop
IL_0050: ldstr "three"
IL_0055: call void [mscorlib]System.Console::WriteLine(string)
IL_005a: nop
IL_005b: br.s IL_0079
IL_005d: nop
IL_005e: ldstr "four"
IL_0063: call void [mscorlib]System.Console::WriteLine(string)
IL_0068: nop
IL_0069: br.s IL_0079
IL_006b: nop
IL_006c: ldstr "default"
IL_0071: call void [mscorlib]System.Console::WriteLine(string)
IL_0076: nop
IL_0077: br.s IL_0079
IL_0079: ret
} // end of method Switch::SwitchWithGoto
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[]
GetProperties() cil managed GetProperties() cil managed
{ {
@ -744,7 +1064,7 @@
IL_0034: brfalse IL_012d IL_0034: brfalse IL_012d
IL_0039: volatile. IL_0039: volatile.
IL_003b: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000008-1' IL_003b: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x600000d-1'
IL_0040: brtrue.s IL_0097 IL_0040: brtrue.s IL_0097
IL_0042: ldc.i4.6 IL_0042: ldc.i4.6
@ -780,9 +1100,9 @@
IL_008b: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_008b: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_0090: volatile. IL_0090: volatile.
IL_0092: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000008-1' IL_0092: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x600000d-1'
IL_0097: volatile. IL_0097: volatile.
IL_0099: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}'::'$$method0x6000008-1' IL_0099: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'::'$$method0x600000d-1'
IL_009e: ldloc.s V_6 IL_009e: ldloc.s V_6
IL_00a0: ldloca.s V_7 IL_00a0: ldloca.s V_7
IL_00a2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_00a2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -876,17 +1196,17 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch
.class private auto ansi '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}' .class private auto ansi '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'
extends [mscorlib]System.Object extends [mscorlib]System.Object
{ {
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000003-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000007-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000004-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000008-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000008-1'
} // end of class '<PrivateImplementationDetails>{D3E1C722-15E3-49C8-B86B-96413DA7BEEE}' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000d-1'
} // end of class '<PrivateImplementationDetails>{95C99B41-CBA3-42E4-A4DE-27E535671AB2}'
// ============================================================= // =============================================================
// *********** DISASSEMBLY COMPLETE *********************** // *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\Switch.res // Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\Switch.res" wurde erstellt.

288
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il

@ -1,6 +1,6 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten.
@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0 .ver 4:0:0:0
} }
.assembly zlaei1fn .assembly f3gworj3
{ {
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
@ -20,15 +20,15 @@
.hash algorithm 0x00008004 .hash algorithm 0x00008004
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module zlaei1fn.dll .module f3gworj3.dll
// MVID: {64CCBA80-944A-4F77-9230-24B174DEE22A} // MVID: {6837A40E-7A00-4F01-B2D7-DE0001F70EDF}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000 .imagebase 0x10000000
.file alignment 0x00000200 .file alignment 0x00000200
.stackreserve 0x00100000 .stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI .subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY .corflags 0x00000001 // ILONLY
// Image base: 0x00680000 // Image base: 0x00780000
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
@ -176,6 +176,212 @@
IL_00b4: ret IL_00b4: ret
} // end of method Switch::SparseIntegerSwitch } // end of method Switch::SparseIntegerSwitch
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 61 (0x3d)
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldarga.s i
IL_0002: dup
IL_0003: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0008: stloc.0
IL_0009: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000e: brfalse.s IL_001f
IL_0010: ldloc.0
IL_0011: ldc.i4.0
IL_0012: beq.s IL_0025
IL_0014: ldloc.0
IL_0015: ldc.i4.5
IL_0016: beq.s IL_002b
IL_0018: ldloc.0
IL_0019: ldc.i4.s 10
IL_001b: beq.s IL_0031
IL_001d: br.s IL_0037
IL_001f: ldstr "null"
IL_0024: ret
IL_0025: ldstr "zero"
IL_002a: ret
IL_002b: ldstr "five"
IL_0030: ret
IL_0031: ldstr "ten"
IL_0036: ret
IL_0037: ldstr "large"
IL_003c: ret
} // end of method Switch::SwitchOverNullableInt
.method public hidebysig static string
SwitchOverNullableIntShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 98 (0x62)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloca.s V_0
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brtrue.s IL_0016
IL_000b: ldloca.s V_1
IL_000d: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0013: ldloc.1
IL_0014: br.s IL_0024
IL_0016: ldloca.s V_0
IL_0018: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001d: ldc.i4.5
IL_001e: add
IL_001f: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0024: stloc.2
IL_0025: ldloca.s V_2
IL_0027: dup
IL_0028: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_002d: stloc.3
IL_002e: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0033: brfalse.s IL_0044
IL_0035: ldloc.3
IL_0036: ldc.i4.0
IL_0037: beq.s IL_004a
IL_0039: ldloc.3
IL_003a: ldc.i4.5
IL_003b: beq.s IL_0050
IL_003d: ldloc.3
IL_003e: ldc.i4.s 10
IL_0040: beq.s IL_0056
IL_0042: br.s IL_005c
IL_0044: ldstr "null"
IL_0049: ret
IL_004a: ldstr "zero"
IL_004f: ret
IL_0050: ldstr "five"
IL_0055: ret
IL_0056: ldstr "ten"
IL_005b: ret
IL_005c: ldstr "large"
IL_0061: ret
} // end of method Switch::SwitchOverNullableIntShifted
.method public hidebysig static string
SwitchOverNullableIntNoNullCase(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 55 (0x37)
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldarga.s i
IL_0002: dup
IL_0003: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0008: stloc.0
IL_0009: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000e: brfalse.s IL_0031
IL_0010: ldloc.0
IL_0011: ldc.i4.0
IL_0012: beq.s IL_001f
IL_0014: ldloc.0
IL_0015: ldc.i4.5
IL_0016: beq.s IL_0025
IL_0018: ldloc.0
IL_0019: ldc.i4.s 10
IL_001b: beq.s IL_002b
IL_001d: br.s IL_0031
IL_001f: ldstr "zero"
IL_0024: ret
IL_0025: ldstr "five"
IL_002a: ret
IL_002b: ldstr "ten"
IL_0030: ret
IL_0031: ldstr "other"
IL_0036: ret
} // end of method Switch::SwitchOverNullableIntNoNullCase
.method public hidebysig static string
SwitchOverNullableIntNoNullCaseShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 92 (0x5c)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloca.s V_0
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brtrue.s IL_0016
IL_000b: ldloca.s V_1
IL_000d: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0013: ldloc.1
IL_0014: br.s IL_0024
IL_0016: ldloca.s V_0
IL_0018: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001d: ldc.i4.5
IL_001e: add
IL_001f: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0024: stloc.2
IL_0025: ldloca.s V_2
IL_0027: dup
IL_0028: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_002d: stloc.3
IL_002e: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0033: brfalse.s IL_0056
IL_0035: ldloc.3
IL_0036: ldc.i4.0
IL_0037: beq.s IL_0044
IL_0039: ldloc.3
IL_003a: ldc.i4.5
IL_003b: beq.s IL_004a
IL_003d: ldloc.3
IL_003e: ldc.i4.s 10
IL_0040: beq.s IL_0050
IL_0042: br.s IL_0056
IL_0044: ldstr "zero"
IL_0049: ret
IL_004a: ldstr "five"
IL_004f: ret
IL_0050: ldstr "ten"
IL_0055: ret
IL_0056: ldstr "other"
IL_005b: ret
} // end of method Switch::SwitchOverNullableIntNoNullCaseShifted
.method public hidebysig static string .method public hidebysig static string
ShortSwitchOverString(string text) cil managed ShortSwitchOverString(string text) cil managed
{ {
@ -243,7 +449,7 @@
IL_0013: brfalse IL_00db IL_0013: brfalse IL_00db
IL_0018: volatile. IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000003-1' IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000007-1'
IL_001f: brtrue.s IL_0082 IL_001f: brtrue.s IL_0082
IL_0021: ldc.i4.7 IL_0021: ldc.i4.7
@ -284,9 +490,9 @@
IL_0076: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_0076: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_007b: volatile. IL_007b: volatile.
IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000003-1' IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000007-1'
IL_0082: volatile. IL_0082: volatile.
IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000003-1' IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000007-1'
IL_0089: ldloc.0 IL_0089: ldloc.0
IL_008a: ldloca.s V_1 IL_008a: ldloca.s V_1
IL_008c: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_008c: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -347,7 +553,7 @@
IL_0013: brfalse IL_013f IL_0013: brfalse IL_013f
IL_0018: volatile. IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000004-1' IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000008-1'
IL_001f: brtrue IL_00b8 IL_001f: brtrue IL_00b8
IL_0024: ldc.i4.s 11 IL_0024: ldc.i4.s 11
@ -408,9 +614,9 @@
IL_00ac: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_00ac: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_00b1: volatile. IL_00b1: volatile.
IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000004-1' IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000008-1'
IL_00b8: volatile. IL_00b8: volatile.
IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000004-1' IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x6000008-1'
IL_00bf: ldloc.1 IL_00bf: ldloc.1
IL_00c0: ldloca.s V_2 IL_00c0: ldloca.s V_2
IL_00c2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_00c2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -551,6 +757,48 @@
IL_007a: br.s IL_0015 IL_007a: br.s IL_0015
} // end of method Switch::SwitchInLoop } // end of method Switch::SwitchInLoop
.method public hidebysig static void SwitchWithGoto(int32 i) cil managed
{
// Code size 104 (0x68)
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldstr "SwitchWithGoto: "
IL_0005: ldarg.0
IL_0006: box [mscorlib]System.Int32
IL_000b: call string [mscorlib]System.String::Concat(object,
object)
IL_0010: call void [mscorlib]System.Console::WriteLine(string)
IL_0015: ldarg.0
IL_0016: stloc.0
IL_0017: ldloc.0
IL_0018: ldc.i4.1
IL_0019: sub
IL_001a: switch (
IL_0031,
IL_003d,
IL_0047,
IL_0052)
IL_002f: br.s IL_005d
IL_0031: ldstr "one"
IL_0036: call void [mscorlib]System.Console::WriteLine(string)
IL_003b: br.s IL_005d
IL_003d: ldstr "two"
IL_0042: call void [mscorlib]System.Console::WriteLine(string)
IL_0047: ldstr "three"
IL_004c: call void [mscorlib]System.Console::WriteLine(string)
IL_0051: ret
IL_0052: ldstr "four"
IL_0057: call void [mscorlib]System.Console::WriteLine(string)
IL_005c: ret
IL_005d: ldstr "default"
IL_0062: call void [mscorlib]System.Console::WriteLine(string)
IL_0067: ret
} // end of method Switch::SwitchWithGoto
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[]
GetProperties() cil managed GetProperties() cil managed
{ {
@ -597,7 +845,7 @@
IL_0031: brfalse IL_0119 IL_0031: brfalse IL_0119
IL_0036: volatile. IL_0036: volatile.
IL_0038: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000008-1' IL_0038: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x600000d-1'
IL_003d: brtrue.s IL_0094 IL_003d: brtrue.s IL_0094
IL_003f: ldc.i4.6 IL_003f: ldc.i4.6
@ -633,9 +881,9 @@
IL_0088: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, IL_0088: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1) !1)
IL_008d: volatile. IL_008d: volatile.
IL_008f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000008-1' IL_008f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x600000d-1'
IL_0094: volatile. IL_0094: volatile.
IL_0096: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}'::'$$method0x6000008-1' IL_0096: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'::'$$method0x600000d-1'
IL_009b: ldloc.s V_6 IL_009b: ldloc.s V_6
IL_009d: ldloca.s V_7 IL_009d: ldloca.s V_7
IL_009f: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0, IL_009f: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -707,17 +955,17 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch
.class private auto ansi '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}' .class private auto ansi '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'
extends [mscorlib]System.Object extends [mscorlib]System.Object
{ {
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000003-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000007-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000004-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000008-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000008-1'
} // end of class '<PrivateImplementationDetails>{64CCBA80-944A-4F77-9230-24B174DEE22A}' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000d-1'
} // end of class '<PrivateImplementationDetails>{6837A40E-7A00-4F01-B2D7-DE0001F70EDF}'
// ============================================================= // =============================================================
// *********** DISASSEMBLY COMPLETE *********************** // *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\Switch.opt.res // Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\Switch.opt.res" wurde erstellt.

255
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il

@ -1,6 +1,6 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten.
@ -25,14 +25,14 @@
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module Switch.dll .module Switch.dll
// MVID: {25FC064E-F764-4556-A3C7-F6570E457CDD} // MVID: {04DBCBA6-8175-41CD-8917-9428C9765986}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000 .imagebase 0x10000000
.file alignment 0x00000200 .file alignment 0x00000200
.stackreserve 0x00100000 .stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI .subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY .corflags 0x00000001 // ILONLY
// Image base: 0x00B30000 // Image base: 0x00830000
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
@ -185,6 +185,214 @@
IL_00b8: ret IL_00b8: ret
} // end of method Switch::SparseIntegerSwitch } // end of method Switch::SparseIntegerSwitch
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 63 (0x3f)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
int32 V_1)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloca.s V_0
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brfalse.s IL_0021
IL_000b: ldloca.s V_0
IL_000d: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: brfalse.s IL_0027
IL_0016: ldloc.1
IL_0017: ldc.i4.5
IL_0018: beq.s IL_002d
IL_001a: ldloc.1
IL_001b: ldc.i4.s 10
IL_001d: beq.s IL_0033
IL_001f: br.s IL_0039
IL_0021: ldstr "null"
IL_0026: ret
IL_0027: ldstr "zero"
IL_002c: ret
IL_002d: ldstr "five"
IL_0032: ret
IL_0033: ldstr "ten"
IL_0038: ret
IL_0039: ldstr "large"
IL_003e: ret
} // end of method Switch::SwitchOverNullableInt
.method public hidebysig static string
SwitchOverNullableIntShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 98 (0x62)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: ldarg.0
IL_0001: stloc.1
IL_0002: ldloca.s V_1
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brtrue.s IL_0016
IL_000b: ldloca.s V_2
IL_000d: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0013: ldloc.2
IL_0014: br.s IL_0024
IL_0016: ldloca.s V_1
IL_0018: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001d: ldc.i4.5
IL_001e: add
IL_001f: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0024: stloc.0
IL_0025: ldloca.s V_0
IL_0027: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_002c: brfalse.s IL_0044
IL_002e: ldloca.s V_0
IL_0030: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0035: stloc.3
IL_0036: ldloc.3
IL_0037: brfalse.s IL_004a
IL_0039: ldloc.3
IL_003a: ldc.i4.5
IL_003b: beq.s IL_0050
IL_003d: ldloc.3
IL_003e: ldc.i4.s 10
IL_0040: beq.s IL_0056
IL_0042: br.s IL_005c
IL_0044: ldstr "null"
IL_0049: ret
IL_004a: ldstr "zero"
IL_004f: ret
IL_0050: ldstr "five"
IL_0055: ret
IL_0056: ldstr "ten"
IL_005b: ret
IL_005c: ldstr "large"
IL_0061: ret
} // end of method Switch::SwitchOverNullableIntShifted
.method public hidebysig static string
SwitchOverNullableIntNoNullCase(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 57 (0x39)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
int32 V_1)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloca.s V_0
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brfalse.s IL_0033
IL_000b: ldloca.s V_0
IL_000d: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: brfalse.s IL_0021
IL_0016: ldloc.1
IL_0017: ldc.i4.5
IL_0018: beq.s IL_0027
IL_001a: ldloc.1
IL_001b: ldc.i4.s 10
IL_001d: beq.s IL_002d
IL_001f: br.s IL_0033
IL_0021: ldstr "zero"
IL_0026: ret
IL_0027: ldstr "five"
IL_002c: ret
IL_002d: ldstr "ten"
IL_0032: ret
IL_0033: ldstr "other"
IL_0038: ret
} // end of method Switch::SwitchOverNullableIntNoNullCase
.method public hidebysig static string
SwitchOverNullableIntNoNullCaseShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 92 (0x5c)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
int32 V_3)
IL_0000: ldarg.0
IL_0001: stloc.1
IL_0002: ldloca.s V_1
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0009: brtrue.s IL_0016
IL_000b: ldloca.s V_2
IL_000d: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0013: ldloc.2
IL_0014: br.s IL_0024
IL_0016: ldloca.s V_1
IL_0018: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001d: ldc.i4.5
IL_001e: add
IL_001f: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0024: stloc.0
IL_0025: ldloca.s V_0
IL_0027: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_002c: brfalse.s IL_0056
IL_002e: ldloca.s V_0
IL_0030: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0035: stloc.3
IL_0036: ldloc.3
IL_0037: brfalse.s IL_0044
IL_0039: ldloc.3
IL_003a: ldc.i4.5
IL_003b: beq.s IL_004a
IL_003d: ldloc.3
IL_003e: ldc.i4.s 10
IL_0040: beq.s IL_0050
IL_0042: br.s IL_0056
IL_0044: ldstr "zero"
IL_0049: ret
IL_004a: ldstr "five"
IL_004f: ret
IL_0050: ldstr "ten"
IL_0055: ret
IL_0056: ldstr "other"
IL_005b: ret
} // end of method Switch::SwitchOverNullableIntNoNullCaseShifted
.method public hidebysig static string .method public hidebysig static string
ShortSwitchOverString(string text) cil managed ShortSwitchOverString(string text) cil managed
{ {
@ -659,6 +867,45 @@
IL_0078: br.s IL_0015 IL_0078: br.s IL_0015
} // end of method Switch::SwitchInLoop } // end of method Switch::SwitchInLoop
.method public hidebysig static void SwitchWithGoto(int32 i) cil managed
{
// Code size 102 (0x66)
.maxstack 2
IL_0000: ldstr "SwitchWithGoto: "
IL_0005: ldarg.0
IL_0006: box [mscorlib]System.Int32
IL_000b: call string [mscorlib]System.String::Concat(object,
object)
IL_0010: call void [mscorlib]System.Console::WriteLine(string)
IL_0015: ldarg.0
IL_0016: ldc.i4.1
IL_0017: sub
IL_0018: switch (
IL_002f,
IL_003b,
IL_0045,
IL_0050)
IL_002d: br.s IL_005b
IL_002f: ldstr "one"
IL_0034: call void [mscorlib]System.Console::WriteLine(string)
IL_0039: br.s IL_005b
IL_003b: ldstr "two"
IL_0040: call void [mscorlib]System.Console::WriteLine(string)
IL_0045: ldstr "three"
IL_004a: call void [mscorlib]System.Console::WriteLine(string)
IL_004f: ret
IL_0050: ldstr "four"
IL_0055: call void [mscorlib]System.Console::WriteLine(string)
IL_005a: ret
IL_005b: ldstr "default"
IL_0060: call void [mscorlib]System.Console::WriteLine(string)
IL_0065: ret
} // end of method Switch::SwitchWithGoto
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[]
GetProperties() cil managed GetProperties() cil managed
{ {

358
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il

@ -1,6 +1,6 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten.
@ -25,14 +25,14 @@
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module Switch.dll .module Switch.dll
// MVID: {134EA2E4-FA5A-4D44-A0FD-C4E5A18E39B1} // MVID: {87DEBC09-DFAD-437D-9221-109E2117A07A}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000 .imagebase 0x10000000
.file alignment 0x00000200 .file alignment 0x00000200
.stackreserve 0x00100000 .stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI .subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY .corflags 0x00000001 // ILONLY
// Image base: 0x00C40000 // Image base: 0x02960000
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
@ -229,6 +229,298 @@
IL_00ed: ret IL_00ed: ret
} // end of method Switch::SparseIntegerSwitch } // end of method Switch::SparseIntegerSwitch
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 87 (0x57)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
int32 V_2,
string V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloc.1
IL_0004: stloc.0
IL_0005: ldloca.s V_0
IL_0007: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000c: brfalse.s IL_0028
IL_000e: ldloca.s V_0
IL_0010: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0015: stloc.2
IL_0016: ldloc.2
IL_0017: brfalse.s IL_0031
IL_0019: br.s IL_001b
IL_001b: ldloc.2
IL_001c: ldc.i4.5
IL_001d: beq.s IL_003a
IL_001f: br.s IL_0021
IL_0021: ldloc.2
IL_0022: ldc.i4.s 10
IL_0024: beq.s IL_0043
IL_0026: br.s IL_004c
IL_0028: nop
IL_0029: ldstr "null"
IL_002e: stloc.3
IL_002f: br.s IL_0055
IL_0031: nop
IL_0032: ldstr "zero"
IL_0037: stloc.3
IL_0038: br.s IL_0055
IL_003a: nop
IL_003b: ldstr "five"
IL_0040: stloc.3
IL_0041: br.s IL_0055
IL_0043: nop
IL_0044: ldstr "ten"
IL_0049: stloc.3
IL_004a: br.s IL_0055
IL_004c: nop
IL_004d: ldstr "large"
IL_0052: stloc.3
IL_0053: br.s IL_0055
IL_0055: ldloc.3
IL_0056: ret
} // end of method Switch::SwitchOverNullableInt
.method public hidebysig static string
SwitchOverNullableIntShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 132 (0x84)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
valuetype [mscorlib]System.Nullable`1<int32> V_3,
int32 V_4,
string V_5)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.2
IL_0003: ldloca.s V_2
IL_0005: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000a: brtrue.s IL_0017
IL_000c: ldloca.s V_3
IL_000e: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0014: ldloc.3
IL_0015: br.s IL_0025
IL_0017: ldloca.s V_2
IL_0019: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001e: ldc.i4.5
IL_001f: add
IL_0020: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: stloc.0
IL_0028: ldloca.s V_0
IL_002a: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_002f: brfalse.s IL_004f
IL_0031: ldloca.s V_0
IL_0033: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0038: stloc.s V_4
IL_003a: ldloc.s V_4
IL_003c: brfalse.s IL_0059
IL_003e: br.s IL_0040
IL_0040: ldloc.s V_4
IL_0042: ldc.i4.5
IL_0043: beq.s IL_0063
IL_0045: br.s IL_0047
IL_0047: ldloc.s V_4
IL_0049: ldc.i4.s 10
IL_004b: beq.s IL_006d
IL_004d: br.s IL_0077
IL_004f: nop
IL_0050: ldstr "null"
IL_0055: stloc.s V_5
IL_0057: br.s IL_0081
IL_0059: nop
IL_005a: ldstr "zero"
IL_005f: stloc.s V_5
IL_0061: br.s IL_0081
IL_0063: nop
IL_0064: ldstr "five"
IL_0069: stloc.s V_5
IL_006b: br.s IL_0081
IL_006d: nop
IL_006e: ldstr "ten"
IL_0073: stloc.s V_5
IL_0075: br.s IL_0081
IL_0077: nop
IL_0078: ldstr "large"
IL_007d: stloc.s V_5
IL_007f: br.s IL_0081
IL_0081: ldloc.s V_5
IL_0083: ret
} // end of method Switch::SwitchOverNullableIntShifted
.method public hidebysig static string
SwitchOverNullableIntNoNullCase(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 78 (0x4e)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
int32 V_2,
string V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloc.1
IL_0004: stloc.0
IL_0005: ldloca.s V_0
IL_0007: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000c: brfalse.s IL_0043
IL_000e: ldloca.s V_0
IL_0010: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0015: stloc.2
IL_0016: ldloc.2
IL_0017: brfalse.s IL_0028
IL_0019: br.s IL_001b
IL_001b: ldloc.2
IL_001c: ldc.i4.5
IL_001d: beq.s IL_0031
IL_001f: br.s IL_0021
IL_0021: ldloc.2
IL_0022: ldc.i4.s 10
IL_0024: beq.s IL_003a
IL_0026: br.s IL_0043
IL_0028: nop
IL_0029: ldstr "zero"
IL_002e: stloc.3
IL_002f: br.s IL_004c
IL_0031: nop
IL_0032: ldstr "five"
IL_0037: stloc.3
IL_0038: br.s IL_004c
IL_003a: nop
IL_003b: ldstr "ten"
IL_0040: stloc.3
IL_0041: br.s IL_004c
IL_0043: nop
IL_0044: ldstr "other"
IL_0049: stloc.3
IL_004a: br.s IL_004c
IL_004c: ldloc.3
IL_004d: ret
} // end of method Switch::SwitchOverNullableIntNoNullCase
.method public hidebysig static string
SwitchOverNullableIntNoNullCaseShifted(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
// Code size 122 (0x7a)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
valuetype [mscorlib]System.Nullable`1<int32> V_1,
valuetype [mscorlib]System.Nullable`1<int32> V_2,
valuetype [mscorlib]System.Nullable`1<int32> V_3,
int32 V_4,
string V_5)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.2
IL_0003: ldloca.s V_2
IL_0005: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_000a: brtrue.s IL_0017
IL_000c: ldloca.s V_3
IL_000e: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0014: ldloc.3
IL_0015: br.s IL_0025
IL_0017: ldloca.s V_2
IL_0019: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_001e: ldc.i4.5
IL_001f: add
IL_0020: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: stloc.0
IL_0028: ldloca.s V_0
IL_002a: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_002f: brfalse.s IL_006d
IL_0031: ldloca.s V_0
IL_0033: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0038: stloc.s V_4
IL_003a: ldloc.s V_4
IL_003c: brfalse.s IL_004f
IL_003e: br.s IL_0040
IL_0040: ldloc.s V_4
IL_0042: ldc.i4.5
IL_0043: beq.s IL_0059
IL_0045: br.s IL_0047
IL_0047: ldloc.s V_4
IL_0049: ldc.i4.s 10
IL_004b: beq.s IL_0063
IL_004d: br.s IL_006d
IL_004f: nop
IL_0050: ldstr "zero"
IL_0055: stloc.s V_5
IL_0057: br.s IL_0077
IL_0059: nop
IL_005a: ldstr "five"
IL_005f: stloc.s V_5
IL_0061: br.s IL_0077
IL_0063: nop
IL_0064: ldstr "ten"
IL_0069: stloc.s V_5
IL_006b: br.s IL_0077
IL_006d: nop
IL_006e: ldstr "other"
IL_0073: stloc.s V_5
IL_0075: br.s IL_0077
IL_0077: ldloc.s V_5
IL_0079: ret
} // end of method Switch::SwitchOverNullableIntNoNullCaseShifted
.method public hidebysig static string .method public hidebysig static string
ShortSwitchOverString(string text) cil managed ShortSwitchOverString(string text) cil managed
{ {
@ -844,6 +1136,64 @@
IL_0091: ret IL_0091: ret
} // end of method Switch::SwitchInLoop } // end of method Switch::SwitchInLoop
.method public hidebysig static void SwitchWithGoto(int32 i) cil managed
{
// Code size 122 (0x7a)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldstr "SwitchWithGoto: "
IL_0006: ldarg.0
IL_0007: box [mscorlib]System.Int32
IL_000c: call string [mscorlib]System.String::Concat(object,
object)
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: nop
IL_0017: ldarg.0
IL_0018: stloc.0
IL_0019: ldloc.0
IL_001a: ldc.i4.1
IL_001b: sub
IL_001c: switch (
IL_0033,
IL_0041,
IL_004f,
IL_005d)
IL_0031: br.s IL_006b
IL_0033: nop
IL_0034: ldstr "one"
IL_0039: call void [mscorlib]System.Console::WriteLine(string)
IL_003e: nop
IL_003f: br.s IL_006b
IL_0041: nop
IL_0042: ldstr "two"
IL_0047: call void [mscorlib]System.Console::WriteLine(string)
IL_004c: nop
IL_004d: br.s IL_004f
IL_004f: nop
IL_0050: ldstr "three"
IL_0055: call void [mscorlib]System.Console::WriteLine(string)
IL_005a: nop
IL_005b: br.s IL_0079
IL_005d: nop
IL_005e: ldstr "four"
IL_0063: call void [mscorlib]System.Console::WriteLine(string)
IL_0068: nop
IL_0069: br.s IL_0079
IL_006b: nop
IL_006c: ldstr "default"
IL_0071: call void [mscorlib]System.Console::WriteLine(string)
IL_0076: nop
IL_0077: br.s IL_0079
IL_0079: ret
} // end of method Switch::SwitchWithGoto
.method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[]
GetProperties() cil managed GetProperties() cil managed
{ {

60
ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs

@ -48,6 +48,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
changed = true; changed = true;
continue; continue;
} }
if (MatchRoslynSwitchOnNullable(block.Instructions, i, out newSwitch)) {
block.Instructions[i - 1].ReplaceWith(newSwitch);
block.Instructions.RemoveRange(i, 2);
i--;
changed = true;
continue;
}
} }
if (!changed) continue; if (!changed) continue;
SwitchDetection.SimplifySwitchInstruction(block); SwitchDetection.SimplifySwitchInstruction(block);
@ -59,6 +66,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
container.SortBlocks(deleteUnreachableBlocks: true); container.SortBlocks(deleteUnreachableBlocks: true);
} }
/// <summary>
/// Matches legacy C# switch on nullable.
/// </summary>
bool MatchSwitchOnNullable(InstructionCollection<ILInstruction> instructions, int i, out SwitchInstruction newSwitch) bool MatchSwitchOnNullable(InstructionCollection<ILInstruction> instructions, int i, out SwitchInstruction newSwitch)
{ {
newSwitch = null; newSwitch = null;
@ -113,5 +123,55 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
return true; return true;
} }
/// <summary>
/// Matches Roslyn C# switch on nullable.
/// </summary>
bool MatchRoslynSwitchOnNullable(InstructionCollection<ILInstruction> instructions, int i, out SwitchInstruction newSwitch)
{
newSwitch = null;
// match first block:
// stloc tmp(ldloc switchValueVar)
// if (logic.not(call get_HasValue(ldloca tmp))) br nullCaseBlock
// br switchBlock
if (i < 1) return false;
if (!instructions[i - 1].MatchStLoc(out var tmp, out var switchValue) ||
!instructions[i].MatchIfInstruction(out var condition, out var trueInst))
return false;
if (!instructions[i + 1].MatchBranch(out var switchBlock) || !trueInst.MatchBranch(out var nullCaseBlock))
return false;
if (!condition.MatchLogicNot(out var getHasValue) || !NullableLiftingTransform.MatchHasValueCall(getHasValue, out var target1) || target1 != tmp)
return false;
// match second block: switchBlock
// stloc switchVar(call GetValueOrDefault(ldloca tmp))
// switch (ldloc switchVar) {
// case [0..1): br caseBlock1
// ... more cases ...
// case [long.MinValue..0),[1..5),[6..10),[11..long.MaxValue]: br defaultBlock
// }
if (switchBlock.Instructions.Count != 2 || switchBlock.IncomingEdgeCount != 1)
return false;
if (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault))
return false;
if (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, out var target2) || target2 != tmp)
return false;
if (!(switchBlock.Instructions[1] is SwitchInstruction switchInst))
return false;
newSwitch = new SwitchInstruction(switchValue);
newSwitch.IsLifted = true;
SwitchSection defaultSection = null;
foreach (var section in switchInst.Sections) {
if (defaultSection == null || section.Labels.Count() >= defaultSection.Labels.Count())
defaultSection = section;
newSwitch.Sections.Add(section);
}
if (defaultSection.Body.MatchBranch(out var defaultBlock) && defaultBlock == nullCaseBlock)
defaultSection.HasNullLabel = true;
else {
newSwitch.Sections.Add(new SwitchSection { Body = new Branch(nullCaseBlock), HasNullLabel = true });
}
return true;
}
} }
} }

Loading…
Cancel
Save