From d04155132affcc36ede6f98b9c18a7676bedc1b0 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 23 Jun 2018 00:47:06 +0200 Subject: [PATCH] Use overload resolution to add only required casts to collection initializers. --- .../TestCases/Pretty/InitializerTests.cs | 41 ++++- .../TestCases/Pretty/InitializerTests.il | 167 ++++++++++++++---- .../TestCases/Pretty/InitializerTests.opt.il | 154 +++++++++++++--- .../Pretty/InitializerTests.opt.roslyn.il | 126 ++++++++++--- .../Pretty/InitializerTests.roslyn.il | 139 ++++++++++++--- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 141 ++++++++++++--- .../CSharp/ExpressionBuilder.cs | 15 +- 7 files changed, 629 insertions(+), 154 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index e6f63925c..32b134dad 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -51,6 +51,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests { new Dictionary().Add(name, typeof(T2)); } + + public void Add(params int[] ints) + { + } } public class C @@ -247,19 +251,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests X(Y(), array); } - public static CustomList ExtensionMethodInCollectionInitializer() + public static void ExtensionMethodInCollectionInitializer() { #if CS60 - return new CustomList { + X(Y(), new CustomList { { 1, 2 } - }; + }); #else CustomList customList = new CustomList(); customList.Add(1, 2); - return customList; + X(Y(), customList); #endif } @@ -270,6 +274,24 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests Console.WriteLine(customList); } + public static void CollectionInitializerWithParamsMethod() + { + X(Y(), new CustomList { + { + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + } + }); + } + public static void CollectionInitializerList() { X(Y(), new List { @@ -579,5 +601,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests Guid.Empty }); } + + + private void Issue907_Test3(string text) + { + X(Y(), new Dictionary { + { + "", + text + } + }); + } } } \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il index 65afd10d5..45d16155a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -99,6 +99,17 @@ IL_0017: ret } // end of method CustomList`1::Add + .method public hidebysig instance void + Add(int32[] ints) cil managed + { + .param [1] + .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method CustomList`1::Add + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -626,9 +637,9 @@ } // end of property StructData::MoreData } // end of class StructData - .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate8' + .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate9' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1c' + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1d' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method private hidebysig static void X(object a, object b) cil managed @@ -913,29 +924,36 @@ IL_001c: ret } // end of method TestCases::IndicesInWrongOrder - .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 - ExtensionMethodInCollectionInitializer() cil managed + .method public hidebysig static void ExtensionMethodInCollectionInitializer() cil managed { - // Code size 22 (0x16) - .maxstack 3 + // Code size 43 (0x2b) + .maxstack 4 .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0, - class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_1) + int32[] V_1) IL_0000: nop IL_0001: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 - IL_0008: ldc.i4.1 - IL_0009: ldc.i4.2 - IL_000a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.Extensions::Add(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1, - int32, - int32) - IL_000f: nop - IL_0010: ldloc.0 - IL_0011: stloc.1 - IL_0012: br.s IL_0014 - - IL_0014: ldloc.1 - IL_0015: ret + IL_0008: ldc.i4.2 + IL_0009: newarr [mscorlib]System.Int32 + IL_000e: stloc.1 + IL_000f: ldloc.1 + IL_0010: ldc.i4.0 + IL_0011: ldc.i4.1 + IL_0012: stelem.i4 + IL_0013: ldloc.1 + IL_0014: ldc.i4.1 + IL_0015: ldc.i4.2 + IL_0016: stelem.i4 + IL_0017: ldloc.1 + IL_0018: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_001d: nop + IL_001e: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0023: ldloc.0 + IL_0024: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_0029: nop + IL_002a: ret } // end of method TestCases::ExtensionMethodInCollectionInitializer .method public hidebysig static void NoCollectionInitializerBecauseOfTypeArguments() cil managed @@ -956,6 +974,70 @@ IL_001a: ret } // end of method TestCases::NoCollectionInitializerBecauseOfTypeArguments + .method public hidebysig static void CollectionInitializerWithParamsMethod() cil managed + { + // Code size 79 (0x4f) + .maxstack 5 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0, + int32[] V_1) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0006: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.s 10 + IL_000f: newarr [mscorlib]System.Int32 + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.0 + IL_0017: ldc.i4.1 + IL_0018: stelem.i4 + IL_0019: ldloc.1 + IL_001a: ldc.i4.1 + IL_001b: ldc.i4.2 + IL_001c: stelem.i4 + IL_001d: ldloc.1 + IL_001e: ldc.i4.2 + IL_001f: ldc.i4.3 + IL_0020: stelem.i4 + IL_0021: ldloc.1 + IL_0022: ldc.i4.3 + IL_0023: ldc.i4.4 + IL_0024: stelem.i4 + IL_0025: ldloc.1 + IL_0026: ldc.i4.4 + IL_0027: ldc.i4.5 + IL_0028: stelem.i4 + IL_0029: ldloc.1 + IL_002a: ldc.i4.5 + IL_002b: ldc.i4.6 + IL_002c: stelem.i4 + IL_002d: ldloc.1 + IL_002e: ldc.i4.6 + IL_002f: ldc.i4.7 + IL_0030: stelem.i4 + IL_0031: ldloc.1 + IL_0032: ldc.i4.7 + IL_0033: ldc.i4.8 + IL_0034: stelem.i4 + IL_0035: ldloc.1 + IL_0036: ldc.i4.8 + IL_0037: ldc.i4.s 9 + IL_0039: stelem.i4 + IL_003a: ldloc.1 + IL_003b: ldc.i4.s 9 + IL_003d: ldc.i4.s 10 + IL_003f: stelem.i4 + IL_0040: ldloc.1 + IL_0041: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_0046: nop + IL_0047: ldloc.0 + IL_0048: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_004d: nop + IL_004e: ret + } // end of method TestCases::CollectionInitializerWithParamsMethod + .method public hidebysig static void CollectionInitializerList() cil managed { // Code size 44 (0x2c) @@ -1145,18 +1227,18 @@ IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 - IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' IL_000d: brtrue.s IL_0022 IL_000f: ldnull - IL_0010: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__7'(object, + IL_0010: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__8'(object, class [mscorlib]System.EventArgs) IL_0016: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int) - IL_001b: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_001b: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' IL_0020: br.s IL_0022 - IL_0022: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0022: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::add_TestEvent(class [mscorlib]System.EventHandler) IL_002c: nop IL_002d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() @@ -1637,17 +1719,17 @@ IL_003f: nop IL_0040: ldloc.2 IL_0041: ldloc.0 - IL_0042: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_0042: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' IL_0047: brtrue.s IL_005c IL_0049: ldnull - IL_004a: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__1b'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_004a: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__1c'(class [mscorlib]System.Globalization.NumberFormatInfo) IL_0050: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) - IL_0055: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_0055: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' IL_005a: br.s IL_005c - IL_005c: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_005c: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' IL_0061: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) IL_0066: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1) @@ -1684,6 +1766,29 @@ IL_0025: ret } // end of method TestCases::Bug953_MissingNullableSpecifierForArrayInitializer + .method private hidebysig instance void + Issue907_Test3(string text) cil managed + { + // Code size 33 (0x21) + .maxstack 4 + .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2 V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldstr "" + IL_0012: ldarg.1 + IL_0013: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0018: nop + IL_0019: ldloc.0 + IL_001a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_001f: nop + IL_0020: ret + } // end of method TestCases::Issue907_Test3 + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -1694,7 +1799,7 @@ IL_0006: ret } // end of method TestCases::.ctor - .method private hidebysig static void 'b__7'(object param0, + .method private hidebysig static void 'b__8'(object param0, class [mscorlib]System.EventArgs param1) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -1704,9 +1809,9 @@ IL_0001: call void [mscorlib]System.Console::WriteLine() IL_0006: nop IL_0007: ret - } // end of method TestCases::'b__7' + } // end of method TestCases::'b__8' - .method private hidebysig static bool 'b__1b'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + .method private hidebysig static bool 'b__1c'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 21 (0x15) @@ -1722,7 +1827,7 @@ IL_0013: ldloc.0 IL_0014: ret - } // end of method TestCases::'b__1b' + } // end of method TestCases::'b__1c' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il index 9cbd55a85..8c98531d0 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -94,6 +94,16 @@ IL_0015: ret } // end of method CustomList`1::Add + .method public hidebysig instance void + Add(int32[] ints) cil managed + { + .param [1] + .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method CustomList`1::Add + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -556,9 +566,9 @@ } // end of property StructData::MoreData } // end of class StructData - .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate8' + .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate9' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1c' + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1d' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method private hidebysig static void X(object a, object b) cil managed @@ -785,22 +795,33 @@ IL_001a: ret } // end of method TestCases::IndicesInWrongOrder - .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 - ExtensionMethodInCollectionInitializer() cil managed + .method public hidebysig static void ExtensionMethodInCollectionInitializer() cil managed { - // Code size 16 (0x10) - .maxstack 3 - .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0) + // Code size 40 (0x28) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0, + int32[] V_1) IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 - IL_0007: ldc.i4.1 - IL_0008: ldc.i4.2 - IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.Extensions::Add(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1, - int32, - int32) - IL_000e: ldloc.0 - IL_000f: ret + IL_0007: ldc.i4.2 + IL_0008: newarr [mscorlib]System.Int32 + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: ldc.i4.0 + IL_0010: ldc.i4.1 + IL_0011: stelem.i4 + IL_0012: ldloc.1 + IL_0013: ldc.i4.1 + IL_0014: ldc.i4.2 + IL_0015: stelem.i4 + IL_0016: ldloc.1 + IL_0017: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_001c: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0021: ldloc.0 + IL_0022: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_0027: ret } // end of method TestCases::ExtensionMethodInCollectionInitializer .method public hidebysig static void NoCollectionInitializerBecauseOfTypeArguments() cil managed @@ -818,6 +839,67 @@ IL_0017: ret } // end of method TestCases::NoCollectionInitializerBecauseOfTypeArguments + .method public hidebysig static void CollectionInitializerWithParamsMethod() cil managed + { + // Code size 76 (0x4c) + .maxstack 5 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0, + int32[] V_1) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0005: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.s 10 + IL_000e: newarr [mscorlib]System.Int32 + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: ldc.i4.0 + IL_0016: ldc.i4.1 + IL_0017: stelem.i4 + IL_0018: ldloc.1 + IL_0019: ldc.i4.1 + IL_001a: ldc.i4.2 + IL_001b: stelem.i4 + IL_001c: ldloc.1 + IL_001d: ldc.i4.2 + IL_001e: ldc.i4.3 + IL_001f: stelem.i4 + IL_0020: ldloc.1 + IL_0021: ldc.i4.3 + IL_0022: ldc.i4.4 + IL_0023: stelem.i4 + IL_0024: ldloc.1 + IL_0025: ldc.i4.4 + IL_0026: ldc.i4.5 + IL_0027: stelem.i4 + IL_0028: ldloc.1 + IL_0029: ldc.i4.5 + IL_002a: ldc.i4.6 + IL_002b: stelem.i4 + IL_002c: ldloc.1 + IL_002d: ldc.i4.6 + IL_002e: ldc.i4.7 + IL_002f: stelem.i4 + IL_0030: ldloc.1 + IL_0031: ldc.i4.7 + IL_0032: ldc.i4.8 + IL_0033: stelem.i4 + IL_0034: ldloc.1 + IL_0035: ldc.i4.8 + IL_0036: ldc.i4.s 9 + IL_0038: stelem.i4 + IL_0039: ldloc.1 + IL_003a: ldc.i4.s 9 + IL_003c: ldc.i4.s 10 + IL_003e: stelem.i4 + IL_003f: ldloc.1 + IL_0040: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_0045: ldloc.0 + IL_0046: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_004b: ret + } // end of method TestCases::CollectionInitializerWithParamsMethod + .method public hidebysig static void CollectionInitializerList() cil managed { // Code size 39 (0x27) @@ -974,16 +1056,16 @@ IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 - IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' IL_000c: brtrue.s IL_001f IL_000e: ldnull - IL_000f: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__7'(object, + IL_000f: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__8'(object, class [mscorlib]System.EventArgs) IL_0015: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int) - IL_001a: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' - IL_001f: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_001a: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' + IL_001f: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate9' IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::add_TestEvent(class [mscorlib]System.EventHandler) IL_0029: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() IL_002e: ldloc.0 @@ -1385,15 +1467,15 @@ IL_0037: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_DateTimeFormat(class [mscorlib]System.Globalization.DateTimeFormatInfo) IL_003c: ldloc.2 IL_003d: ldloc.0 - IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' IL_0043: brtrue.s IL_0056 IL_0045: ldnull - IL_0046: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__1b'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0046: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'b__1c'(class [mscorlib]System.Globalization.NumberFormatInfo) IL_004c: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) - IL_0051: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' - IL_0056: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_0051: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' + IL_0056: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::'CS$<>9__CachedAnonymousMethodDelegate1d' IL_005b: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) IL_0060: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1) @@ -1425,6 +1507,26 @@ IL_0023: ret } // end of method TestCases::Bug953_MissingNullableSpecifierForArrayInitializer + .method private hidebysig instance void + Issue907_Test3(string text) cil managed + { + // Code size 30 (0x1e) + .maxstack 4 + .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldstr "" + IL_0011: ldarg.1 + IL_0012: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0017: ldloc.0 + IL_0018: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_001d: ret + } // end of method TestCases::Issue907_Test3 + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -1435,7 +1537,7 @@ IL_0006: ret } // end of method TestCases::.ctor - .method private hidebysig static void 'b__7'(object param0, + .method private hidebysig static void 'b__8'(object param0, class [mscorlib]System.EventArgs param1) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -1443,9 +1545,9 @@ .maxstack 8 IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret - } // end of method TestCases::'b__7' + } // end of method TestCases::'b__8' - .method private hidebysig static bool 'b__1b'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + .method private hidebysig static bool 'b__1c'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 17 (0x11) @@ -1456,7 +1558,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method TestCases::'b__1b' + } // end of method TestCases::'b__1c' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il index 1c0a02f42..f224f563e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -98,6 +98,16 @@ IL_0015: ret } // end of method CustomList`1::Add + .method public hidebysig instance void + Add(int32[] ints) cil managed + { + .param [1] + .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method CustomList`1::Add + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -568,8 +578,8 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' '<>9' - .field public static class [mscorlib]System.EventHandler '<>9__29_0' - .field public static class [mscorlib]System.Func`2 '<>9__49_0' + .field public static class [mscorlib]System.EventHandler '<>9__30_0' + .field public static class [mscorlib]System.Func`2 '<>9__50_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -591,17 +601,17 @@ } // end of method '<>c'::.ctor .method assembly hidebysig instance void - 'b__29_0'(object '', + 'b__30_0'(object '', class [mscorlib]System.EventArgs '') cil managed { // Code size 6 (0x6) .maxstack 8 IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret - } // end of method '<>c'::'b__29_0' + } // end of method '<>c'::'b__30_0' .method assembly hidebysig instance bool - 'b__49_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + 'b__50_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { // Code size 17 (0x11) .maxstack 8 @@ -611,7 +621,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method '<>c'::'b__49_0' + } // end of method '<>c'::'b__50_0' } // end of class '<>c' @@ -819,19 +829,30 @@ IL_001a: ret } // end of method TestCases::IndicesInWrongOrder - .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 - ExtensionMethodInCollectionInitializer() cil managed + .method public hidebysig static void ExtensionMethodInCollectionInitializer() cil managed { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() - IL_0005: dup - IL_0006: ldc.i4.1 - IL_0007: ldc.i4.2 - IL_0008: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.Extensions::Add(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1, - int32, - int32) - IL_000d: ret + // Code size 38 (0x26) + .maxstack 6 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0005: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.2 + IL_000d: newarr [mscorlib]System.Int32 + IL_0012: dup + IL_0013: ldc.i4.0 + IL_0014: ldc.i4.1 + IL_0015: stelem.i4 + IL_0016: dup + IL_0017: ldc.i4.1 + IL_0018: ldc.i4.2 + IL_0019: stelem.i4 + IL_001a: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_001f: ldloc.0 + IL_0020: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_0025: ret } // end of method TestCases::ExtensionMethodInCollectionInitializer .method public hidebysig static void NoCollectionInitializerBecauseOfTypeArguments() cil managed @@ -846,6 +867,28 @@ IL_0015: ret } // end of method TestCases::NoCollectionInitializerBecauseOfTypeArguments + .method public hidebysig static void CollectionInitializerWithParamsMethod() cil managed + { + // Code size 42 (0x2a) + .maxstack 5 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0005: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.s 10 + IL_000e: newarr [mscorlib]System.Int32 + IL_0013: dup + IL_0014: ldtoken field valuetype ''/'__StaticArrayInitTypeSize=40' ''::E0D2592373A0C161E56E266306CD8405CD719D19 + IL_0019: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, + valuetype [mscorlib]System.RuntimeFieldHandle) + IL_001e: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_0023: ldloc.0 + IL_0024: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_0029: ret + } // end of method TestCases::CollectionInitializerWithParamsMethod + .method public hidebysig static void CollectionInitializerList() cil managed { // Code size 37 (0x25) @@ -987,18 +1030,18 @@ IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 - IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__29_0' + IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__30_0' IL_000c: dup IL_000d: brtrue.s IL_0026 IL_000f: pop IL_0010: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9' - IL_0015: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__29_0'(object, + IL_0015: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__30_0'(object, class [mscorlib]System.EventArgs) IL_001b: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int) IL_0020: dup - IL_0021: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__29_0' + IL_0021: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__30_0' IL_0026: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::add_TestEvent(class [mscorlib]System.EventHandler) IL_002b: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() IL_0030: ldloc.0 @@ -1461,17 +1504,17 @@ IL_0033: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_DateTimeFormat(class [mscorlib]System.Globalization.DateTimeFormatInfo) IL_0038: dup IL_0039: ldloc.0 - IL_003a: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__49_0' + IL_003a: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__50_0' IL_003f: dup IL_0040: brtrue.s IL_0059 IL_0042: pop IL_0043: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9' - IL_0048: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__49_0'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0048: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__50_0'(class [mscorlib]System.Globalization.NumberFormatInfo) IL_004e: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) IL_0053: dup - IL_0054: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__49_0' + IL_0054: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__50_0' IL_0059: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) IL_005e: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1) @@ -1497,6 +1540,23 @@ IL_001c: ret } // end of method TestCases::Bug953_MissingNullableSpecifierForArrayInitializer + .method private hidebysig instance void + Issue907_Test3(string text) cil managed + { + // Code size 28 (0x1c) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000a: dup + IL_000b: ldstr "" + IL_0010: ldarg.1 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0016: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_001b: ret + } // end of method TestCases::Issue907_Test3 + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -1509,7 +1569,25 @@ } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases +.class private auto ansi sealed '' + extends [mscorlib]System.Object +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=40' + extends [mscorlib]System.ValueType + { + .pack 1 + .size 40 + } // end of class '__StaticArrayInitTypeSize=40' + + .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=40' E0D2592373A0C161E56E266306CD8405CD719D19 at I_00004630 +} // end of class '' + // ============================================================= +.data cil I_00004630 = bytearray ( + 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 + 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 + 09 00 00 00 0A 00 00 00) // *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il index b13b2d070..56d92d6db 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -103,6 +103,17 @@ IL_0017: ret } // end of method CustomList`1::Add + .method public hidebysig instance void + Add(int32[] ints) cil managed + { + .param [1] + .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method CustomList`1::Add + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -601,8 +612,8 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' '<>9' - .field public static class [mscorlib]System.EventHandler '<>9__29_0' - .field public static class [mscorlib]System.Func`2 '<>9__49_0' + .field public static class [mscorlib]System.EventHandler '<>9__30_0' + .field public static class [mscorlib]System.Func`2 '<>9__50_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -625,7 +636,7 @@ } // end of method '<>c'::.ctor .method assembly hidebysig instance void - 'b__29_0'(object '', + 'b__30_0'(object '', class [mscorlib]System.EventArgs '') cil managed { // Code size 8 (0x8) @@ -634,10 +645,10 @@ IL_0001: call void [mscorlib]System.Console::WriteLine() IL_0006: nop IL_0007: ret - } // end of method '<>c'::'b__29_0' + } // end of method '<>c'::'b__30_0' .method assembly hidebysig instance bool - 'b__49_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + 'b__50_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { // Code size 17 (0x11) .maxstack 8 @@ -647,7 +658,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method '<>c'::'b__49_0' + } // end of method '<>c'::'b__50_0' } // end of class '<>c' @@ -925,26 +936,33 @@ IL_001c: ret } // end of method TestCases::IndicesInWrongOrder - .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 - ExtensionMethodInCollectionInitializer() cil managed + .method public hidebysig static void ExtensionMethodInCollectionInitializer() cil managed { - // Code size 20 (0x14) - .maxstack 4 + // Code size 41 (0x29) + .maxstack 6 .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0) IL_0000: nop - IL_0001: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() - IL_0006: dup - IL_0007: ldc.i4.1 - IL_0008: ldc.i4.2 - IL_0009: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.Extensions::Add(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1, - int32, - int32) - IL_000e: nop - IL_000f: stloc.0 - IL_0010: br.s IL_0012 - - IL_0012: ldloc.0 - IL_0013: ret + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0006: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.2 + IL_000e: newarr [mscorlib]System.Int32 + IL_0013: dup + IL_0014: ldc.i4.0 + IL_0015: ldc.i4.1 + IL_0016: stelem.i4 + IL_0017: dup + IL_0018: ldc.i4.1 + IL_0019: ldc.i4.2 + IL_001a: stelem.i4 + IL_001b: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_0020: nop + IL_0021: ldloc.0 + IL_0022: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_0027: nop + IL_0028: ret } // end of method TestCases::ExtensionMethodInCollectionInitializer .method public hidebysig static void NoCollectionInitializerBecauseOfTypeArguments() cil managed @@ -965,6 +983,31 @@ IL_001a: ret } // end of method TestCases::NoCollectionInitializerBecauseOfTypeArguments + .method public hidebysig static void CollectionInitializerWithParamsMethod() cil managed + { + // Code size 45 (0x2d) + .maxstack 5 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1 V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0006: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.s 10 + IL_000f: newarr [mscorlib]System.Int32 + IL_0014: dup + IL_0015: ldtoken field valuetype ''/'__StaticArrayInitTypeSize=40' ''::E0D2592373A0C161E56E266306CD8405CD719D19 + IL_001a: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, + valuetype [mscorlib]System.RuntimeFieldHandle) + IL_001f: callvirt instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/CustomList`1::Add(int32[]) + IL_0024: nop + IL_0025: ldloc.0 + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_002b: nop + IL_002c: ret + } // end of method TestCases::CollectionInitializerWithParamsMethod + .method public hidebysig static void CollectionInitializerList() cil managed { // Code size 42 (0x2a) @@ -1142,18 +1185,18 @@ IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 - IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__29_0' + IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__30_0' IL_000d: dup IL_000e: brtrue.s IL_0027 IL_0010: pop IL_0011: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9' - IL_0016: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__29_0'(object, + IL_0016: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__30_0'(object, class [mscorlib]System.EventArgs) IL_001c: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int) IL_0021: dup - IL_0022: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__29_0' + IL_0022: stsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__30_0' IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/Data::add_TestEvent(class [mscorlib]System.EventHandler) IL_002c: nop IL_002d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() @@ -1708,17 +1751,17 @@ IL_003b: nop IL_003c: dup IL_003d: ldloc.0 - IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__49_0' + IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__50_0' IL_0043: dup IL_0044: brtrue.s IL_005d IL_0046: pop IL_0047: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9' - IL_004c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__49_0'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_004c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'b__50_0'(class [mscorlib]System.Globalization.NumberFormatInfo) IL_0052: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) IL_0057: dup - IL_0058: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__49_0' + IL_0058: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases/'<>c'::'<>9__50_0' IL_005d: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) IL_0062: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1) @@ -1749,6 +1792,26 @@ IL_001e: ret } // end of method TestCases::Bug953_MissingNullableSpecifierForArrayInitializer + .method private hidebysig instance void + Issue907_Test3(string text) cil managed + { + // Code size 31 (0x1f) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000b: dup + IL_000c: ldstr "" + IL_0011: ldarg.1 + IL_0012: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0017: nop + IL_0018: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases::X(object, + object) + IL_001d: nop + IL_001e: ret + } // end of method TestCases::Issue907_Test3 + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -1762,7 +1825,25 @@ } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests.TestCases +.class private auto ansi sealed '' + extends [mscorlib]System.Object +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=40' + extends [mscorlib]System.ValueType + { + .pack 1 + .size 40 + } // end of class '__StaticArrayInitTypeSize=40' + + .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=40' E0D2592373A0C161E56E266306CD8405CD719D19 at I_00004884 +} // end of class '' + // ============================================================= +.data cil I_00004884 = bytearray ( + 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 + 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 + 09 00 00 00 0A 00 00 00) // *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index c2c0038d7..f9c4e73c5 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -140,30 +140,11 @@ namespace ICSharpCode.Decompiler.CSharp // Parameter is marked params // If the argument is an array creation, inline all elements into the call and add missing default values. // Otherwise handle it normally. - if (arg.ResolveResult is ArrayCreateResolveResult acrr && - acrr.SizeArguments.Count == 1 && - acrr.SizeArguments[0].IsCompileTimeConstant && - acrr.SizeArguments[0].ConstantValue is int length) { - var expandedParameters = expectedParameters.Take(expectedParameters.Count - 1).ToList(); - var expandedArguments = new List(arguments); - if (length > 0) { - var arrayElements = ((ArrayCreateExpression)arg.Expression).Initializer.Elements.ToArray(); - var elementType = ((ArrayType)acrr.Type).ElementType; - for (int j = 0; j < length; j++) { - expandedParameters.Add(new DefaultParameter(elementType, parameter.Name + j)); - if (j < arrayElements.Length) - expandedArguments.Add(new TranslatedExpression(arrayElements[j])); - else - expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction()); - } - } + if (TransformParamsArgument(expectedTargetDetails, target.ResolveResult, method, parameter, + arg, ref expectedParameters, ref arguments)) { Debug.Assert(argumentNames == null); - if (IsUnambiguousCall(expectedTargetDetails, method, target.ResolveResult, Empty.Array, expandedArguments, argumentNames, out _) == OverloadResolutionErrors.None) { - isExpandedForm = true; - expectedParameters = expandedParameters; - arguments = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach())); - continue; - } + isExpandedForm = true; + continue; } } @@ -280,6 +261,114 @@ namespace ICSharpCode.Decompiler.CSharp } } + /// + /// Converts a call to an Add method to a collection initializer expression. + /// + public ExpressionWithResolveResult BuildCollectionInitializerExpression(OpCode callOpCode, IMethod method, + InitializedObjectResolveResult target, IReadOnlyList callArguments) + { + // (see ECMA-334, section 12.7.11.4): + // The collection object to which a collection initializer is applied shall be of a type that implements + // System.Collections.IEnumerable or a compile-time error occurs. For each specified element in order, + // the collection initializer invokes an Add method on the target object with the expression list of the + // element initializer as argument list, applying normal overload resolution for each invocation. Thus, the + // collection object shall contain an applicable Add method for each element initializer. + + // The list of applicable methods includes all methods (as of C# 6.0 extension methods, too) named 'Add' + // that can be invoked on the target object, with the following exceptions: + // - Methods with ref or out parameters may not be used, + // - methods that have type parameters, that cannot be inferred from the parameter list may not be used, + // - vararg methods may not be used. + // - named arguments are not supported. + // However, note that params methods may be used. + // TODO : implement support for optional arguments + + // At this point, we assume that 'method' fulfills all the conditions mentioned above. We just need to make + // sure that the correct method is called by resolving any ambiguities by inserting casts, if necessary. + + ExpectedTargetDetails expectedTargetDetails = new ExpectedTargetDetails { CallOpCode = callOpCode }; + + // Special case: only in this case, collection initializers, are extension methods already transformed on + // ILAst level, therefore we have to exclude the first argument. + int firstParamIndex = method.IsExtensionMethod ? 1 : 0; + + var arguments = new List(callArguments.Count); + Debug.Assert(callArguments.Count == method.Parameters.Count - firstParamIndex); + var expectedParameters = new List(arguments.Count); // parameters, but in argument order + bool isExpandedForm = false; + for (int i = 0; i < callArguments.Count; i++) { + var parameter = method.Parameters[i + firstParamIndex]; + + var arg = expressionBuilder.Translate(callArguments[i], parameter.Type); + if (parameter.IsParams && i + 1 == callArguments.Count) { + // Parameter is marked params + // If the argument is an array creation, inline all elements into the call and add missing default values. + // Otherwise handle it normally. + if (TransformParamsArgument(expectedTargetDetails, target, method, parameter, + arg, ref expectedParameters, ref arguments)) { + isExpandedForm = true; + continue; + } + } + + IType parameterType; + if (parameter.Type.Kind == TypeKind.Dynamic) { + parameterType = expressionBuilder.compilation.FindType(KnownTypeCode.Object); + } else { + parameterType = parameter.Type; + } + + arg = arg.ConvertTo(parameterType, expressionBuilder, allowImplicitConversion: arg.Type.Kind != TypeKind.Dynamic); + + arguments.Add(arg); + expectedParameters.Add(parameter); + } + + var unused = new IdentifierExpression("initializedObject").WithRR(target).WithoutILInstruction(); + var transform = GetRequiredTransformationsForCall(expectedTargetDetails, method, ref unused, + arguments, null, expectedParameters, CallTransformation.None, out IParameterizedMember foundMethod); + Debug.Assert(transform == CallTransformation.None); + + // Calls with only one argument do not need an array initializer expression to wrap them. + // Any special cases are handled by the caller (i.e., ExpressionBuilder.TranslateObjectAndCollectionInitializer) + if (arguments.Count == 1) + return arguments[0]; + + return new ArrayInitializerExpression(arguments.Select(a => a.Expression)) + .WithRR(new CSharpInvocationResolveResult(target, method, arguments.SelectArray(a => a.ResolveResult), + isExtensionMethodInvocation: method.IsExtensionMethod, isExpandedForm: isExpandedForm)); + } + + private bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult, + IMethod method, IParameter parameter, TranslatedExpression arg, ref List expectedParameters, + ref List arguments) + { + if (arg.ResolveResult is ArrayCreateResolveResult acrr && + acrr.SizeArguments.Count == 1 && + acrr.SizeArguments[0].IsCompileTimeConstant && + acrr.SizeArguments[0].ConstantValue is int length) { + var expandedParameters = expectedParameters.Take(expectedParameters.Count - 1).ToList(); + var expandedArguments = new List(arguments); + if (length > 0) { + var arrayElements = ((ArrayCreateExpression)arg.Expression).Initializer.Elements.ToArray(); + var elementType = ((ArrayType)acrr.Type).ElementType; + for (int j = 0; j < length; j++) { + expandedParameters.Add(new DefaultParameter(elementType, parameter.Name + j)); + if (j < arrayElements.Length) + expandedArguments.Add(new TranslatedExpression(arrayElements[j])); + else + expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction()); + } + } + if (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty.Array, expandedArguments, null, out _) == OverloadResolutionErrors.None) { + expectedParameters = expandedParameters; + arguments = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach())); + return true; + } + } + return false; + } + [Flags] enum CallTransformation { @@ -310,7 +399,7 @@ namespace ICSharpCode.Decompiler.CSharp requireTarget = !(target.Expression is ThisReferenceExpression); } } else { - requireTarget = false; + requireTarget = true; } bool targetCasted = false; bool argumentsCasted = false; @@ -355,9 +444,9 @@ namespace ICSharpCode.Decompiler.CSharp foundMethod = method; break; } - if (requireTarget) + if ((allowedTransforms & CallTransformation.RequireTarget) != 0 && requireTarget) transform |= CallTransformation.RequireTarget; - if (requireTypeArguments) + if ((allowedTransforms & CallTransformation.RequireTypeArguments) != 0 && requireTypeArguments) transform |= CallTransformation.RequireTypeArguments; return transform; } diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index b9c12106f..7326bf0f8 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -2012,7 +2012,7 @@ namespace ICSharpCode.Decompiler.CSharp var memberRR = new MemberResolveResult(initObjRR, lastElement.Member); switch (info.Kind) { case IL.Transforms.AccessPathKind.Adder: - elementsStack.Peek().Add(MakeInitializerElements(lastElement.OpCode, (IMethod)lastElement.Member, initObjRR, info.Values)); + elementsStack.Peek().Add(new CallBuilder(this, typeSystem, settings).BuildCollectionInitializerExpression(lastElement.OpCode, (IMethod)lastElement.Member, initObjRR, info.Values)); break; case IL.Transforms.AccessPathKind.Setter: if (lastElement.Indices?.Length > 0) { @@ -2062,19 +2062,6 @@ namespace ICSharpCode.Decompiler.CSharp } } - Expression MakeInitializerElements(OpCode opCode, IMethod method, ResolveResult targetResolveResult, List values) - { - int firstParameterOffset = method.IsExtensionMethod ? 1 : 0; - if (values.Count == 1) { - return Translate(values[0], typeHint: method.Parameters[firstParameterOffset].Type).ConvertTo(method.Parameters[0].Type, this); - } - var expressions = new Expression[values.Count]; - for (int i = 0; i < values.Count; i++) { - expressions[i] = Translate(values[i], typeHint: method.Parameters[i + firstParameterOffset].Type).ConvertTo(method.Parameters[i + firstParameterOffset].Type, this); - } - return new ArrayInitializerExpression(expressions); - } - TranslatedExpression TranslateArrayInitializer(Block block) { var stloc = block.Instructions.FirstOrDefault() as StLoc;