From 8f588208b9d6940957aa8119662a48f3e2334755 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 7 Jul 2018 19:58:23 +0200 Subject: [PATCH] Fix tuple type in 'new List<(int, string)>'. --- .../TestCases/Pretty/TupleTests.cs | 28 +- .../TestCases/Pretty/TupleTests.opt.roslyn.il | 168 +++++++---- .../TestCases/Pretty/TupleTests.roslyn.il | 192 ++++++++---- .../ICSharpCode.Decompiler.csproj | 1 - .../TypeSystem/ApplyAttributeTypeVisitor.cs | 12 +- .../Implementation/MetadataTypeParameter.cs | 1 - .../Implementation/MetadataTypeReference.cs | 278 ------------------ .../TypeSystem/MetadataAssembly.cs | 30 +- 8 files changed, 305 insertions(+), 405 deletions(-) delete mode 100644 ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs index e9cd6678d..abd6b9b81 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections; using System.Collections.Generic; using System.Linq; @@ -111,20 +112,31 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public void Foreach(IEnumerable<(int, string)> input) { - foreach (var item3 in input) { - int item = item3.Item1; - string item2 = item3.Item2; - Console.WriteLine($"{item}: {item2}"); + foreach (var item in input) { + Console.WriteLine($"{item.Item1}: {item.Item2}"); } } public void ForeachNamedElements(IEnumerable<(int Index, string Data)> input) { - foreach (var item3 in input) { - int item = item3.Index; - string item2 = item3.Data; - Console.WriteLine($"{item}: {item2}"); + foreach (var item in input) { + Console.WriteLine($"{item.Index}: {item.Data}"); } } + + public void NonGenericForeach(IEnumerable input) + { + foreach ((string, int) item in input) { + Console.WriteLine($"{item.Item1}: {item.Item2}"); + } + } + + public void CallForeach() + { + Foreach(new List<(int, string)> { + (1, "a"), + (2, "b") + }); + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.opt.roslyn.il index aef3e97c4..04a84f86f 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.opt.roslyn.il @@ -492,50 +492,47 @@ .method public hidebysig instance void Foreach(class [mscorlib]System.Collections.Generic.IEnumerable`1> input) cil managed { - // Code size 71 (0x47) + // Code size 69 (0x45) .maxstack 3 .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1> V_0, - int32 V_1, - string V_2) + valuetype [mscorlib]System.ValueTuple`2 V_1) IL_0000: ldarg.1 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_0032 + IL_0007: br.s IL_0030 IL_0009: ldloc.0 IL_000a: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1>::get_Current() - IL_000f: dup - IL_0010: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 - IL_0015: stloc.1 - IL_0016: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 - IL_001b: stloc.2 - IL_001c: ldstr "{0}: {1}" - IL_0021: ldloc.1 - IL_0022: box [mscorlib]System.Int32 - IL_0027: ldloc.2 - IL_0028: call string [mscorlib]System.String::Format(string, + IL_000f: stloc.1 + IL_0010: ldstr "{0}: {1}" + IL_0015: ldloc.1 + IL_0016: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_001b: box [mscorlib]System.Int32 + IL_0020: ldloc.1 + IL_0021: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0026: call string [mscorlib]System.String::Format(string, object, object) - IL_002d: call void [mscorlib]System.Console::WriteLine(string) - IL_0032: ldloc.0 - IL_0033: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0038: brtrue.s IL_0009 + IL_002b: call void [mscorlib]System.Console::WriteLine(string) + IL_0030: ldloc.0 + IL_0031: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0036: brtrue.s IL_0009 - IL_003a: leave.s IL_0046 + IL_0038: leave.s IL_0044 } // end .try finally { - IL_003c: ldloc.0 - IL_003d: brfalse.s IL_0045 + IL_003a: ldloc.0 + IL_003b: brfalse.s IL_0043 - IL_003f: ldloc.0 - IL_0040: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0045: endfinally + IL_003d: ldloc.0 + IL_003e: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0043: endfinally } // end handler - IL_0046: ret + IL_0044: ret } // end of method TupleTests::Foreach .method public hidebysig instance void @@ -544,52 +541,123 @@ .param [1] .custom instance void [mscorlib]System.Runtime.CompilerServices.TupleElementNamesAttribute::.ctor(string[]) = ( 01 00 02 00 00 00 05 49 6E 64 65 78 04 44 61 74 // .......Index.Dat 61 00 00 ) // a.. - // Code size 71 (0x47) + // Code size 69 (0x45) .maxstack 3 .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1> V_0, - int32 V_1, - string V_2) + valuetype [mscorlib]System.ValueTuple`2 V_1) IL_0000: ldarg.1 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_0032 + IL_0007: br.s IL_0030 IL_0009: ldloc.0 IL_000a: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1>::get_Current() - IL_000f: dup - IL_0010: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 - IL_0015: stloc.1 - IL_0016: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 - IL_001b: stloc.2 - IL_001c: ldstr "{0}: {1}" - IL_0021: ldloc.1 - IL_0022: box [mscorlib]System.Int32 - IL_0027: ldloc.2 - IL_0028: call string [mscorlib]System.String::Format(string, + IL_000f: stloc.1 + IL_0010: ldstr "{0}: {1}" + IL_0015: ldloc.1 + IL_0016: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_001b: box [mscorlib]System.Int32 + IL_0020: ldloc.1 + IL_0021: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0026: call string [mscorlib]System.String::Format(string, object, object) - IL_002d: call void [mscorlib]System.Console::WriteLine(string) - IL_0032: ldloc.0 - IL_0033: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0038: brtrue.s IL_0009 + IL_002b: call void [mscorlib]System.Console::WriteLine(string) + IL_0030: ldloc.0 + IL_0031: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0036: brtrue.s IL_0009 - IL_003a: leave.s IL_0046 + IL_0038: leave.s IL_0044 } // end .try finally { - IL_003c: ldloc.0 - IL_003d: brfalse.s IL_0045 + IL_003a: ldloc.0 + IL_003b: brfalse.s IL_0043 - IL_003f: ldloc.0 - IL_0040: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0045: endfinally + IL_003d: ldloc.0 + IL_003e: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0043: endfinally } // end handler - IL_0046: ret + IL_0044: ret } // end of method TupleTests::ForeachNamedElements + .method public hidebysig instance void + NonGenericForeach(class [mscorlib]System.Collections.IEnumerable input) cil managed + { + // Code size 81 (0x51) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.IEnumerator V_0, + valuetype [mscorlib]System.ValueTuple`2 V_1, + class [mscorlib]System.IDisposable V_2) + IL_0000: ldarg.1 + IL_0001: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0006: stloc.0 + .try + { + IL_0007: br.s IL_0035 + + IL_0009: ldloc.0 + IL_000a: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_000f: unbox.any valuetype [mscorlib]System.ValueTuple`2 + IL_0014: stloc.1 + IL_0015: ldstr "{0}: {1}" + IL_001a: ldloc.1 + IL_001b: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_0020: ldloc.1 + IL_0021: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0026: box [mscorlib]System.Int32 + IL_002b: call string [mscorlib]System.String::Format(string, + object, + object) + IL_0030: call void [mscorlib]System.Console::WriteLine(string) + IL_0035: ldloc.0 + IL_0036: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_003b: brtrue.s IL_0009 + + IL_003d: leave.s IL_0050 + + } // end .try + finally + { + IL_003f: ldloc.0 + IL_0040: isinst [mscorlib]System.IDisposable + IL_0045: stloc.2 + IL_0046: ldloc.2 + IL_0047: brfalse.s IL_004f + + IL_0049: ldloc.2 + IL_004a: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_004f: endfinally + } // end handler + IL_0050: ret + } // end of method TupleTests::NonGenericForeach + + .method public hidebysig instance void + CallForeach() cil managed + { + // Code size 46 (0x2e) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1>::.ctor() + IL_0006: dup + IL_0007: ldc.i4.1 + IL_0008: ldstr "a" + IL_000d: newobj instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0, + !1) + IL_0012: callvirt instance void class [mscorlib]System.Collections.Generic.List`1>::Add(!0) + IL_0017: dup + IL_0018: ldc.i4.2 + IL_0019: ldstr "b" + IL_001e: newobj instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0, + !1) + IL_0023: callvirt instance void class [mscorlib]System.Collections.Generic.List`1>::Add(!0) + IL_0028: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.TupleTests::Foreach(class [mscorlib]System.Collections.Generic.IEnumerable`1>) + IL_002d: ret + } // end of method TupleTests::CallForeach + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.roslyn.il index 2d3494916..a45f1c60b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.roslyn.il @@ -517,12 +517,10 @@ .method public hidebysig instance void Foreach(class [mscorlib]System.Collections.Generic.IEnumerable`1> input) cil managed { - // Code size 79 (0x4f) + // Code size 75 (0x4b) .maxstack 3 .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1> V_0, - valuetype [mscorlib]System.ValueTuple`2 V_1, - int32 V_2, - string V_3) + valuetype [mscorlib]System.ValueTuple`2 V_1) IL_0000: nop IL_0001: nop IL_0002: ldarg.1 @@ -530,46 +528,42 @@ IL_0008: stloc.0 .try { - IL_0009: br.s IL_0039 + IL_0009: br.s IL_0035 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: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 - IL_0020: stloc.3 - IL_0021: ldstr "{0}: {1}" - IL_0026: ldloc.2 - IL_0027: box [mscorlib]System.Int32 - IL_002c: ldloc.3 - IL_002d: call string [mscorlib]System.String::Format(string, + IL_0013: ldstr "{0}: {1}" + IL_0018: ldloc.1 + IL_0019: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_001e: box [mscorlib]System.Int32 + IL_0023: ldloc.1 + IL_0024: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0029: call string [mscorlib]System.String::Format(string, object, object) - IL_0032: call void [mscorlib]System.Console::WriteLine(string) - IL_0037: nop - IL_0038: nop - IL_0039: ldloc.0 - IL_003a: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_003f: brtrue.s IL_000b + IL_002e: call void [mscorlib]System.Console::WriteLine(string) + IL_0033: nop + IL_0034: nop + IL_0035: ldloc.0 + IL_0036: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_003b: brtrue.s IL_000b - IL_0041: leave.s IL_004e + IL_003d: leave.s IL_004a } // end .try finally { - IL_0043: ldloc.0 - IL_0044: brfalse.s IL_004d + IL_003f: ldloc.0 + IL_0040: brfalse.s IL_0049 - IL_0046: ldloc.0 - IL_0047: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_004c: nop - IL_004d: endfinally + IL_0042: ldloc.0 + IL_0043: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0048: nop + IL_0049: endfinally } // end handler - IL_004e: ret + IL_004a: ret } // end of method TupleTests::Foreach .method public hidebysig instance void @@ -578,12 +572,10 @@ .param [1] .custom instance void [mscorlib]System.Runtime.CompilerServices.TupleElementNamesAttribute::.ctor(string[]) = ( 01 00 02 00 00 00 05 49 6E 64 65 78 04 44 61 74 // .......Index.Dat 61 00 00 ) // a.. - // Code size 79 (0x4f) + // Code size 75 (0x4b) .maxstack 3 .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1> V_0, - valuetype [mscorlib]System.ValueTuple`2 V_1, - int32 V_2, - string V_3) + valuetype [mscorlib]System.ValueTuple`2 V_1) IL_0000: nop IL_0001: nop IL_0002: ldarg.1 @@ -591,48 +583,128 @@ IL_0008: stloc.0 .try { - IL_0009: br.s IL_0039 + IL_0009: br.s IL_0035 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: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 - IL_0020: stloc.3 - IL_0021: ldstr "{0}: {1}" - IL_0026: ldloc.2 - IL_0027: box [mscorlib]System.Int32 - IL_002c: ldloc.3 - IL_002d: call string [mscorlib]System.String::Format(string, + IL_0013: ldstr "{0}: {1}" + IL_0018: ldloc.1 + IL_0019: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_001e: box [mscorlib]System.Int32 + IL_0023: ldloc.1 + IL_0024: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0029: call string [mscorlib]System.String::Format(string, object, object) - IL_0032: call void [mscorlib]System.Console::WriteLine(string) - IL_0037: nop - IL_0038: nop - IL_0039: ldloc.0 - IL_003a: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_003f: brtrue.s IL_000b + IL_002e: call void [mscorlib]System.Console::WriteLine(string) + IL_0033: nop + IL_0034: nop + IL_0035: ldloc.0 + IL_0036: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_003b: brtrue.s IL_000b - IL_0041: leave.s IL_004e + IL_003d: leave.s IL_004a } // end .try finally { - IL_0043: ldloc.0 - IL_0044: brfalse.s IL_004d + IL_003f: ldloc.0 + IL_0040: brfalse.s IL_0049 - IL_0046: ldloc.0 - IL_0047: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_004c: nop - IL_004d: endfinally + IL_0042: ldloc.0 + IL_0043: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0048: nop + IL_0049: endfinally } // end handler - IL_004e: ret + IL_004a: ret } // end of method TupleTests::ForeachNamedElements + .method public hidebysig instance void + NonGenericForeach(class [mscorlib]System.Collections.IEnumerable input) cil managed + { + // Code size 87 (0x57) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.IEnumerator V_0, + valuetype [mscorlib]System.ValueTuple`2 V_1, + class [mscorlib]System.IDisposable V_2) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.1 + IL_0003: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_0008: stloc.0 + .try + { + IL_0009: br.s IL_003a + + IL_000b: ldloc.0 + IL_000c: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() + IL_0011: unbox.any valuetype [mscorlib]System.ValueTuple`2 + IL_0016: stloc.1 + IL_0017: nop + IL_0018: ldstr "{0}: {1}" + IL_001d: ldloc.1 + IL_001e: ldfld !0 valuetype [mscorlib]System.ValueTuple`2::Item1 + IL_0023: ldloc.1 + IL_0024: ldfld !1 valuetype [mscorlib]System.ValueTuple`2::Item2 + IL_0029: box [mscorlib]System.Int32 + IL_002e: call string [mscorlib]System.String::Format(string, + object, + object) + IL_0033: call void [mscorlib]System.Console::WriteLine(string) + IL_0038: nop + IL_0039: nop + IL_003a: ldloc.0 + IL_003b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0040: brtrue.s IL_000b + + IL_0042: leave.s IL_0056 + + } // end .try + finally + { + IL_0044: ldloc.0 + IL_0045: isinst [mscorlib]System.IDisposable + IL_004a: stloc.2 + IL_004b: ldloc.2 + IL_004c: brfalse.s IL_0055 + + IL_004e: ldloc.2 + IL_004f: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0054: nop + IL_0055: endfinally + } // end handler + IL_0056: ret + } // end of method TupleTests::NonGenericForeach + + .method public hidebysig instance void + CallForeach() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: newobj instance void class [mscorlib]System.Collections.Generic.List`1>::.ctor() + IL_0007: dup + IL_0008: ldc.i4.1 + IL_0009: ldstr "a" + IL_000e: newobj instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0, + !1) + IL_0013: callvirt instance void class [mscorlib]System.Collections.Generic.List`1>::Add(!0) + IL_0018: nop + IL_0019: dup + IL_001a: ldc.i4.2 + IL_001b: ldstr "b" + IL_0020: newobj instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0, + !1) + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1>::Add(!0) + IL_002a: nop + IL_002b: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.TupleTests::Foreach(class [mscorlib]System.Collections.Generic.IEnumerable`1>) + IL_0030: nop + IL_0031: ret + } // end of method TupleTests::CallForeach + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 76d924be0..a7f28dddb 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -359,7 +359,6 @@ - diff --git a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs index ce148131c..a4366ce4c 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs @@ -36,7 +36,8 @@ namespace ICSharpCode.Decompiler.TypeSystem ICompilation compilation, SRM.CustomAttributeHandleCollection? attributes, SRM.MetadataReader metadata, - TypeSystemOptions options) + TypeSystemOptions options, + bool typeChildrenOnly = false) { if ((options & (TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple)) == TypeSystemOptions.None) { return inputType; @@ -73,9 +74,14 @@ namespace ICSharpCode.Decompiler.TypeSystem } } if (hasDynamicAttribute || useTupleTypes) { - return inputType.AcceptVisitor(new ApplyAttributeTypeVisitor( + var visitor = new ApplyAttributeTypeVisitor( compilation, hasDynamicAttribute, dynamicAttributeData, useTupleTypes, tupleElementNames - )); + ); + if (typeChildrenOnly) { + return inputType.VisitChildren(visitor); + } else { + return inputType.AcceptVisitor(visitor); + } } else { return inputType; } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs index 7aad3675e..624f1e0fc 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs @@ -34,7 +34,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation readonly GenericParameterAttributes attr; // lazy-loaded: - IReadOnlyList customAttributes; IReadOnlyList constraints; public static ITypeParameter[] Create(MetadataAssembly assembly, ITypeDefinition copyFromOuter, IEntity owner, GenericParameterHandleCollection handles) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs deleted file mode 100644 index 16d2941d6..000000000 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2018 Daniel Grunwald -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using SRM = System.Reflection.Metadata; -using System.Diagnostics; -using System; -using ICSharpCode.Decompiler.Util; -using System.Linq; -using System.Collections.Immutable; - -namespace ICSharpCode.Decompiler.TypeSystem.Implementation -{ - sealed class MetadataTypeReference : ITypeReference - { - readonly SRM.EntityHandle type; - readonly SRM.MetadataReader metadata; - readonly SRM.CustomAttributeHandleCollection? typeAttributes; - readonly TypeSystemOptions options; - - public MetadataTypeReference(SRM.EntityHandle type, - SRM.MetadataReader metadata, - SRM.CustomAttributeHandleCollection? typeAttributes, - TypeSystemOptions options) - { - this.type = type; - this.metadata = metadata; - this.typeAttributes = typeAttributes; - this.options = options; - } - - public IType Resolve(ITypeResolveContext context) - { - return Resolve(type, metadata, - new TypeProvider(context.CurrentAssembly), - new GenericContext(context), - options, typeAttributes); - } - - public static IType Resolve(SRM.EntityHandle type, - SRM.MetadataReader metadata, - TypeProvider typeProvider, - GenericContext genericContext, - TypeSystemOptions options, - SRM.CustomAttributeHandleCollection? typeAttributes = null) - { - if (type.IsNil) - return SpecialType.UnknownType; - IType ty; - switch (type.Kind) { - case SRM.HandleKind.TypeDefinition: - ty = typeProvider.GetTypeFromDefinition(metadata, (SRM.TypeDefinitionHandle)type, 0); - break; - case SRM.HandleKind.TypeReference: - ty = typeProvider.GetTypeFromReference(metadata, (SRM.TypeReferenceHandle)type, 0); - break; - case SRM.HandleKind.TypeSpecification: - var typeSpec = metadata.GetTypeSpecification((SRM.TypeSpecificationHandle)type); - ty = typeSpec.DecodeSignature(typeProvider, genericContext); - break; - default: - Debug.Fail("Not a type handle"); - ty = SpecialType.UnknownType; - break; - } - ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, typeProvider.Compilation, - typeAttributes, metadata, options); - return ty; - } - } - - sealed class FieldTypeReference : ITypeReference - { - readonly SRM.EntityHandle fieldHandle; - readonly SRM.MetadataReader metadata; - readonly TypeSystemOptions options; - - public FieldTypeReference(SRM.FieldDefinitionHandle fieldHandle, - SRM.MetadataReader metadata, - TypeSystemOptions options) - { - this.fieldHandle = fieldHandle; - this.metadata = metadata; - this.options = options; - } - - public FieldTypeReference(SRM.MemberReferenceHandle fieldReferenceHandle, - SRM.MetadataReader metadata, - TypeSystemOptions attributeOptions) - { - this.fieldHandle = fieldReferenceHandle; - this.metadata = metadata; - this.options = attributeOptions; - } - - IType ITypeReference.Resolve(ITypeResolveContext context) - { - if (fieldHandle.Kind == SRM.HandleKind.FieldDefinition) { - return Resolve((SRM.FieldDefinitionHandle)fieldHandle, metadata, context, options); - } else { - var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)fieldHandle); - IType ty = memberRef.DecodeFieldSignature(new TypeProvider(context.CurrentAssembly), new GenericContext(context)); - ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation, - memberRef.GetCustomAttributes(), metadata, options); - return ty; - } - } - - public static IType Resolve(SRM.FieldDefinitionHandle fieldHandle, - SRM.MetadataReader metadata, - ITypeResolveContext context, - TypeSystemOptions options) - { - var fieldDef = metadata.GetFieldDefinition(fieldHandle); - IType ty = fieldDef.DecodeSignature(new TypeProvider(context.CurrentAssembly), new GenericContext(context)); - ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation, - fieldDef.GetCustomAttributes(), metadata, options); - return ty; - } - } - - /// - /// Represents an unresolved method signature. - /// - sealed class UnresolvedMethodSignature - { - readonly SRM.EntityHandle handle; - readonly SRM.MetadataReader metadata; - readonly TypeSystemOptions options; - - public UnresolvedMethodSignature(SRM.MethodDefinitionHandle handle, SRM.MetadataReader metadata, - TypeSystemOptions options) - { - this.handle = handle; - this.metadata = metadata; - this.options = options; - } - - public UnresolvedMethodSignature(SRM.PropertyDefinitionHandle handle, SRM.MetadataReader metadata, - TypeSystemOptions attributeOptions) - { - this.handle = handle; - this.metadata = metadata; - this.options = attributeOptions; - } - - public SRM.MethodSignature Resolve(ITypeResolveContext context) - { - return (SRM.MethodSignature)context.Compilation.CacheManager.GetOrAddShared( - this, key => { - Debug.Assert(key == this); - switch (handle.Kind) { - case SRM.HandleKind.MethodDefinition: - return GetSignature( - metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)handle), - metadata, context, options - ); - case SRM.HandleKind.PropertyDefinition: - return GetSignature( - metadata.GetPropertyDefinition((SRM.PropertyDefinitionHandle)handle), - metadata, context, options - ); - default: - throw new InvalidOperationException(); - } - } - ); - } - - public static SRM.MethodSignature GetSignature(SRM.MethodDefinition methodDef, - SRM.MetadataReader metadata, ITypeResolveContext context, - TypeSystemOptions options) - { - var typeProvider = new TypeProvider(context.CurrentAssembly); - var signature = methodDef.DecodeSignature(typeProvider, new GenericContext(context)); - return ApplyAttributes(signature, methodDef.GetParameters(), context.Compilation, metadata, options); - } - - public static SRM.MethodSignature GetSignature(SRM.PropertyDefinition propertyDef, - SRM.MetadataReader metadata, ITypeResolveContext context, - TypeSystemOptions options) - { - var typeProvider = new TypeProvider(context.CurrentAssembly); - var signature = propertyDef.DecodeSignature(typeProvider, new GenericContext(context)); - var accessors = propertyDef.GetAccessors(); - SRM.ParameterHandleCollection? parameterHandles = null; - if (!accessors.Getter.IsNil) { - var getter = metadata.GetMethodDefinition(accessors.Getter); - parameterHandles = getter.GetParameters(); - } else { - if (!accessors.Setter.IsNil) { - var setter = metadata.GetMethodDefinition(accessors.Setter); - parameterHandles = setter.GetParameters(); - } - } - return ApplyAttributes(signature, parameterHandles, context.Compilation, metadata, options); - } - - static SRM.MethodSignature ApplyAttributes(SRM.MethodSignature signature, SRM.ParameterHandleCollection? parameterHandles, ICompilation compilation, SRM.MetadataReader metadata, TypeSystemOptions options) - { - SRM.CustomAttributeHandleCollection? returnTypeAttributes = null; - var parameterAttributes = new SRM.CustomAttributeHandleCollection?[signature.ParameterTypes.Length]; - if (parameterHandles != null) { - foreach (var parameterHandle in parameterHandles) { - var par = metadata.GetParameter(parameterHandle); - if (par.SequenceNumber == 0) { - returnTypeAttributes = par.GetCustomAttributes(); - } else if (par.SequenceNumber <= parameterAttributes.Length) { - parameterAttributes[par.SequenceNumber - 1] = par.GetCustomAttributes(); - } - } - } - IType returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType( - signature.ReturnType, compilation, returnTypeAttributes, metadata, options - ); - var parameterTypes = signature.ParameterTypes.SelectWithIndex( - (i, p) => ApplyAttributeTypeVisitor.ApplyAttributesToType( - p, compilation, parameterAttributes[i], metadata, options - ) - ).ToImmutableArray(); - return new SRM.MethodSignature( - signature.Header, returnType, - signature.RequiredParameterCount, signature.GenericParameterCount, - parameterTypes - ); - } - } - - sealed class SignatureParameterTypeReference : ITypeReference - { - readonly UnresolvedMethodSignature unresolvedSig; - readonly int index; - - public SignatureParameterTypeReference(UnresolvedMethodSignature unresolvedSig, int index) - { - this.unresolvedSig = unresolvedSig; - this.index = index; - } - - public IType Resolve(ITypeResolveContext context) - { - var sig = unresolvedSig.Resolve(context); - if (index < sig.ParameterTypes.Length) - return sig.ParameterTypes[index]; - else - return SpecialType.UnknownType; - } - } - - sealed class SignatureReturnTypeReference : ITypeReference - { - readonly UnresolvedMethodSignature unresolvedSig; - - public SignatureReturnTypeReference(UnresolvedMethodSignature unresolvedSig) - { - this.unresolvedSig = unresolvedSig; - } - - public IType Resolve(ITypeResolveContext context) - { - return unresolvedSig.Resolve(context).ReturnType; - } - } -} diff --git a/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs b/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs index fc38f4655..e8ff651a9 100644 --- a/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs +++ b/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs @@ -237,17 +237,39 @@ namespace ICSharpCode.Decompiler.TypeSystem public IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, TypeSystemOptions customOptions, CustomAttributeHandleCollection? typeAttributes = null) { - if (typeRefDefSpec.Kind == HandleKind.ExportedType) { - return ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec)); + if (typeRefDefSpec.IsNil) + return SpecialType.UnknownType; + IType ty; + switch (typeRefDefSpec.Kind) { + case HandleKind.TypeDefinition: + ty = TypeProvider.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)typeRefDefSpec, 0); + break; + case HandleKind.TypeReference: + ty = TypeProvider.GetTypeFromReference(metadata, (TypeReferenceHandle)typeRefDefSpec, 0); + break; + case HandleKind.TypeSpecification: + var typeSpec = metadata.GetTypeSpecification((TypeSpecificationHandle)typeRefDefSpec); + ty = typeSpec.DecodeSignature(TypeProvider, context); + break; + case HandleKind.ExportedType: + return ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec)); + default: + Debug.Fail("Not a type handle"); + ty = SpecialType.UnknownType; + break; } - return MetadataTypeReference.Resolve(typeRefDefSpec, metadata, TypeProvider, context, customOptions, typeAttributes); + ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, typeAttributes, metadata, customOptions); + return ty; } IType ResolveDeclaringType(EntityHandle declaringTypeReference, GenericContext context) { // resolve without substituting dynamic/tuple types - return ResolveType(declaringTypeReference, context, + var ty = ResolveType(declaringTypeReference, context, options & ~(TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple)); + // but substitute tuple types in type arguments: + ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, typeChildrenOnly: true); + return ty; } #endregion