diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 0d2436bf4..a591c7338 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -83,6 +83,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.Expected.cs b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.Expected.cs new file mode 100644 index 000000000..05c27d59c --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.Expected.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly +{ + internal class NoForEachStatement + { + public static void SimpleNonGenericForeach(IEnumerable enumerable) + { + IEnumerator enumerator = enumerable.GetEnumerator(); + try { + while (enumerator.MoveNext()) { +#if ROSLYN && OPT + Console.WriteLine(enumerator.Current); +#else + object current = enumerator.Current; + Console.WriteLine(current); +#endif + } + } finally { + IDisposable disposable = enumerator as IDisposable; + if (disposable != null) { + disposable.Dispose(); + } + } + } + + public static void SimpleForeachOverInts(IEnumerable enumerable) + { + using (IEnumerator enumerator = enumerable.GetEnumerator()) { + while (enumerator.MoveNext()) { +#if ROSLYN && OPT + Console.WriteLine(enumerator.Current); +#else + int current = enumerator.Current; + Console.WriteLine(current); +#endif + } + } + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.cs b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.cs new file mode 100644 index 000000000..6cced27e6 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly +{ + internal class NoForEachStatement + { + public static void SimpleNonGenericForeach(IEnumerable enumerable) + { + foreach (object item in enumerable) { + Console.WriteLine(item); + } + } + + public static void SimpleForeachOverInts(IEnumerable enumerable) + { + foreach (int item in enumerable) { + Console.WriteLine(item); + } + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.il new file mode 100644 index 000000000..0218966ae --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.il @@ -0,0 +1,156 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly rerff2f0 +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .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. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module rerff2f0.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + extends [mscorlib]System.Object +{ + .method public hidebysig static void SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed + { + // Code size 64 (0x40) + .maxstack 2 + .locals init (object V_0, + class [mscorlib]System.Collections.IEnumerator V_1, + bool V_2, + class [mscorlib]System.IDisposable V_3) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0008: stloc.1 + .try + { + IL_0009: br.s IL_001b + + IL_000b: ldloc.1 + IL_000c: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_0011: stloc.0 + IL_0012: nop + IL_0013: ldloc.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(object) + IL_0019: nop + IL_001a: nop + IL_001b: ldloc.1 + IL_001c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0021: stloc.2 + IL_0022: ldloc.2 + IL_0023: brtrue.s IL_000b + + IL_0025: leave.s IL_003e + + } // end .try + finally + { + IL_0027: ldloc.1 + IL_0028: isinst [mscorlib]System.IDisposable + IL_002d: stloc.3 + IL_002e: ldloc.3 + IL_002f: ldnull + IL_0030: ceq + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: brtrue.s IL_003d + + IL_0036: ldloc.3 + IL_0037: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_003c: nop + IL_003d: endfinally + } // end handler + IL_003e: nop + IL_003f: ret + } // end of method NoForEachStatement::SimpleNonGenericForeach + + .method public hidebysig static void SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + { + // Code size 57 (0x39) + .maxstack 2 + .locals init (int32 V_0, + class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1, + bool V_2) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0008: stloc.1 + .try + { + IL_0009: br.s IL_001b + + IL_000b: ldloc.1 + IL_000c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0011: stloc.0 + IL_0012: nop + IL_0013: ldloc.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: nop + IL_001a: nop + IL_001b: ldloc.1 + IL_001c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0021: stloc.2 + IL_0022: ldloc.2 + IL_0023: brtrue.s IL_000b + + IL_0025: leave.s IL_0037 + + } // end .try + finally + { + IL_0027: ldloc.1 + IL_0028: ldnull + IL_0029: ceq + IL_002b: stloc.2 + IL_002c: ldloc.2 + IL_002d: brtrue.s IL_0036 + + IL_002f: ldloc.1 + IL_0030: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0035: nop + IL_0036: endfinally + } // end handler + IL_0037: nop + IL_0038: ret + } // end of method NoForEachStatement::SimpleForeachOverInts + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoForEachStatement::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.il new file mode 100644 index 000000000..7307150dd --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.il @@ -0,0 +1,128 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly prqfqkbt +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .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. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module prqfqkbt.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + extends [mscorlib]System.Object +{ + .method public hidebysig static void SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed + { + // Code size 50 (0x32) + .maxstack 1 + .locals init (object V_0, + class [mscorlib]System.Collections.IEnumerator V_1, + class [mscorlib]System.IDisposable V_2) + IL_0000: ldarg.0 + IL_0001: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0006: stloc.1 + .try + { + IL_0007: br.s IL_0016 + + IL_0009: ldloc.1 + IL_000a: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(object) + IL_0016: ldloc.1 + IL_0017: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_001c: brtrue.s IL_0009 + + IL_001e: leave.s IL_0031 + + } // end .try + finally + { + IL_0020: ldloc.1 + IL_0021: isinst [mscorlib]System.IDisposable + IL_0026: stloc.2 + IL_0027: ldloc.2 + IL_0028: brfalse.s IL_0030 + + IL_002a: ldloc.2 + IL_002b: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0030: endfinally + } // end handler + IL_0031: ret + } // end of method NoForEachStatement::SimpleNonGenericForeach + + .method public hidebysig static void SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + { + // Code size 43 (0x2b) + .maxstack 1 + .locals init (int32 V_0, + class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1) + IL_0000: ldarg.0 + IL_0001: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0006: stloc.1 + .try + { + IL_0007: br.s IL_0016 + + IL_0009: ldloc.1 + IL_000a: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(int32) + IL_0016: ldloc.1 + IL_0017: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_001c: brtrue.s IL_0009 + + IL_001e: leave.s IL_002a + + } // end .try + finally + { + IL_0020: ldloc.1 + IL_0021: brfalse.s IL_0029 + + IL_0023: ldloc.1 + IL_0024: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0029: endfinally + } // end handler + IL_002a: ret + } // end of method NoForEachStatement::SimpleForeachOverInts + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoForEachStatement::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.roslyn.il new file mode 100644 index 000000000..10d523787 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.roslyn.il @@ -0,0 +1,126 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly NoForEachStatement +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .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. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module NoForEachStatement.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + extends [mscorlib]System.Object +{ + .method public hidebysig static void SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed + { + // Code size 48 (0x30) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.IEnumerator V_0, + class [mscorlib]System.IDisposable V_1) + IL_0000: ldarg.0 + IL_0001: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0006: stloc.0 + .try + { + IL_0007: br.s IL_0014 + + IL_0009: ldloc.0 + IL_000a: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_000f: call void [mscorlib]System.Console::WriteLine(object) + IL_0014: ldloc.0 + IL_0015: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_001a: brtrue.s IL_0009 + + IL_001c: leave.s IL_002f + + } // end .try + finally + { + IL_001e: ldloc.0 + IL_001f: isinst [mscorlib]System.IDisposable + IL_0024: stloc.1 + IL_0025: ldloc.1 + IL_0026: brfalse.s IL_002e + + IL_0028: ldloc.1 + IL_0029: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002e: endfinally + } // end handler + IL_002f: ret + } // end of method NoForEachStatement::SimpleNonGenericForeach + + .method public hidebysig static void SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + { + // Code size 41 (0x29) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1 V_0) + IL_0000: ldarg.0 + IL_0001: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0006: stloc.0 + .try + { + IL_0007: br.s IL_0014 + + IL_0009: ldloc.0 + IL_000a: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_000f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0014: ldloc.0 + IL_0015: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_001a: brtrue.s IL_0009 + + IL_001c: leave.s IL_0028 + + } // end .try + finally + { + IL_001e: ldloc.0 + IL_001f: brfalse.s IL_0027 + + IL_0021: ldloc.0 + IL_0022: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0027: endfinally + } // end handler + IL_0028: ret + } // end of method NoForEachStatement::SimpleForeachOverInts + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method NoForEachStatement::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.roslyn.il new file mode 100644 index 000000000..8c8ecb107 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.roslyn.il @@ -0,0 +1,145 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly NoForEachStatement +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .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. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module NoForEachStatement.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + extends [mscorlib]System.Object +{ + .method public hidebysig static void SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed + { + // Code size 56 (0x38) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.IEnumerator V_0, + object V_1, + class [mscorlib]System.IDisposable V_2) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0008: stloc.0 + .try + { + IL_0009: br.s IL_001b + + IL_000b: ldloc.0 + IL_000c: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_0011: stloc.1 + IL_0012: nop + IL_0013: ldloc.1 + IL_0014: call void [mscorlib]System.Console::WriteLine(object) + IL_0019: nop + IL_001a: nop + IL_001b: ldloc.0 + IL_001c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0021: brtrue.s IL_000b + + IL_0023: leave.s IL_0037 + + } // end .try + finally + { + IL_0025: ldloc.0 + IL_0026: isinst [mscorlib]System.IDisposable + IL_002b: stloc.2 + IL_002c: ldloc.2 + IL_002d: brfalse.s IL_0036 + + IL_002f: ldloc.2 + IL_0030: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0035: nop + IL_0036: endfinally + } // end handler + IL_0037: ret + } // end of method NoForEachStatement::SimpleNonGenericForeach + + .method public hidebysig static void SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + { + // Code size 49 (0x31) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1 V_0, + int32 V_1) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0008: stloc.0 + .try + { + IL_0009: br.s IL_001b + + IL_000b: ldloc.0 + IL_000c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0011: stloc.1 + IL_0012: nop + IL_0013: ldloc.1 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: nop + IL_001a: nop + IL_001b: ldloc.0 + IL_001c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0021: brtrue.s IL_000b + + IL_0023: leave.s IL_0030 + + } // end .try + finally + { + IL_0025: ldloc.0 + IL_0026: brfalse.s IL_002f + + IL_0028: ldloc.0 + IL_0029: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002e: nop + IL_002f: endfinally + } // end handler + IL_0030: ret + } // end of method NoForEachStatement::SimpleForeachOverInts + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method NoForEachStatement::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs index 63ebcf6dd..e0e2b7aeb 100644 --- a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs @@ -68,7 +68,7 @@ namespace ICSharpCode.Decompiler.Tests }; [Test] - public void NoArrayInitializers([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) + public void NoArrayInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { ArrayInitializers = false @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void NoDecimalConstants([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) + public void NoDecimalConstants([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { DecimalConstants = false @@ -84,13 +84,21 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void NoExtensionMethods([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) + public void NoExtensionMethods([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { ExtensionMethods = false }); } + [Test] + public void NoForEachStatement([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { + ForEachStatement = false + }); + } + void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);