From 7c5ded93f0998bbd08f3cea278d626114ef82736 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 6 Oct 2017 08:25:00 +0200 Subject: [PATCH 01/84] Move F# Tests to ILPrettyTestRunner --- .../FSharpPatterns/FSharpPatternTests.cs | 30 ------ .../FSharpPatterns/TestHelpers.cs | 87 ---------------- .../FSharpPatterns/ToolLocator.cs | 99 ------------------- .../ICSharpCode.Decompiler.Tests.csproj | 5 + .../ILPretty}/FSharpUsing.fs | 0 .../ILPretty/FSharpUsing_Debug.cs} | 0 .../ILPretty/FSharpUsing_Debug.il} | 0 .../ILPretty/FSharpUsing_Release.cs} | 0 .../ILPretty/FSharpUsing_Release.il} | 0 9 files changed, 5 insertions(+), 216 deletions(-) delete mode 100644 ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpPatternTests.cs delete mode 100644 ICSharpCode.Decompiler.Tests/FSharpPatterns/TestHelpers.cs delete mode 100644 ICSharpCode.Decompiler.Tests/FSharpPatterns/ToolLocator.cs rename ICSharpCode.Decompiler.Tests/{FSharpPatterns => TestCases/ILPretty}/FSharpUsing.fs (100%) rename ICSharpCode.Decompiler.Tests/{FSharpPatterns/FSharpUsing.fs.Debug.cs => TestCases/ILPretty/FSharpUsing_Debug.cs} (100%) rename ICSharpCode.Decompiler.Tests/{FSharpPatterns/FSharpUsing.fs.Debug.il => TestCases/ILPretty/FSharpUsing_Debug.il} (100%) rename ICSharpCode.Decompiler.Tests/{FSharpPatterns/FSharpUsing.fs.Release.cs => TestCases/ILPretty/FSharpUsing_Release.cs} (100%) rename ICSharpCode.Decompiler.Tests/{FSharpPatterns/FSharpUsing.fs.Release.il => TestCases/ILPretty/FSharpUsing_Release.il} (100%) diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpPatternTests.cs b/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpPatternTests.cs deleted file mode 100644 index 7980d6579..000000000 --- a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpPatternTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace ICSharpCode.Decompiler.Tests.FSharpPatterns -{ - [TestFixture] - public class FSharpPatternTests - { - [Test] - public void FSharpUsingDecompilesToCSharpUsing_Debug() - { - var ilCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Debug.il"); - var csharpCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Debug.cs"); - TestHelpers.RunIL(ilCode, csharpCode); - } - - [Test] - public void FSharpUsingDecompilesToCSharpUsing_Release() - { - var ilCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Release.il"); - var csharpCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Release.cs"); - TestHelpers.RunIL(ilCode, csharpCode); - } - } -} diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/TestHelpers.cs b/ICSharpCode.Decompiler.Tests/FSharpPatterns/TestHelpers.cs deleted file mode 100644 index dc6cd0bc4..000000000 --- a/ICSharpCode.Decompiler.Tests/FSharpPatterns/TestHelpers.cs +++ /dev/null @@ -1,87 +0,0 @@ -using ICSharpCode.Decompiler.Ast; -using ICSharpCode.Decompiler.Tests.Helpers; -using ICSharpCode.NRefactory.CSharp; -using Mono.Cecil; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace ICSharpCode.Decompiler.Tests.FSharpPatterns -{ - public class TestHelpers - { - public static string FuzzyReadResource(string resourceName) - { - var asm = Assembly.GetExecutingAssembly(); - var allResources = asm.GetManifestResourceNames(); - var fullResourceName = allResources.Single(r => r.EndsWith(resourceName, StringComparison.OrdinalIgnoreCase)); - return new StreamReader(asm.GetManifestResourceStream(fullResourceName)).ReadToEnd(); - } - - static Lazy ilasm = new Lazy(() => ToolLocator.FindTool("ilasm.exe")); - static Lazy ildasm = new Lazy(() => ToolLocator.FindTool("ildasm.exe")); - - public static string CompileIL(string source) - { - if (ilasm.Value == null) - Assert.NotNull(ilasm.Value, "Could not find ILASM.exe"); - var tmp = Path.GetTempFileName(); - File.Delete(tmp); - var sourceFile = Path.ChangeExtension(tmp, ".il"); - File.WriteAllText(sourceFile, source); - var asmFile = Path.ChangeExtension(sourceFile, ".dll"); - - var args = string.Format("{0} /dll /debug /output:{1}", sourceFile, asmFile); - using (var proc = Process.Start(new ProcessStartInfo(ilasm.Value, args) { UseShellExecute = false, })) - { - proc.WaitForExit(); - Assert.AreEqual(0, proc.ExitCode); - } - - File.Delete(sourceFile); - Assert.True(File.Exists(asmFile), "Assembly File does not exist"); - return asmFile; - } - - public static void RunIL(string ilCode, string expectedCSharpCode) - { - var asmFilePath = CompileIL(ilCode); - CompareAssemblyAgainstCSharp(expectedCSharpCode, asmFilePath); - } - - private static void CompareAssemblyAgainstCSharp(string expectedCSharpCode, string asmFilePath) - { - var module = ModuleDefinition.ReadModule(asmFilePath); - try - { - try { module.ReadSymbols(); } catch { } - AstBuilder decompiler = new AstBuilder(new DecompilerContext(module)); - decompiler.AddAssembly(module); - new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); - StringWriter output = new StringWriter(); - - // the F# assembly contains a namespace `` where the part after tmp is randomly generated. - // remove this from the ast to simplify the diff - var startupCodeNode = decompiler.SyntaxTree.Children.OfType().SingleOrDefault(d => d.Name.StartsWith(" Path.Combine(dir, fileName)).FirstOrDefault(File.Exists); - } - - private static IEnumerable FindPathForWindowsSdk() - { - string[] windowsSdkPaths = new[] - { - @"Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\", - @"Microsoft SDKs\Windows\v8.0A\bin\", - @"Microsoft SDKs\Windows\v8.0\bin\NETFX 4.0 Tools\", - @"Microsoft SDKs\Windows\v8.0\bin\", - @"Microsoft SDKs\Windows\v7.1A\bin\NETFX 4.0 Tools\", - @"Microsoft SDKs\Windows\v7.1A\bin\", - @"Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\", - @"Microsoft SDKs\Windows\v7.0A\bin\", - @"Microsoft SDKs\Windows\v6.1A\bin\", - @"Microsoft SDKs\Windows\v6.0A\bin\", - @"Microsoft SDKs\Windows\v6.0\bin\", - @"Microsoft.NET\FrameworkSDK\bin" - }; - - foreach (var possiblePath in windowsSdkPaths) - { - string fullPath = string.Empty; - - // Check alternate program file paths as well as 64-bit versions. - if (Environment.Is64BitProcess) - { - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath, "x64"); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath, "x64"); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - } - - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - } - } - - private static IEnumerable FindPathForDotNetFramework() - { - string[] frameworkPaths = new[] - { - @"Microsoft.NET\Framework\v4.0.30319", - @"Microsoft.NET\Framework\v2.0.50727" - }; - - foreach (var possiblePath in frameworkPaths) - { - string fullPath = string.Empty; - - if (Environment.Is64BitProcess) - { - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath.Replace(@"\Framework\", @"\Framework64\")); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - } - - fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath); - if (Directory.Exists(fullPath)) - { - yield return fullPath; - } - } - } - } -} diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index a46ed0bcf..eec8a43b6 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -44,12 +44,17 @@ + + + + + diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing.fs similarity index 100% rename from ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs rename to ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing.fs diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Debug.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs similarity index 100% rename from ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Debug.cs rename to ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Debug.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.il similarity index 100% rename from ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Debug.il rename to ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.il diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Release.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs similarity index 100% rename from ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Release.cs rename to ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs diff --git a/ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Release.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.il similarity index 100% rename from ICSharpCode.Decompiler.Tests/FSharpPatterns/FSharpUsing.fs.Release.il rename to ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.il From 2d2ca893e9d89ce016f63e8bba6ba9cb5958d6da Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 6 Oct 2017 09:13:52 +0200 Subject: [PATCH 02/84] ConditionDetection: Remove empty else-branches. --- .../ICSharpCode.Decompiler.csproj | 1 + .../IL/ControlFlow/ConditionDetection.cs | 17 ++++++++++++---- .../Instructions/ILInstructionExtensions.cs | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 581380e6d..b9320c5b4 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -271,6 +271,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index 268b9a429..d93a5b58a 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -176,10 +176,19 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow if (DetectExitPoints.CompatibleExitInstruction(trueExitInst, falseExitInst)) { // if (...) { ...; goto exitPoint; } goto nextBlock; nextBlock: ...; goto exitPoint; // -> if (...) { ... } else { ... } goto exitPoint; - context.Step("Inline block as else-branch", ifInst); - targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); - targetBlock.Remove(); - ifInst.FalseInst = targetBlock; + + // the else block is not empty or nop-only: + if (!targetBlock.IsNopBlock(ignoreExitPoint: falseExitInst)) { + context.Step("Inline block as else-branch", ifInst); + targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); + targetBlock.Remove(); + ifInst.FalseInst = targetBlock; + } else { + // the else block is empty or nop-only and can be safely removed: + context.Step("Remove empty else-branch", ifInst); + targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); + targetBlock.Remove(); + } exitInst = block.Instructions[block.Instructions.Count - 1] = falseExitInst; Block trueBlock = ifInst.TrueInst as Block; if (trueBlock != null) { diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs new file mode 100644 index 000000000..c363dd1de --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.Decompiler.IL +{ + public static class ILInstructionExtensions + { + /// + /// Determines whether a block only consists of nop instructions or is empty. + /// + public static bool IsNopBlock(this Block block, ILInstruction ignoreExitPoint = null) + { + if (block == null) + throw new ArgumentNullException(nameof(block)); + return block.Children.Count(i => !(i is Nop) && i != ignoreExitPoint) == 0; + } + } +} From aa0e37923657456e83474215b00653195f744c80 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 6 Oct 2017 13:33:46 +0200 Subject: [PATCH 03/84] Add tests to ILPrettyTestRunner --- .../ILPrettyTestRunner.cs | 12 +++++++ .../TestCases/ILPretty/FSharpUsing_Debug.cs | 32 ++++++++----------- .../TestCases/ILPretty/FSharpUsing_Release.cs | 32 ++++++++----------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 7d2f9ed47..97f7fa0e4 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -42,6 +42,18 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test] + public void FSharpUsing_Debug() + { + Run(); + } + + [Test] + public void FSharpUsing_Release() + { + Run(); + } + void Run([CallerMemberName] string testName = null) { var ilFile = Path.Combine(TestCasePath, testName + ".il"); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs index 3c62c0cac..d9ca8bff4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs @@ -5,18 +5,16 @@ public static class FSharpUsingPatterns { public static void sample1() { - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte((byte)1); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte((byte)1); } } public static void sample2() { Console.WriteLine("some text"); - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte((byte)2); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte((byte)2); Console.WriteLine("some text"); } } @@ -24,9 +22,8 @@ public static class FSharpUsingPatterns public static void sample3() { Console.WriteLine("some text"); - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte((byte)3); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte((byte)3); } Console.WriteLine("some text"); } @@ -35,9 +32,8 @@ public static class FSharpUsingPatterns { Console.WriteLine("some text"); int num; - using (FileStream fs = File.OpenRead("x.txt")) - { - num = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + num = fileStream.ReadByte(); } int firstByte = num; Console.WriteLine("read:" + firstByte.ToString()); @@ -47,16 +43,14 @@ public static class FSharpUsingPatterns { Console.WriteLine("some text"); int num; - using (FileStream fs = File.OpenRead("x.txt")) - { - num = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + num = fileStream.ReadByte(); } int firstByte = num; int num3; - using (FileStream fs = File.OpenRead("x.txt")) - { - int num2 = fs.ReadByte(); - num3 = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + int num2 = fileStream.ReadByte(); + num3 = fileStream.ReadByte(); } int secondByte = num3; Console.WriteLine("read: {0}, {1}", firstByte, secondByte); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs index c9d091847..6396bc6d5 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs @@ -5,18 +5,16 @@ public static class FSharpUsingPatterns { public static void sample1() { - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte(1); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte(1); } } public static void sample2() { Console.WriteLine("some text"); - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte(2); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte(2); Console.WriteLine("some text"); } } @@ -24,9 +22,8 @@ public static class FSharpUsingPatterns public static void sample3() { Console.WriteLine("some text"); - using (FileStream fs = File.Create("x.txt")) - { - fs.WriteByte(3); + using (FileStream fileStream = File.Create("x.txt")) { + fileStream.WriteByte(3); } Console.WriteLine("some text"); } @@ -35,9 +32,8 @@ public static class FSharpUsingPatterns { Console.WriteLine("some text"); int num; - using (FileStream fs = File.OpenRead("x.txt")) - { - num = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + num = fileStream.ReadByte(); } int firstByte = num; Console.WriteLine("read:" + firstByte.ToString()); @@ -47,16 +43,14 @@ public static class FSharpUsingPatterns { Console.WriteLine("some text"); int secondByte; - using (FileStream fs = File.OpenRead("x.txt")) - { - secondByte = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + secondByte = fileStream.ReadByte(); } int firstByte = secondByte; int num2; - using (FileStream fs = File.OpenRead("x.txt")) - { - int num = fs.ReadByte(); - num2 = fs.ReadByte(); + using (FileStream fileStream = File.OpenRead("x.txt")) { + int num = fileStream.ReadByte(); + num2 = fileStream.ReadByte(); } secondByte = num2; Console.WriteLine("read: {0}, {1}", firstByte, secondByte); From 25cdf7d16a0abb764b9496fe12c7371ce66e1ccb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 10:27:31 +0200 Subject: [PATCH 04/84] Add CSharpILMixedLanguage --- ILSpy/ILSpy.csproj | 1 + ILSpy/Languages/CSharpILMixedLanguage.cs | 26 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 ILSpy/Languages/CSharpILMixedLanguage.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index f61c643c4..db6d26eab 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -106,6 +106,7 @@ DebugSteps.xaml + diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs new file mode 100644 index 000000000..9be3e0092 --- /dev/null +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ICSharpCode.Decompiler; +using ICSharpCode.Decompiler.Disassembler; +using Mono.Cecil; + +namespace ICSharpCode.ILSpy +{ + [Export(typeof(Language))] + class CSharpILMixedLanguage : Language + { + private readonly bool detectControlStructure = true; + + public override string Name => "IL with C#"; + + public override string FileExtension => ".il"; + + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) + { + var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + dis.DisassembleMethod(method); + } + } +} From 4347fab625661926df360c84f3fc2354a2f3b616 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 12:13:04 +0200 Subject: [PATCH 05/84] Add SequencePointBuilder. --- .../CSharp/CSharpDecompiler.cs | 14 ++ .../CSharp/SequencePointBuilder.cs | 147 ++++++++++++++++++ .../ICSharpCode.Decompiler.csproj | 2 + ICSharpCode.Decompiler/IL/SequencePoint.cs | 26 ++++ 4 files changed, 189 insertions(+) create mode 100644 ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs create mode 100644 ICSharpCode.Decompiler/IL/SequencePoint.cs diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 801b95b7c..1bba92164 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL.ControlFlow; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.CSharp { @@ -982,6 +983,19 @@ namespace ICSharpCode.Decompiler.CSharp } #endregion + #region Sequence Points + /// + /// Creates sequence points for the given syntax tree. + /// + /// This only works correctly when the nodes in the syntax tree have line/column information. + /// + public Dictionary> CreateSequencePoints(SyntaxTree syntaxTree) + { + SequencePointBuilder spb = new SequencePointBuilder(); + syntaxTree.AcceptVisitor(spb); + return spb.GetSequencePoints(); + } + #endregion } [Flags] diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs new file mode 100644 index 000000000..eaf3367b7 --- /dev/null +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -0,0 +1,147 @@ +// Copyright (c) 2017 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 System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.Decompiler.CSharp.Syntax; +using ICSharpCode.Decompiler.IL; +using ICSharpCode.Decompiler.Util; + +namespace ICSharpCode.Decompiler.CSharp +{ + /// + /// Given a SyntaxTree that was output from the decompiler, constructs the list of sequence points. + /// + class SequencePointBuilder : DepthFirstAstVisitor + { + struct StatePerSequencePoint + { + internal readonly AstNode PrimaryNode; + internal readonly List Intervals; + internal ILFunction Function; + + public StatePerSequencePoint(AstNode primaryNode) + { + this.PrimaryNode = primaryNode; + this.Intervals = new List(); + this.Function = null; + } + } + + readonly List<(ILFunction, SequencePoint)> sequencePoints = new List<(ILFunction, SequencePoint)>(); + readonly HashSet mappedInstructions = new HashSet(); + readonly Stack outerStates = new Stack(); + StatePerSequencePoint current = new StatePerSequencePoint(); + + void VisitAsSequencePoint(AstNode node) + { + StartSequencePoint(node); + node.AcceptVisitor(this); + EndSequencePoint(node.StartLocation, node.EndLocation); + } + + protected override void VisitChildren(AstNode node) + { + base.VisitChildren(node); + AddToSequencePoint(node); + } + + public override void VisitBlockStatement(BlockStatement blockStatement) + { + foreach (var stmt in blockStatement.Statements) { + VisitAsSequencePoint(stmt); + } + } + + public override void VisitForStatement(ForStatement forStatement) + { + foreach (var init in forStatement.Initializers) { + VisitAsSequencePoint(init); + } + VisitAsSequencePoint(forStatement.Condition); + foreach (var inc in forStatement.Iterators) { + VisitAsSequencePoint(inc); + } + VisitAsSequencePoint(forStatement.EmbeddedStatement); + } + + /// + /// Start a new C# statement = new sequence point. + /// + void StartSequencePoint(AstNode primaryNode) + { + outerStates.Push(current); + current = new StatePerSequencePoint(primaryNode); + } + + void EndSequencePoint(TextLocation startLocation, TextLocation endLocation) + { + if (current.Intervals.Count > 0 && current.Function != null) { + sequencePoints.Add((current.Function, new SequencePoint { + Offset = current.Intervals.Select(i => i.Start).Min(), + StartLine = startLocation.Line, + StartColumn = startLocation.Column, + EndLine = endLocation.Line, + EndColumn = endLocation.Column + })); + } + current = outerStates.Pop(); + } + + void AddToSequencePoint(AstNode node) + { + foreach (var inst in node.Annotations.OfType()) { + AddToSequencePoint(inst); + } + } + + void AddToSequencePoint(ILInstruction inst) + { + if (!mappedInstructions.Add(inst)) { + // inst was already used by a nested sequence point within this sequence point + return; + } + // Add the IL range associated with this instruction to the current sequence point. + if (!inst.ILRange.IsEmpty) { + current.Intervals.Add(inst.ILRange); + current.Function = inst.Ancestors.OfType().FirstOrDefault(); + } + // Also add the child IL instructions, unless they were already processed by + // another C# expression. + foreach (var child in inst.Children) { + AddToSequencePoint(child); + } + } + + internal Dictionary> GetSequencePoints() + { + var dict = new Dictionary>(); + foreach (var (function, sequencePoint) in this.sequencePoints) { + if (!dict.TryGetValue(function, out var list)) { + dict.Add(function, list = new List()); + } + list.Add(sequencePoint); + } + foreach (var list in dict.Values) { + list.Sort((a, b) => a.Offset.CompareTo(b.Offset)); + } + return dict; + } + } +} diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index a1e17edfd..93e3c5389 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -60,6 +60,7 @@ + @@ -272,6 +273,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/SequencePoint.cs b/ICSharpCode.Decompiler/IL/SequencePoint.cs new file mode 100644 index 000000000..568953c35 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/SequencePoint.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.Decompiler.IL +{ + /// + /// A sequence point produced by the decompiler. + /// + public struct SequencePoint + { + /// + /// IL offset. + /// + public int Offset { get; set; } + + public int StartLine { get; set; } + public int StartColumn { get; set; } + public int EndLine { get; set; } + public int EndColumn { get; set; } + + public bool IsHidden { + get { return StartLine == 0xfeefee && StartLine == EndLine; } + } + } +} From 1eb8caa013b0a5cd471aed98f68215906d622f6d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 13:33:48 +0200 Subject: [PATCH 06/84] Move CSharpHighlightingTokenWriter to outer class --- ILSpy/ILSpy.csproj | 1 + .../CSharpHighlightingTokenWriter.cs | 429 ++++++++++++++++++ ILSpy/Languages/CSharpLanguage.cs | 420 +---------------- 3 files changed, 431 insertions(+), 419 deletions(-) create mode 100644 ILSpy/Languages/CSharpHighlightingTokenWriter.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index db6d26eab..ab3db44d7 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -116,6 +116,7 @@ + diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs new file mode 100644 index 000000000..633ac75e6 --- /dev/null +++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs @@ -0,0 +1,429 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.Decompiler.CSharp; +using ICSharpCode.Decompiler.CSharp.OutputVisitor; +using ICSharpCode.Decompiler.CSharp.Syntax; +using ICSharpCode.Decompiler.TypeSystem; + +namespace ICSharpCode.ILSpy +{ + class CSharpHighlightingTokenWriter : DecoratingTokenWriter + { + ISmartTextOutput textOutput; + + HighlightingColor visibilityKeywordsColor; + HighlightingColor namespaceKeywordsColor; + HighlightingColor structureKeywordsColor; + HighlightingColor gotoKeywordsColor; + HighlightingColor queryKeywordsColor; + HighlightingColor exceptionKeywordsColor; + HighlightingColor checkedKeywordColor; + HighlightingColor unsafeKeywordsColor; + HighlightingColor valueTypeKeywordsColor; + HighlightingColor referenceTypeKeywordsColor; + HighlightingColor operatorKeywordsColor; + HighlightingColor parameterModifierColor; + HighlightingColor modifiersColor; + HighlightingColor accessorKeywordsColor; + HighlightingColor attributeKeywordsColor; + + HighlightingColor referenceTypeColor; + HighlightingColor valueTypeColor; + HighlightingColor interfaceTypeColor; + HighlightingColor enumerationTypeColor; + HighlightingColor typeParameterTypeColor; + HighlightingColor delegateTypeColor; + + HighlightingColor methodCallColor; + HighlightingColor methodDeclarationColor; + + HighlightingColor fieldDeclarationColor; + HighlightingColor fieldAccessColor; + + HighlightingColor valueKeywordColor; + HighlightingColor thisKeywordColor; + HighlightingColor trueKeywordColor; + HighlightingColor typeKeywordsColor; + + public CSharpHighlightingTokenWriter(TokenWriter decoratedWriter, ISmartTextOutput textOutput) : base(decoratedWriter) + { + this.textOutput = textOutput; + var highlighting = HighlightingManager.Instance.GetDefinition("C#"); + + //this.defaultTextColor = ???; + + this.visibilityKeywordsColor = highlighting.GetNamedColor("Visibility"); + this.namespaceKeywordsColor = highlighting.GetNamedColor("NamespaceKeywords"); + this.structureKeywordsColor = highlighting.GetNamedColor("Keywords"); + this.gotoKeywordsColor = highlighting.GetNamedColor("GotoKeywords"); + this.queryKeywordsColor = highlighting.GetNamedColor("QueryKeywords"); + this.exceptionKeywordsColor = highlighting.GetNamedColor("ExceptionKeywords"); + this.checkedKeywordColor = highlighting.GetNamedColor("CheckedKeyword"); + this.unsafeKeywordsColor = highlighting.GetNamedColor("UnsafeKeywords"); + this.valueTypeKeywordsColor = highlighting.GetNamedColor("ValueTypeKeywords"); + this.referenceTypeKeywordsColor = highlighting.GetNamedColor("ReferenceTypeKeywords"); + this.operatorKeywordsColor = highlighting.GetNamedColor("OperatorKeywords"); + this.parameterModifierColor = highlighting.GetNamedColor("ParameterModifiers"); + this.modifiersColor = highlighting.GetNamedColor("Modifiers"); + this.accessorKeywordsColor = highlighting.GetNamedColor("GetSetAddRemove"); + + this.referenceTypeColor = highlighting.GetNamedColor("ReferenceTypes"); + this.valueTypeColor = highlighting.GetNamedColor("ValueTypes"); + this.interfaceTypeColor = highlighting.GetNamedColor("InterfaceTypes"); + this.enumerationTypeColor = highlighting.GetNamedColor("EnumTypes"); + this.typeParameterTypeColor = highlighting.GetNamedColor("TypeParameters"); + this.delegateTypeColor = highlighting.GetNamedColor("DelegateTypes"); + this.methodDeclarationColor = this.methodCallColor = highlighting.GetNamedColor("MethodCall"); + //this.eventDeclarationColor = this.eventAccessColor = defaultTextColor; + //this.propertyDeclarationColor = this.propertyAccessColor = defaultTextColor; + this.fieldDeclarationColor = this.fieldAccessColor = highlighting.GetNamedColor("FieldAccess"); + //this.variableDeclarationColor = this.variableAccessColor = defaultTextColor; + //this.parameterDeclarationColor = this.parameterAccessColor = defaultTextColor; + this.valueKeywordColor = highlighting.GetNamedColor("NullOrValueKeywords"); + this.thisKeywordColor = highlighting.GetNamedColor("ThisOrBaseReference"); + this.trueKeywordColor = highlighting.GetNamedColor("TrueFalse"); + this.typeKeywordsColor = highlighting.GetNamedColor("TypeKeywords"); + this.attributeKeywordsColor = highlighting.GetNamedColor("AttributeKeywords"); + //this.externAliasKeywordColor = ...; + } + + public override void WriteKeyword(Role role, string keyword) + { + HighlightingColor color = null; + switch (keyword) { + case "namespace": + case "using": + if (role == UsingStatement.UsingKeywordRole) + color = structureKeywordsColor; + else + color = namespaceKeywordsColor; + break; + case "this": + case "base": + color = thisKeywordColor; + break; + case "true": + case "false": + color = trueKeywordColor; + break; + case "public": + case "internal": + case "protected": + case "private": + color = visibilityKeywordsColor; + break; + case "if": + case "else": + case "switch": + case "case": + case "default": + case "while": + case "do": + case "for": + case "foreach": + case "lock": + case "global": + case "dynamic": + case "await": + case "where": + color = structureKeywordsColor; + break; + case "in": + if (nodeStack.PeekOrDefault() is ForeachStatement) + color = structureKeywordsColor; + else if (nodeStack.PeekOrDefault() is QueryClause) + color = queryKeywordsColor; + else + color = parameterModifierColor; + break; + case "as": + case "is": + case "new": + case "sizeof": + case "typeof": + case "nameof": + case "stackalloc": + color = typeKeywordsColor; + break; + case "try": + case "throw": + case "catch": + case "finally": + color = exceptionKeywordsColor; + break; + case "when": + if (role == CatchClause.WhenKeywordRole) + color = exceptionKeywordsColor; + break; + case "get": + case "set": + case "add": + case "remove": + if (role == PropertyDeclaration.GetKeywordRole || + role == PropertyDeclaration.SetKeywordRole || + role == CustomEventDeclaration.AddKeywordRole || + role == CustomEventDeclaration.RemoveKeywordRole) + color = accessorKeywordsColor; + break; + case "abstract": + case "const": + case "event": + case "extern": + case "override": + case "readonly": + case "sealed": + case "static": + case "virtual": + case "volatile": + case "async": + case "partial": + color = modifiersColor; + break; + case "checked": + case "unchecked": + color = checkedKeywordColor; + break; + case "fixed": + case "unsafe": + color = unsafeKeywordsColor; + break; + case "enum": + case "struct": + color = valueTypeKeywordsColor; + break; + case "class": + case "interface": + case "delegate": + color = referenceTypeKeywordsColor; + break; + case "select": + case "group": + case "by": + case "into": + case "from": + case "ascending": + case "descending": + case "orderby": + case "let": + case "join": + case "on": + case "equals": + if (nodeStack.PeekOrDefault() is QueryClause) + color = queryKeywordsColor; + break; + case "explicit": + case "implicit": + case "operator": + color = operatorKeywordsColor; + break; + case "params": + case "ref": + case "out": + color = parameterModifierColor; + break; + case "break": + case "continue": + case "goto": + case "yield": + case "return": + color = gotoKeywordsColor; + break; + } + if (nodeStack.PeekOrDefault() is AttributeSection) + color = attributeKeywordsColor; + if (color != null) { + textOutput.BeginSpan(color); + } + base.WriteKeyword(role, keyword); + if (color != null) { + textOutput.EndSpan(); + } + } + + public override void WritePrimitiveType(string type) + { + HighlightingColor color = null; + switch (type) { + case "new": + color = typeKeywordsColor; + break; + case "bool": + case "byte": + case "char": + case "decimal": + case "double": + case "enum": + case "float": + case "int": + case "long": + case "sbyte": + case "short": + case "struct": + case "uint": + case "ushort": + case "ulong": + color = valueTypeKeywordsColor; + break; + case "object": + case "string": + case "void": + color = referenceTypeKeywordsColor; + break; + } + if (color != null) { + textOutput.BeginSpan(color); + } + base.WritePrimitiveType(type); + if (color != null) { + textOutput.EndSpan(); + } + } + + public override void WriteIdentifier(Identifier identifier) + { + HighlightingColor color = null; + if (identifier.Name == "value" && nodeStack.PeekOrDefault() is Accessor accessor && accessor.Role != PropertyDeclaration.GetterRole) + color = valueKeywordColor; + switch (GetCurrentDefinition()) { + case ITypeDefinition t: + switch (t.Kind) { + case TypeKind.Delegate: + color = delegateTypeColor; + break; + case TypeKind.Class: + color = referenceTypeColor; + break; + case TypeKind.Interface: + color = interfaceTypeColor; + break; + case TypeKind.Enum: + color = enumerationTypeColor; + break; + case TypeKind.Struct: + color = valueTypeColor; + break; + } + break; + case IMethod m: + color = methodDeclarationColor; + break; + case IField f: + color = fieldDeclarationColor; + break; + } + switch (GetCurrentMemberReference()) { + case IType t: + switch (t.Kind) { + case TypeKind.Delegate: + color = delegateTypeColor; + break; + case TypeKind.Class: + color = referenceTypeColor; + break; + case TypeKind.Interface: + color = interfaceTypeColor; + break; + case TypeKind.Enum: + color = enumerationTypeColor; + break; + case TypeKind.Struct: + color = valueTypeColor; + break; + } + break; + case IMethod m: + color = methodCallColor; + break; + case IField f: + color = fieldAccessColor; + break; + } + if (color != null) { + textOutput.BeginSpan(color); + } + base.WriteIdentifier(identifier); + if (color != null) { + textOutput.EndSpan(); + } + } + + public override void WritePrimitiveValue(object value, string literalValue = null) + { + HighlightingColor color = null; + if (value is null) { + color = valueKeywordColor; + } + if (value is true || value is false) { + color = trueKeywordColor; + } + if (color != null) { + textOutput.BeginSpan(color); + } + base.WritePrimitiveValue(value, literalValue); + if (color != null) { + textOutput.EndSpan(); + } + } + + ISymbol GetCurrentDefinition() + { + if (nodeStack == null || nodeStack.Count == 0) + return null; + + var node = nodeStack.Peek(); + if (node is Identifier) + node = node.Parent; + if (IsDefinition(ref node)) + return node.GetSymbol(); + + return null; + } + + static bool IsDefinition(ref AstNode node) + { + if (node is EntityDeclaration) + return true; + if (node is VariableInitializer && node.Parent is FieldDeclaration) { + node = node.Parent; + return true; + } + if (node is FixedVariableInitializer) + return true; + return false; + } + + ISymbol GetCurrentMemberReference() + { + AstNode node = nodeStack.Peek(); + var symbol = node.GetSymbol(); + if (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression) { + symbol = node.Parent.GetSymbol(); + } + if (symbol != null && node.Parent is ObjectCreateExpression) { + symbol = node.Parent.GetSymbol(); + } + if (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member) { + var declaringType = member.DeclaringType; + if (declaringType != null && declaringType.Kind == TypeKind.Delegate) + return null; + } + return symbol; + } + + Stack nodeStack = new Stack(); + + public override void StartNode(AstNode node) + { + nodeStack.Push(node); + base.StartNode(node); + } + + public override void EndNode(AstNode node) + { + base.EndNode(node); + nodeStack.Pop(); + } + } +} diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index c9ef04f3d..0c1836845 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); TokenWriter tokenWriter = new TextTokenWriter(output, settings, typeSystem) { FoldBraces = settings.FoldBraces }; if (output is ISmartTextOutput highlightingOutput) { - tokenWriter = new HighlightingTokenWriter(tokenWriter, highlightingOutput); + tokenWriter = new CSharpHighlightingTokenWriter(tokenWriter, highlightingOutput); } syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); } @@ -518,423 +518,5 @@ namespace ICSharpCode.ILSpy var flags = ConversionFlags.All & ~ConversionFlags.ShowBody; return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(symbol); } - - class HighlightingTokenWriter : DecoratingTokenWriter - { - ISmartTextOutput textOutput; - - HighlightingColor visibilityKeywordsColor; - HighlightingColor namespaceKeywordsColor; - HighlightingColor structureKeywordsColor; - HighlightingColor gotoKeywordsColor; - HighlightingColor queryKeywordsColor; - HighlightingColor exceptionKeywordsColor; - HighlightingColor checkedKeywordColor; - HighlightingColor unsafeKeywordsColor; - HighlightingColor valueTypeKeywordsColor; - HighlightingColor referenceTypeKeywordsColor; - HighlightingColor operatorKeywordsColor; - HighlightingColor parameterModifierColor; - HighlightingColor modifiersColor; - HighlightingColor accessorKeywordsColor; - HighlightingColor attributeKeywordsColor; - - HighlightingColor referenceTypeColor; - HighlightingColor valueTypeColor; - HighlightingColor interfaceTypeColor; - HighlightingColor enumerationTypeColor; - HighlightingColor typeParameterTypeColor; - HighlightingColor delegateTypeColor; - - HighlightingColor methodCallColor; - HighlightingColor methodDeclarationColor; - - HighlightingColor fieldDeclarationColor; - HighlightingColor fieldAccessColor; - - HighlightingColor valueKeywordColor; - HighlightingColor thisKeywordColor; - HighlightingColor trueKeywordColor; - HighlightingColor typeKeywordsColor; - - public HighlightingTokenWriter(TokenWriter decoratedWriter, ISmartTextOutput textOutput) : base(decoratedWriter) - { - this.textOutput = textOutput; - var highlighting = HighlightingManager.Instance.GetDefinition("C#"); - - //this.defaultTextColor = ???; - - this.visibilityKeywordsColor = highlighting.GetNamedColor("Visibility"); - this.namespaceKeywordsColor = highlighting.GetNamedColor("NamespaceKeywords"); - this.structureKeywordsColor = highlighting.GetNamedColor("Keywords"); - this.gotoKeywordsColor = highlighting.GetNamedColor("GotoKeywords"); - this.queryKeywordsColor = highlighting.GetNamedColor("QueryKeywords"); - this.exceptionKeywordsColor = highlighting.GetNamedColor("ExceptionKeywords"); - this.checkedKeywordColor = highlighting.GetNamedColor("CheckedKeyword"); - this.unsafeKeywordsColor = highlighting.GetNamedColor("UnsafeKeywords"); - this.valueTypeKeywordsColor = highlighting.GetNamedColor("ValueTypeKeywords"); - this.referenceTypeKeywordsColor = highlighting.GetNamedColor("ReferenceTypeKeywords"); - this.operatorKeywordsColor = highlighting.GetNamedColor("OperatorKeywords"); - this.parameterModifierColor = highlighting.GetNamedColor("ParameterModifiers"); - this.modifiersColor = highlighting.GetNamedColor("Modifiers"); - this.accessorKeywordsColor = highlighting.GetNamedColor("GetSetAddRemove"); - - this.referenceTypeColor = highlighting.GetNamedColor("ReferenceTypes"); - this.valueTypeColor = highlighting.GetNamedColor("ValueTypes"); - this.interfaceTypeColor = highlighting.GetNamedColor("InterfaceTypes"); - this.enumerationTypeColor = highlighting.GetNamedColor("EnumTypes"); - this.typeParameterTypeColor = highlighting.GetNamedColor("TypeParameters"); - this.delegateTypeColor = highlighting.GetNamedColor("DelegateTypes"); - this.methodDeclarationColor = this.methodCallColor = highlighting.GetNamedColor("MethodCall"); - //this.eventDeclarationColor = this.eventAccessColor = defaultTextColor; - //this.propertyDeclarationColor = this.propertyAccessColor = defaultTextColor; - this.fieldDeclarationColor = this.fieldAccessColor = highlighting.GetNamedColor("FieldAccess"); - //this.variableDeclarationColor = this.variableAccessColor = defaultTextColor; - //this.parameterDeclarationColor = this.parameterAccessColor = defaultTextColor; - this.valueKeywordColor = highlighting.GetNamedColor("NullOrValueKeywords"); - this.thisKeywordColor = highlighting.GetNamedColor("ThisOrBaseReference"); - this.trueKeywordColor = highlighting.GetNamedColor("TrueFalse"); - this.typeKeywordsColor = highlighting.GetNamedColor("TypeKeywords"); - this.attributeKeywordsColor = highlighting.GetNamedColor("AttributeKeywords"); - //this.externAliasKeywordColor = ...; - } - - public override void WriteKeyword(Role role, string keyword) - { - HighlightingColor color = null; - switch (keyword) { - case "namespace": - case "using": - if (role == UsingStatement.UsingKeywordRole) - color = structureKeywordsColor; - else - color = namespaceKeywordsColor; - break; - case "this": - case "base": - color = thisKeywordColor; - break; - case "true": - case "false": - color = trueKeywordColor; - break; - case "public": - case "internal": - case "protected": - case "private": - color = visibilityKeywordsColor; - break; - case "if": - case "else": - case "switch": - case "case": - case "default": - case "while": - case "do": - case "for": - case "foreach": - case "lock": - case "global": - case "dynamic": - case "await": - case "where": - color = structureKeywordsColor; - break; - case "in": - if (nodeStack.PeekOrDefault() is ForeachStatement) - color = structureKeywordsColor; - else if (nodeStack.PeekOrDefault() is QueryClause) - color = queryKeywordsColor; - else - color = parameterModifierColor; - break; - case "as": - case "is": - case "new": - case "sizeof": - case "typeof": - case "nameof": - case "stackalloc": - color = typeKeywordsColor; - break; - case "try": - case "throw": - case "catch": - case "finally": - color = exceptionKeywordsColor; - break; - case "when": - if (role == CatchClause.WhenKeywordRole) - color = exceptionKeywordsColor; - break; - case "get": - case "set": - case "add": - case "remove": - if (role == PropertyDeclaration.GetKeywordRole || - role == PropertyDeclaration.SetKeywordRole || - role == CustomEventDeclaration.AddKeywordRole || - role == CustomEventDeclaration.RemoveKeywordRole) - color = accessorKeywordsColor; - break; - case "abstract": - case "const": - case "event": - case "extern": - case "override": - case "readonly": - case "sealed": - case "static": - case "virtual": - case "volatile": - case "async": - case "partial": - color = modifiersColor; - break; - case "checked": - case "unchecked": - color = checkedKeywordColor; - break; - case "fixed": - case "unsafe": - color = unsafeKeywordsColor; - break; - case "enum": - case "struct": - color = valueTypeKeywordsColor; - break; - case "class": - case "interface": - case "delegate": - color = referenceTypeKeywordsColor; - break; - case "select": - case "group": - case "by": - case "into": - case "from": - case "ascending": - case "descending": - case "orderby": - case "let": - case "join": - case "on": - case "equals": - if (nodeStack.PeekOrDefault() is QueryClause) - color = queryKeywordsColor; - break; - case "explicit": - case "implicit": - case "operator": - color = operatorKeywordsColor; - break; - case "params": - case "ref": - case "out": - color = parameterModifierColor; - break; - case "break": - case "continue": - case "goto": - case "yield": - case "return": - color = gotoKeywordsColor; - break; - } - if (nodeStack.PeekOrDefault() is AttributeSection) - color = attributeKeywordsColor; - if (color != null) { - textOutput.BeginSpan(color); - } - base.WriteKeyword(role, keyword); - if (color != null) { - textOutput.EndSpan(); - } - } - - public override void WritePrimitiveType(string type) - { - HighlightingColor color = null; - switch (type) { - case "new": - color = typeKeywordsColor; - break; - case "bool": - case "byte": - case "char": - case "decimal": - case "double": - case "enum": - case "float": - case "int": - case "long": - case "sbyte": - case "short": - case "struct": - case "uint": - case "ushort": - case "ulong": - color = valueTypeKeywordsColor; - break; - case "object": - case "string": - case "void": - color = referenceTypeKeywordsColor; - break; - } - if (color != null) { - textOutput.BeginSpan(color); - } - base.WritePrimitiveType(type); - if (color != null) { - textOutput.EndSpan(); - } - } - - public override void WriteIdentifier(Identifier identifier) - { - HighlightingColor color = null; - if (identifier.Name == "value" && nodeStack.PeekOrDefault() is Accessor accessor && accessor.Role != PropertyDeclaration.GetterRole) - color = valueKeywordColor; - switch (GetCurrentDefinition()) { - case ITypeDefinition t: - switch (t.Kind) { - case TypeKind.Delegate: - color = delegateTypeColor; - break; - case TypeKind.Class: - color = referenceTypeColor; - break; - case TypeKind.Interface: - color = interfaceTypeColor; - break; - case TypeKind.Enum: - color = enumerationTypeColor; - break; - case TypeKind.Struct: - color = valueTypeColor; - break; - } - break; - case IMethod m: - color = methodDeclarationColor; - break; - case IField f: - color = fieldDeclarationColor; - break; - } - switch (GetCurrentMemberReference()) { - case IType t: - switch (t.Kind) { - case TypeKind.Delegate: - color = delegateTypeColor; - break; - case TypeKind.Class: - color = referenceTypeColor; - break; - case TypeKind.Interface: - color = interfaceTypeColor; - break; - case TypeKind.Enum: - color = enumerationTypeColor; - break; - case TypeKind.Struct: - color = valueTypeColor; - break; - } - break; - case IMethod m: - color = methodCallColor; - break; - case IField f: - color = fieldAccessColor; - break; - } - if (color != null) { - textOutput.BeginSpan(color); - } - base.WriteIdentifier(identifier); - if (color != null) { - textOutput.EndSpan(); - } - } - - public override void WritePrimitiveValue(object value, string literalValue = null) - { - HighlightingColor color = null; - if (value is null) { - color = valueKeywordColor; - } - if (value is true || value is false) { - color = trueKeywordColor; - } - if (color != null) { - textOutput.BeginSpan(color); - } - base.WritePrimitiveValue(value, literalValue); - if (color != null) { - textOutput.EndSpan(); - } - } - - ISymbol GetCurrentDefinition() - { - if (nodeStack == null || nodeStack.Count == 0) - return null; - - var node = nodeStack.Peek(); - if (node is Identifier) - node = node.Parent; - if (IsDefinition(ref node)) - return node.GetSymbol(); - - return null; - } - - static bool IsDefinition(ref AstNode node) - { - if (node is EntityDeclaration) - return true; - if (node is VariableInitializer && node.Parent is FieldDeclaration) { - node = node.Parent; - return true; - } - if (node is FixedVariableInitializer) - return true; - return false; - } - - ISymbol GetCurrentMemberReference() - { - AstNode node = nodeStack.Peek(); - var symbol = node.GetSymbol(); - if (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression) { - symbol = node.Parent.GetSymbol(); - } - if (symbol != null && node.Parent is ObjectCreateExpression) { - symbol = node.Parent.GetSymbol(); - } - if (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member) { - var declaringType = member.DeclaringType; - if (declaringType != null && declaringType.Kind == TypeKind.Delegate) - return null; - } - return symbol; - } - - Stack nodeStack = new Stack(); - - public override void StartNode(AstNode node) - { - nodeStack.Push(node); - base.StartNode(node); - } - - public override void EndNode(AstNode node) - { - base.EndNode(node); - nodeStack.Pop(); - } - } } } From 98719849915bb68b97db804e73c667900b49ef22 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 13:34:25 +0200 Subject: [PATCH 07/84] Fix end location of PrimitiveExpression --- .../CSharp/OutputVisitor/InsertMissingTokensDecorator.cs | 7 ++++--- .../CSharp/Syntax/Expressions/PrimitiveExpression.cs | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs index 203e29c43..1e20d061a 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs @@ -103,13 +103,14 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor public override void WritePrimitiveValue(object value, string literalValue = null) { Expression node = nodes.Peek().LastOrDefault() as Expression; + var startLocation = locationProvider.Location; + base.WritePrimitiveValue(value, literalValue); if (node is PrimitiveExpression) { - ((PrimitiveExpression)node).SetStartLocation(locationProvider.Location); + ((PrimitiveExpression)node).SetLocation(startLocation, locationProvider.Location); } if (node is NullReferenceExpression) { - ((NullReferenceExpression)node).SetStartLocation(locationProvider.Location); + ((NullReferenceExpression)node).SetStartLocation(startLocation); } - base.WritePrimitiveValue(value, literalValue); } public override void WritePrimitiveType(string type) diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs index af3818269..3e6d49724 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs @@ -43,11 +43,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } - internal void SetStartLocation(TextLocation value) + internal void SetLocation(TextLocation startLocation, TextLocation endLocation) { ThrowIfFrozen(); - this.startLocation = value; - this.endLocation = null; + this.startLocation = startLocation; + this.endLocation = endLocation; } string literalValue; From d871960bec338c2550af40b8ba87d3ad893b1cb2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 13:35:06 +0200 Subject: [PATCH 08/84] Add WriteInstruction to MethodBodyDisassembler --- .../Disassembler/MethodBodyDisassembler.cs | 38 +++++-------------- .../Disassembler/ReflectionDisassembler.cs | 7 +++- ICSharpCode.Decompiler/IL/SequencePoint.cs | 4 +- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index a3f85c9a4..ec65a8371 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.Disassembler /// /// Disassembles a method body. /// - public sealed class MethodBodyDisassembler + public class MethodBodyDisassembler { readonly ITextOutput output; readonly bool detectControlStructure; @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.Disassembler this.cancellationToken = cancellationToken; } - public void Disassemble(MethodBody body/*, MemberMapping methodMapping*/) + public void Disassemble(MethodBody body) { // start writing IL code MethodDefinition method = body.Method; @@ -61,20 +61,7 @@ namespace ICSharpCode.Decompiler.Disassembler WriteStructureBody(new ILStructure(body), branchTargets, ref inst, method.Body.CodeSize); } else { foreach (var inst in method.Body.Instructions) { - //var startLocation = output.Location; - inst.WriteTo(output); - - /* - if (debugSymbols != null) { - // add IL code mappings - used in debugger - debugSymbols.SequencePoints.Add( - new SequencePoint() { - StartLocation = output.Location, - EndLocation = output.Location, - ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) } - }); - }*/ - + WriteInstruction(output, inst); output.WriteLine(); } WriteExceptionHandlers(body); @@ -191,19 +178,7 @@ namespace ICSharpCode.Decompiler.Disassembler if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { output.WriteLine(); // put an empty line after branches, and in front of branch targets } - //var startLocation = output.Location; - inst.WriteTo(output); - - /*// add IL code mappings - used in debugger - if (debugSymbols != null) { - debugSymbols.SequencePoints.Add( - new SequencePoint() { - StartLocation = startLocation, - EndLocation = output.Location, - ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) } - }); - }*/ - + WriteInstruction(output, inst); output.WriteLine(); prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch @@ -237,5 +212,10 @@ namespace ICSharpCode.Decompiler.Disassembler throw new NotSupportedException(); } } + + protected virtual void WriteInstruction(ITextOutput output, Instruction instruction) + { + instruction.WriteTo(output); + } } } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index 7707f7791..6137fc0d5 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -36,12 +36,17 @@ namespace ICSharpCode.Decompiler.Disassembler MemberReference currentMember; public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken) + : this(output, new MethodBodyDisassembler(output, detectControlStructure, cancellationToken), cancellationToken) + { + } + + public ReflectionDisassembler(ITextOutput output, MethodBodyDisassembler methodBodyDisassembler, CancellationToken cancellationToken) { if (output == null) throw new ArgumentNullException(nameof(output)); this.output = output; this.cancellationToken = cancellationToken; - this.methodBodyDisassembler = new MethodBodyDisassembler(output, detectControlStructure, cancellationToken); + this.methodBodyDisassembler = methodBodyDisassembler; } #region Disassemble Method diff --git a/ICSharpCode.Decompiler/IL/SequencePoint.cs b/ICSharpCode.Decompiler/IL/SequencePoint.cs index 568953c35..ec2ac3d45 100644 --- a/ICSharpCode.Decompiler/IL/SequencePoint.cs +++ b/ICSharpCode.Decompiler/IL/SequencePoint.cs @@ -7,8 +7,8 @@ namespace ICSharpCode.Decompiler.IL /// /// A sequence point produced by the decompiler. /// - public struct SequencePoint - { + public struct SequencePoint + { /// /// IL offset. /// From a663b5b0dfc79c4799461848c2e4fe8370428835 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 13:35:28 +0200 Subject: [PATCH 09/84] Implement basic mixed view in CSharpILMixedLanguage --- ILSpy/ExtensionMethods.cs | 25 ++++++ ILSpy/Languages/CSharpILMixedLanguage.cs | 103 ++++++++++++++++++++++- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/ILSpy/ExtensionMethods.cs b/ILSpy/ExtensionMethods.cs index 32cd8ea30..c83d09f4e 100644 --- a/ILSpy/ExtensionMethods.cs +++ b/ILSpy/ExtensionMethods.cs @@ -64,6 +64,31 @@ namespace ICSharpCode.ILSpy return ~start; } + public static int BinarySearch(this IList instance, TKey itemKey, Func keySelector) + where TKey : IComparable, IComparable + { + if (instance == null) + throw new ArgumentNullException(nameof(instance)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + int start = 0; + int end = instance.Count - 1; + + while (start <= end) { + int m = (start + end) / 2; + TKey key = keySelector(instance[m]); + int result = key.CompareTo(itemKey); + if (result == 0) + return m; + if (result < 0) + start = m + 1; + else + end = m - 1; + } + return ~start; + } + public static bool IsCustomAttribute(this TypeDefinition type) { while (type.FullName != "System.Object") { diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 9be3e0092..a51ed133c 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -1,9 +1,20 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; +using System.IO; using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Media; +using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Decompiler; +using ICSharpCode.Decompiler.CSharp; +using ICSharpCode.Decompiler.CSharp.OutputVisitor; +using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.Disassembler; +using ICSharpCode.Decompiler.IL; +using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Util; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -17,10 +28,100 @@ namespace ICSharpCode.ILSpy public override string FileExtension => ".il"; + CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options) + { + CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings); + decompiler.CancellationToken = options.CancellationToken; + return decompiler; + } + + void WriteCode(TextWriter output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem) + { + syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); + TokenWriter tokenWriter = new TextWriterTokenWriter(output); + tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter); + syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); + } + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + //AddReferenceWarningMessage(method.Module.Assembly, output); + var csharpOutput = new StringWriter(); + CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); + var st = decompiler.Decompile(method); + WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem); + var sequencePoints = (IList)decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.CecilMethod == method).Value ?? EmptyList.Instance; + var codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); + WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true)); + var methodDisassembler = new MixedMethodBodyDisassembler(output, codeLines, sequencePoints, detectControlStructure, options.CancellationToken); + var dis = new ReflectionDisassembler(output, methodDisassembler, options.CancellationToken); dis.DisassembleMethod(method); } + + class MixedMethodBodyDisassembler : MethodBodyDisassembler + { + // list sorted by IL offset + IList sequencePoints; + // lines of raw c# source code + string[] codeLines; + + public MixedMethodBodyDisassembler(ITextOutput output, string[] codeLines, IList sequencePoints, bool detectControlStructure, CancellationToken cancellationToken) + : base(output, detectControlStructure, cancellationToken) + { + if (codeLines == null) + throw new ArgumentNullException(nameof(codeLines)); + if (sequencePoints == null) + throw new ArgumentNullException(nameof(sequencePoints)); + + this.codeLines = codeLines; + this.sequencePoints = sequencePoints; + } + + protected override void WriteInstruction(ITextOutput output, Mono.Cecil.Cil.Instruction instruction) + { + int index = sequencePoints.BinarySearch(instruction.Offset, seq => seq.Offset); + if (index >= 0) { + var info = sequencePoints[index]; + if (!info.IsHidden) { + for (int line = info.StartLine; line <= info.EndLine; line++) { + if (output is ISmartTextOutput highlightingOutput) { + string text = codeLines[line - 1]; + int startColumn = 1; + int endColumn = text.Length + 1; + if (line == info.StartLine) + startColumn = info.StartColumn; + if (line == info.EndLine) + endColumn = info.EndColumn; + WriteHighlightedCommentLine(highlightingOutput, text, startColumn - 1, endColumn - 1); + } else + WriteCommentLine(output, codeLines[line - 1]); + } + } else { + WriteCommentLine(output, "no code"); + } + } + base.WriteInstruction(output, instruction); + } + + HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) }; + HighlightingColor black = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.Black) }; + + void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn) + { + output.BeginSpan(gray); + output.Write("// " + text.Substring(0, startColumn)); + output.BeginSpan(black); + output.Write(text.Substring(startColumn, endColumn - startColumn)); + output.EndSpan(); + output.Write(text.Substring(endColumn)); + output.EndSpan(); + output.WriteLine(); + } + + void WriteCommentLine(ITextOutput output, string text) + { + output.WriteLine("// " + text); + } + } } } From 682ca234d597e8b3ef6446030e57b51e3b9cf91f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 14:07:59 +0200 Subject: [PATCH 10/84] [csilview] remove indentation from single-line C# code in C#-IL view. --- ILSpy/Languages/CSharpILMixedLanguage.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index a51ed133c..08e0fb58a 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy startColumn = info.StartColumn; if (line == info.EndLine) endColumn = info.EndColumn; - WriteHighlightedCommentLine(highlightingOutput, text, startColumn - 1, endColumn - 1); + WriteHighlightedCommentLine(highlightingOutput, text, startColumn - 1, endColumn - 1, info.StartLine == info.EndLine); } else WriteCommentLine(output, codeLines[line - 1]); } @@ -106,10 +106,13 @@ namespace ICSharpCode.ILSpy HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) }; HighlightingColor black = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.Black) }; - void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn) + void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn, bool isSingleLine) { output.BeginSpan(gray); - output.Write("// " + text.Substring(0, startColumn)); + if (isSingleLine) + output.Write("// " + text.Substring(0, startColumn).TrimStart()); + else + output.Write("// " + text.Substring(0, startColumn)); output.BeginSpan(black); output.Write(text.Substring(startColumn, endColumn - startColumn)); output.EndSpan(); From 809f2c1c9c7e36b87130e9bce5afc5a77571ee78 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 14:08:35 +0200 Subject: [PATCH 11/84] Sort languages in drop-down by name (except for debug 'languages') --- ILSpy/Languages/Languages.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ILSpy/Languages/Languages.cs b/ILSpy/Languages/Languages.cs index 2cf2e5632..2312f7ec5 100644 --- a/ILSpy/Languages/Languages.cs +++ b/ILSpy/Languages/Languages.cs @@ -43,6 +43,7 @@ namespace ICSharpCode.ILSpy { List languages = new List(); languages.AddRange(composition.GetExportedValues()); + languages.Sort((a, b) => a.Name.CompareTo(b.Name)); #if DEBUG languages.AddRange(ILAstLanguage.GetDebugLanguages()); languages.AddRange(CSharpLanguage.GetDebugLanguages()); From bc430a93587aa5287810b29443d8f0144e4e854a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 14:16:54 +0200 Subject: [PATCH 12/84] Support SwitchStatement in SequencePointBuilder. --- .../CSharp/SequencePointBuilder.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index eaf3367b7..a361005b5 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -32,8 +32,19 @@ namespace ICSharpCode.Decompiler.CSharp { struct StatePerSequencePoint { + /// + /// Main AST node associated with this sequence point. + /// internal readonly AstNode PrimaryNode; + + /// + /// List of IL intervals that are associated with this sequence point. + /// internal readonly List Intervals; + + /// + /// The function containing this sequence point. + /// internal ILFunction Function; public StatePerSequencePoint(AstNode primaryNode) @@ -46,7 +57,11 @@ namespace ICSharpCode.Decompiler.CSharp readonly List<(ILFunction, SequencePoint)> sequencePoints = new List<(ILFunction, SequencePoint)>(); readonly HashSet mappedInstructions = new HashSet(); + + // Stack holding information for outer statements. readonly Stack outerStates = new Stack(); + + // Collects information for the current sequence point. StatePerSequencePoint current = new StatePerSequencePoint(); void VisitAsSequencePoint(AstNode node) @@ -71,6 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp public override void VisitForStatement(ForStatement forStatement) { + // Every element of a for-statement is it's own sequence point. foreach (var init in forStatement.Initializers) { VisitAsSequencePoint(init); } @@ -80,6 +96,28 @@ namespace ICSharpCode.Decompiler.CSharp } VisitAsSequencePoint(forStatement.EmbeddedStatement); } + + public override void VisitSwitchStatement(SwitchStatement switchStatement) + { + StartSequencePoint(switchStatement); + switchStatement.Expression.AcceptVisitor(this); + foreach (var section in switchStatement.SwitchSections) { + // note: sections will not contribute to the current sequence point + section.AcceptVisitor(this); + } + // add switch statement itself to sequence point + // (call only after the sections are visited) + AddToSequencePoint(switchStatement); + EndSequencePoint(switchStatement.StartLocation, switchStatement.RParToken.EndLocation); + } + + public override void VisitSwitchSection(Syntax.SwitchSection switchSection) + { + // every statement in the switch section is its own sequence point + foreach (var stmt in switchSection.Statements) { + VisitAsSequencePoint(stmt); + } + } /// /// Start a new C# statement = new sequence point. @@ -104,6 +142,10 @@ namespace ICSharpCode.Decompiler.CSharp current = outerStates.Pop(); } + /// + /// Add the ILAst instruction associated with the AstNode to the sequence point. + /// Also add all its ILAst sub-instructions (unless they were already added to another sequence point). + /// void AddToSequencePoint(AstNode node) { foreach (var inst in node.Annotations.OfType()) { @@ -129,6 +171,9 @@ namespace ICSharpCode.Decompiler.CSharp } } + /// + /// Called after the visitor is done to return the results. + /// internal Dictionary> GetSequencePoints() { var dict = new Dictionary>(); From 9d7fb0627dddb38d7b07187315e6d7bc91a60464 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 14:55:19 +0200 Subject: [PATCH 13/84] Add hidden sequence points for unmapped code. --- .../CSharp/SequencePointBuilder.cs | 27 ++++++++++++++++--- ICSharpCode.Decompiler/IL/SequencePoint.cs | 17 +++++++++++- ILSpy/Languages/CSharpILMixedLanguage.cs | 18 ++++++++----- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index a361005b5..716710e01 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.IL; @@ -131,8 +132,12 @@ namespace ICSharpCode.Decompiler.CSharp void EndSequencePoint(TextLocation startLocation, TextLocation endLocation) { if (current.Intervals.Count > 0 && current.Function != null) { + // use LongSet to deduplicate and merge the intervals + var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End))); + Debug.Assert(!longSet.IsEmpty); sequencePoints.Add((current.Function, new SequencePoint { - Offset = current.Intervals.Select(i => i.Start).Min(), + Offset = (int)longSet.Intervals[0].Start, + EndOffset = (int)longSet.Intervals[0].End, StartLine = startLocation.Line, StartColumn = startLocation.Column, EndLine = endLocation.Line, @@ -183,8 +188,24 @@ namespace ICSharpCode.Decompiler.CSharp } list.Add(sequencePoint); } - foreach (var list in dict.Values) { - list.Sort((a, b) => a.Offset.CompareTo(b.Offset)); + foreach (var (function, list) in dict.ToList()) { + // For each function, sort sequence points + // and insert hidden sequence points in the gaps. + var newList = new List(); + int pos = 0; + foreach (var sequencePoint in list.OrderBy(sp => sp.Offset)) { + Debug.Assert(sequencePoint.Offset >= pos); + if (sequencePoint.Offset > pos) { + var hidden = new SequencePoint(); + hidden.Offset = pos; + hidden.EndOffset = sequencePoint.Offset; + hidden.SetHidden(); + newList.Add(hidden); + } + newList.Add(sequencePoint); + pos = sequencePoint.EndOffset; + } + dict[function] = newList; } return dict; } diff --git a/ICSharpCode.Decompiler/IL/SequencePoint.cs b/ICSharpCode.Decompiler/IL/SequencePoint.cs index ec2ac3d45..d313fa73d 100644 --- a/ICSharpCode.Decompiler/IL/SequencePoint.cs +++ b/ICSharpCode.Decompiler/IL/SequencePoint.cs @@ -10,10 +10,20 @@ namespace ICSharpCode.Decompiler.IL public struct SequencePoint { /// - /// IL offset. + /// IL start offset. /// public int Offset { get; set; } + /// + /// IL end offset. + /// + /// + /// This does not get stored in debug information; + /// it is used internally to create hidden sequence points + /// for the IL fragments not covered by any sequence point. + /// + public int EndOffset { get; set; } + public int StartLine { get; set; } public int StartColumn { get; set; } public int EndLine { get; set; } @@ -22,5 +32,10 @@ namespace ICSharpCode.Decompiler.IL public bool IsHidden { get { return StartLine == 0xfeefee && StartLine == EndLine; } } + + internal void SetHidden() + { + StartLine = EndLine = 0xfeefee; + } } } diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 08e0fb58a..628e88933 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -82,9 +82,10 @@ namespace ICSharpCode.ILSpy int index = sequencePoints.BinarySearch(instruction.Offset, seq => seq.Offset); if (index >= 0) { var info = sequencePoints[index]; + var highlightingOutput = output as ISmartTextOutput; if (!info.IsHidden) { for (int line = info.StartLine; line <= info.EndLine; line++) { - if (output is ISmartTextOutput highlightingOutput) { + if (highlightingOutput != null) { string text = codeLines[line - 1]; int startColumn = 1; int endColumn = text.Length + 1; @@ -97,25 +98,28 @@ namespace ICSharpCode.ILSpy WriteCommentLine(output, codeLines[line - 1]); } } else { - WriteCommentLine(output, "no code"); + output.Write("// "); + highlightingOutput?.BeginSpan(gray); + output.WriteLine("(hidden sequence point)"); + highlightingOutput?.EndSpan(); } } base.WriteInstruction(output, instruction); } HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) }; - HighlightingColor black = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.Black) }; void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn, bool isSingleLine) { + output.Write("// "); output.BeginSpan(gray); if (isSingleLine) - output.Write("// " + text.Substring(0, startColumn).TrimStart()); + output.Write(text.Substring(0, startColumn).TrimStart()); else - output.Write("// " + text.Substring(0, startColumn)); - output.BeginSpan(black); - output.Write(text.Substring(startColumn, endColumn - startColumn)); + output.Write(text.Substring(0, startColumn)); output.EndSpan(); + output.Write(text.Substring(startColumn, endColumn - startColumn)); + output.BeginSpan(gray); output.Write(text.Substring(endColumn)); output.EndSpan(); output.WriteLine(); From 3aca47d1f55a259782175de49b7cf1c3aa396634 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 15:59:35 +0200 Subject: [PATCH 14/84] Allow decompiling whole assembly in IL + C# mode. --- .../CSharp/SequencePointBuilder.cs | 25 +++++-- .../Transforms/IntroduceExtensionMethods.cs | 15 ++++- .../Disassembler/MethodBodyDisassembler.cs | 2 +- ILSpy/Languages/CSharpILMixedLanguage.cs | 65 ++++++++++--------- ILSpy/Languages/ILLanguage.cs | 30 +++++---- 5 files changed, 82 insertions(+), 55 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 716710e01..463ff1e1c 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.CSharp readonly Stack outerStates = new Stack(); // Collects information for the current sequence point. - StatePerSequencePoint current = new StatePerSequencePoint(); + StatePerSequencePoint current; void VisitAsSequencePoint(AstNode node) { @@ -165,7 +165,7 @@ namespace ICSharpCode.Decompiler.CSharp return; } // Add the IL range associated with this instruction to the current sequence point. - if (!inst.ILRange.IsEmpty) { + if (!inst.ILRange.IsEmpty && current.Intervals != null) { current.Intervals.Add(inst.ILRange); current.Function = inst.Ancestors.OfType().FirstOrDefault(); } @@ -189,13 +189,24 @@ namespace ICSharpCode.Decompiler.CSharp list.Add(sequencePoint); } foreach (var (function, list) in dict.ToList()) { - // For each function, sort sequence points - // and insert hidden sequence points in the gaps. + // For each function, sort sequence points and fix overlaps+gaps var newList = new List(); int pos = 0; - foreach (var sequencePoint in list.OrderBy(sp => sp.Offset)) { - Debug.Assert(sequencePoint.Offset >= pos); - if (sequencePoint.Offset > pos) { + foreach (var sequencePoint in list.OrderBy(sp => sp.Offset).ThenBy(sp => sp.EndOffset)) { + if (sequencePoint.Offset < pos) { + // overlapping sequence point? + // delete previous sequence points that are after sequencePoint.Offset + while (newList.Count > 0 && newList.Last().EndOffset > pos) { + var last = newList.Last(); + if (last.Offset >= sequencePoint.Offset) { + newList.RemoveAt(newList.Count - 1); + } else { + last.EndOffset = sequencePoint.Offset; + newList[newList.Count - 1] = last; + } + } + } else if (sequencePoint.Offset > pos) { + // insert hidden sequence point in the gap. var hidden = new SequencePoint(); hidden.Offset = pos; hidden.EndOffset = sequencePoint.Offset; diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs index 1ff8f83e3..53596faa9 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs @@ -43,15 +43,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { this.context = context; this.usingScope = this.rootUsingScope = rootNode.Annotation(); + currentMember = context.DecompiledMember; + SetContext(); rootNode.AcceptVisitor(this); } void SetContext() { this.usingScope = rootUsingScope; - foreach (var name in currentMember.Namespace.Split('.')) - usingScope = new UsingScope(usingScope, name); - resolveContext = new CSharpTypeResolveContext(currentMember.ParentAssembly, usingScope.Resolve(context.TypeSystem.Compilation), currentMember.DeclaringTypeDefinition, currentMember); + string ns = currentMember?.Namespace ?? context.DecompiledTypeDefinition?.Namespace; + if (ns != null) { + foreach (var name in ns.Split('.')) + usingScope = new UsingScope(usingScope, name); + } + resolveContext = new CSharpTypeResolveContext( + context.DecompiledAssembly, + usingScope.Resolve(context.TypeSystem.Compilation), + currentMember?.DeclaringTypeDefinition ?? context.DecompiledTypeDefinition, + currentMember); resolver = new CSharpResolver(resolveContext); } diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index ec65a8371..c5860c7cb 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.Disassembler this.cancellationToken = cancellationToken; } - public void Disassemble(MethodBody body) + public virtual void Disassemble(MethodBody body) { // start writing IL code MethodDefinition method = body.Method; diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 628e88933..73340f695 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -16,68 +16,69 @@ using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; using Mono.Cecil; +using Mono.Cecil.Cil; namespace ICSharpCode.ILSpy { [Export(typeof(Language))] - class CSharpILMixedLanguage : Language + class CSharpILMixedLanguage : ILLanguage { - private readonly bool detectControlStructure = true; - public override string Name => "IL with C#"; - public override string FileExtension => ".il"; + protected override ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options) + { + return new ReflectionDisassembler(output, + new MixedMethodBodyDisassembler(output, detectControlStructure, options), + options.CancellationToken); + } - CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options) + static CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options) { CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings); decompiler.CancellationToken = options.CancellationToken; return decompiler; } - void WriteCode(TextWriter output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem) + static void WriteCode(TextWriter output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem) { syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); TokenWriter tokenWriter = new TextWriterTokenWriter(output); tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); } - - public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) - { - //AddReferenceWarningMessage(method.Module.Assembly, output); - var csharpOutput = new StringWriter(); - CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); - var st = decompiler.Decompile(method); - WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem); - var sequencePoints = (IList)decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.CecilMethod == method).Value ?? EmptyList.Instance; - var codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); - WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true)); - var methodDisassembler = new MixedMethodBodyDisassembler(output, codeLines, sequencePoints, detectControlStructure, options.CancellationToken); - var dis = new ReflectionDisassembler(output, methodDisassembler, options.CancellationToken); - dis.DisassembleMethod(method); - } - + class MixedMethodBodyDisassembler : MethodBodyDisassembler { + readonly DecompilationOptions options; // list sorted by IL offset - IList sequencePoints; + IList sequencePoints; // lines of raw c# source code string[] codeLines; - public MixedMethodBodyDisassembler(ITextOutput output, string[] codeLines, IList sequencePoints, bool detectControlStructure, CancellationToken cancellationToken) - : base(output, detectControlStructure, cancellationToken) + public MixedMethodBodyDisassembler(ITextOutput output, bool detectControlStructure, DecompilationOptions options) + : base(output, detectControlStructure, options.CancellationToken) { - if (codeLines == null) - throw new ArgumentNullException(nameof(codeLines)); - if (sequencePoints == null) - throw new ArgumentNullException(nameof(sequencePoints)); + this.options = options; + } - this.codeLines = codeLines; - this.sequencePoints = sequencePoints; + public override void Disassemble(MethodBody body) + { + var method = body.Method; + try { + var csharpOutput = new StringWriter(); + CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); + var st = decompiler.Decompile(method); + WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem); + this.sequencePoints = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.CecilMethod == method).Value ?? (IList)EmptyList.Instance; + this.codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); + base.Disassemble(body); + } finally { + this.sequencePoints = null; + this.codeLines = null; + } } - protected override void WriteInstruction(ITextOutput output, Mono.Cecil.Cil.Instruction instruction) + protected override void WriteInstruction(ITextOutput output, Instruction instruction) { int index = sequencePoints.BinarySearch(instruction.Offset, seq => seq.Offset); if (index >= 0) { diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index 817586d95..71dec3ee7 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy [Export(typeof(Language))] public class ILLanguage : Language { - private readonly bool detectControlStructure = true; + protected bool detectControlStructure = true; public override string Name { get { return "IL"; } @@ -44,21 +44,26 @@ namespace ICSharpCode.ILSpy get { return ".il"; } } + protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options) + { + return new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + } + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + var dis = CreateDisassembler(output, options); dis.DisassembleMethod(method); } public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + var dis = CreateDisassembler(output, options); dis.DisassembleField(field); } public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { - ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + ReflectionDisassembler rd = CreateDisassembler(output, options); rd.DisassembleProperty(property); if (property.GetMethod != null) { output.WriteLine(); @@ -76,7 +81,7 @@ namespace ICSharpCode.ILSpy public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { - ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + ReflectionDisassembler rd = CreateDisassembler(output, options); rd.DisassembleEvent(ev); if (ev.AddMethod != null) { output.WriteLine(); @@ -94,13 +99,14 @@ namespace ICSharpCode.ILSpy public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + var dis = CreateDisassembler(output, options); dis.DisassembleType(type); } public override void DecompileNamespace(string nameSpace, IEnumerable types, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleNamespace(nameSpace, types); + var dis = CreateDisassembler(output, options); + dis.DisassembleNamespace(nameSpace, types); } public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) @@ -108,17 +114,17 @@ namespace ICSharpCode.ILSpy output.WriteLine("// " + assembly.FileName); output.WriteLine(); - ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + var dis = CreateDisassembler(output, options); if (options.FullDecompilation) - rd.WriteAssemblyReferences(assembly.ModuleDefinition); + dis.WriteAssemblyReferences(assembly.ModuleDefinition); if (assembly.AssemblyDefinition != null) - rd.WriteAssemblyHeader(assembly.AssemblyDefinition); + dis.WriteAssemblyHeader(assembly.AssemblyDefinition); output.WriteLine(); - rd.WriteModuleHeader(assembly.ModuleDefinition); + dis.WriteModuleHeader(assembly.ModuleDefinition); if (options.FullDecompilation) { output.WriteLine(); output.WriteLine(); - rd.WriteModuleContents(assembly.ModuleDefinition); + dis.WriteModuleContents(assembly.ModuleDefinition); } } From 312277119c5c5f9a01e8ab378dcd1f2eb24ac6a1 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 15:07:36 +0200 Subject: [PATCH 15/84] Move ILAstWritingOptions to separate file --- .../ICSharpCode.Decompiler.csproj | 1 + .../IL/ILAstWritingOptions.cs | 66 +++++++++++++++++++ .../IL/Instructions/ILInstruction.cs | 13 ---- 3 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 93e3c5389..07d6c2668 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -273,6 +273,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs new file mode 100644 index 000000000..42b8ddf66 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Text; + +namespace ICSharpCode.Decompiler.IL +{ + public class ILAstWritingOptions : INotifyPropertyChanged + { + private bool useLogicOperationSugar; + private bool useFieldSugar; + private bool showILRanges; + + /// + /// Sugar for logic.not/and/or. + /// + public bool UseLogicOperationSugar { + get { return useLogicOperationSugar; } + set { + if (useLogicOperationSugar != value) { + useLogicOperationSugar = value; + OnPropertyChanged(); + } + } + } + + /// + /// Sugar for ldfld/stfld. + /// + public bool UseFieldSugar { + get { return useFieldSugar; } + set { + if (useFieldSugar != value) { + useFieldSugar = value; + OnPropertyChanged(); + } + } + } + + /// + /// Show IL ranges in ILAst output. + /// + public bool ShowILRanges { + get { return showILRanges; } + set { + if (showILRanges != value) { + showILRanges = value; + OnPropertyChanged(); + } + } + } + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChanged?.Invoke(this, e); + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index b4042364e..d0bce881a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -745,17 +745,4 @@ namespace ICSharpCode.Decompiler.IL /// StackType UnderlyingResultType { get; } } - - public class ILAstWritingOptions - { - /// - /// Sugar for logic.not/and/or. - /// - public bool UseLogicOperationSugar { get; set; } - - /// - /// Sugar for ldfld/stfld. - /// - public bool UseFieldSugar { get; set; } - } } From 10cf712135bc0dd41de9577dd9c0ed63b85583ec Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 15:08:52 +0200 Subject: [PATCH 16/84] Move ILAst writing options to DebugSteps pane and implement auto refresh. --- ILSpy/DebugSteps.xaml | 9 ++++- ILSpy/DebugSteps.xaml.cs | 28 +++++++++++++- ILSpy/Languages/ILAstLanguage.cs | 63 +------------------------------- 3 files changed, 34 insertions(+), 66 deletions(-) diff --git a/ILSpy/DebugSteps.xaml b/ILSpy/DebugSteps.xaml index a96d1463e..e343e5070 100644 --- a/ILSpy/DebugSteps.xaml +++ b/ILSpy/DebugSteps.xaml @@ -6,7 +6,12 @@ xmlns:local="clr-namespace:ICSharpCode.ILSpy" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> - + + + + + + @@ -21,5 +26,5 @@ - + diff --git a/ILSpy/DebugSteps.xaml.cs b/ILSpy/DebugSteps.xaml.cs index f2c44b474..f3c3b7a7f 100644 --- a/ILSpy/DebugSteps.xaml.cs +++ b/ILSpy/DebugSteps.xaml.cs @@ -2,6 +2,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL.Transforms; namespace ICSharpCode.ILSpy @@ -12,6 +13,13 @@ namespace ICSharpCode.ILSpy /// public partial class DebugSteps : UserControl, IPane { + static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions { + UseFieldSugar = true, + UseLogicOperationSugar = true + }; + + public static ILAstWritingOptions Options => writingOptions; + #if DEBUG ILAstLanguage language; #endif @@ -23,6 +31,7 @@ namespace ICSharpCode.ILSpy #if DEBUG MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged; MainWindow.Instance.SelectionChanged += SelectionChanged; + writingOptions.PropertyChanged += WritingOptions_PropertyChanged; if (MainWindow.Instance.CurrentLanguage is ILAstLanguage l) { l.StepperUpdated += ILAstStepperUpdated; @@ -32,9 +41,17 @@ namespace ICSharpCode.ILSpy #endif } + private void WritingOptions_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + DecompileAsync(lastSelectedStep); + } + private void SelectionChanged(object sender, SelectionChangedEventArgs e) { - Dispatcher.Invoke(() => tree.ItemsSource = null); + Dispatcher.Invoke(() => { + tree.ItemsSource = null; + lastSelectedStep = int.MaxValue; + }); } private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) @@ -57,7 +74,10 @@ namespace ICSharpCode.ILSpy { #if DEBUG if (language == null) return; - Dispatcher.Invoke(() => tree.ItemsSource = language.Stepper.Steps); + Dispatcher.Invoke(() => { + tree.ItemsSource = language.Stepper.Steps; + lastSelectedStep = int.MaxValue; + }); #endif } @@ -71,6 +91,7 @@ namespace ICSharpCode.ILSpy #if DEBUG MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged -= FilterSettings_PropertyChanged; MainWindow.Instance.SelectionChanged -= SelectionChanged; + writingOptions.PropertyChanged -= WritingOptions_PropertyChanged; if (language != null) { language.StepperUpdated -= ILAstStepperUpdated; } @@ -98,8 +119,11 @@ namespace ICSharpCode.ILSpy DecompileAsync(n.BeginStep, true); } + int lastSelectedStep = int.MaxValue; + void DecompileAsync(int step, bool isDebug = false) { + lastSelectedStep = step; var window = MainWindow.Instance; var state = window.TextView.GetState(); window.TextView.DecompileAsync(window.CurrentLanguage, window.SelectedNodes, diff --git a/ILSpy/Languages/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs index a812da2b5..416455600 100644 --- a/ILSpy/Languages/ILAstLanguage.cs +++ b/ILSpy/Languages/ILAstLanguage.cs @@ -53,47 +53,6 @@ namespace ICSharpCode.ILSpy } public override string Name { get { return name; } } - /* - public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) - { - if (!method.HasBody) { - return; - } - - ILAstBuilder astBuilder = new ILAstBuilder(); - ILBlock ilMethod = new ILBlock(); - DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method }; - ilMethod.Body = astBuilder.Build(method, inlineVariables, context); - - if (abortBeforeStep != null) { - new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value); - } - - if (context.CurrentMethodIsAsync) - output.WriteLine("async/await"); - - var allVariables = ilMethod.GetSelfAndChildrenRecursive().Select(e => e.Operand as ILVariable) - .Where(v => v != null && !v.IsParameter).Distinct(); - foreach (ILVariable v in allVariables) { - output.WriteDefinition(v.Name, v); - if (v.Type != null) { - output.Write(" : "); - if (v.IsPinned) - output.Write("pinned "); - v.Type.WriteTo(output, ILNameSyntax.ShortTypeName); - } - if (v.IsGenerated) { - output.Write(" [generated]"); - } - output.WriteLine(); - } - output.WriteLine(); - - foreach (ILNode node in ilMethod.Body) { - node.WriteTo(output); - output.WriteLine(); - } - }*/ internal static IEnumerable GetDebugLanguages() { @@ -141,10 +100,6 @@ namespace ICSharpCode.ILSpy class BlockIL : ILAstLanguage { readonly IReadOnlyList transforms; - readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions { - UseFieldSugar = true, - UseLogicOperationSugar = true - }; public BlockIL(IReadOnlyList transforms) : base("ILAst") { @@ -180,27 +135,11 @@ namespace ICSharpCode.ILSpy OnStepperUpdated(new EventArgs()); } } - (output as ISmartTextOutput)?.AddUIElement(OptionsCheckBox(nameof(writingOptions.UseFieldSugar))); - output.WriteLine(); - (output as ISmartTextOutput)?.AddUIElement(OptionsCheckBox(nameof(writingOptions.UseLogicOperationSugar))); - output.WriteLine(); (output as ISmartTextOutput)?.AddButton(Images.ViewCode, "Show Steps", delegate { DebugSteps.Show(); }); output.WriteLine(); - il.WriteTo(output, writingOptions); - } - - Func OptionsCheckBox(string propertyName) - { - return () => { - var checkBox = new System.Windows.Controls.CheckBox(); - checkBox.Content = propertyName; - checkBox.Cursor = System.Windows.Input.Cursors.Arrow; - checkBox.SetBinding(System.Windows.Controls.CheckBox.IsCheckedProperty, - new System.Windows.Data.Binding(propertyName) { Source = writingOptions }); - return checkBox; - }; + il.WriteTo(output, DebugSteps.Options); } } } From 5fec6bd7f7925816fe3e58cb7d1191269fa7734f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 15:59:22 +0200 Subject: [PATCH 17/84] Implement Interval.WriteTo extension method on ILAst --- .../IL/InstructionOutputExtensions.cs | 11 ++++++ ICSharpCode.Decompiler/IL/Instructions.cs | 37 +++++++++++++++++++ ICSharpCode.Decompiler/IL/Instructions.tt | 1 + .../Instructions/BinaryNumericInstruction.cs | 1 + .../IL/Instructions/Branch.cs | 1 + .../IL/Instructions/CallIndirect.cs | 1 + .../IL/Instructions/CallInstruction.cs | 1 + .../IL/Instructions/Comp.cs | 1 + .../CompoundAssignmentInstruction.cs | 1 + .../IL/Instructions/Conv.cs | 1 + .../IL/Instructions/IfInstruction.cs | 1 + .../IL/Instructions/LdLen.cs | 1 + .../IL/Instructions/Leave.cs | 1 + .../IL/Instructions/LockInstruction.cs | 1 + .../IL/Instructions/MemoryInstructions.cs | 4 ++ .../Instructions/NullCoalescingInstruction.cs | 1 + .../IL/Instructions/SimpleInstruction.cs | 4 ++ .../IL/Instructions/StringToInt.cs | 1 + .../IL/Instructions/SwitchInstruction.cs | 2 + .../IL/Instructions/TryInstruction.cs | 4 ++ .../IL/Instructions/UnaryInstruction.cs | 1 + .../IL/Instructions/UsingInstruction.cs | 1 + 22 files changed, 78 insertions(+) diff --git a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs index 1bc8681ca..d5a79cb1a 100644 --- a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs +++ b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs @@ -18,6 +18,7 @@ using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.IL { @@ -50,5 +51,15 @@ namespace ICSharpCode.Decompiler.IL else output.WriteReference(symbol.Name, symbol); } + + public static void WriteTo(this Interval interval, ITextOutput output, ILAstWritingOptions options) + { + if (!options.ShowILRanges) + return; + if (interval.IsEmpty) + output.Write("[empty] "); + else + output.Write($"[{interval.Start}..{interval.InclusiveEnd}] "); + } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index 2afb023df..cf68e4446 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -297,6 +297,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.argument.WriteTo(output, options); @@ -389,6 +390,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.left.WriteTo(output, options); @@ -816,6 +818,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); variable.WriteTo(output); @@ -2113,6 +2116,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); variable.WriteTo(output); @@ -2187,6 +2191,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); variable.WriteTo(output); @@ -2318,6 +2323,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); variable.WriteTo(output); @@ -2412,6 +2418,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.value.WriteTo(output, options); @@ -2505,6 +2512,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); Disassembler.DisassemblerHelpers.WriteOperand(output, Value); @@ -2541,6 +2549,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.I4; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); Disassembler.DisassemblerHelpers.WriteOperand(output, Value); @@ -2577,6 +2586,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.I8; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); Disassembler.DisassemblerHelpers.WriteOperand(output, Value); @@ -2613,6 +2623,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.F; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); Disassembler.DisassemblerHelpers.WriteOperand(output, Value); @@ -2649,6 +2660,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); Disassembler.DisassemblerHelpers.WriteOperand(output, Value); @@ -2715,6 +2727,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.I; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); method.WriteTo(output); @@ -2762,6 +2775,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); method.WriteTo(output); @@ -2803,6 +2817,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -2841,6 +2856,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); member.WriteTo(output); @@ -3009,6 +3025,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (IsVolatile) output.Write("volatile."); if (UnalignedPrefix > 0) @@ -3149,6 +3166,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (IsVolatile) output.Write("volatile."); if (UnalignedPrefix > 0) @@ -3254,6 +3272,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); field.WriteTo(output); @@ -3295,6 +3314,7 @@ namespace ICSharpCode.Decompiler.IL public IField Field { get { return field; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); field.WriteTo(output); @@ -3342,6 +3362,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3383,6 +3404,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3485,6 +3507,7 @@ namespace ICSharpCode.Decompiler.IL } void OriginalWriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (IsVolatile) output.Write("volatile."); if (UnalignedPrefix > 0) @@ -3609,6 +3632,7 @@ namespace ICSharpCode.Decompiler.IL } void OriginalWriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (IsVolatile) output.Write("volatile."); if (UnalignedPrefix > 0) @@ -3665,6 +3689,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3715,6 +3740,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3765,6 +3791,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3875,6 +3902,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -3920,6 +3948,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return type.GetStackType(); } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -4032,6 +4061,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.I4; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -4217,6 +4247,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (IsReadOnly) output.Write("readonly."); output.Write(OpCode); @@ -4318,6 +4349,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.array.WriteTo(output, options); @@ -4438,6 +4470,7 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType { get { return StackType.O; } } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -4516,6 +4549,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); type.WriteTo(output); @@ -4610,6 +4644,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.value.WriteTo(output, options); @@ -4702,6 +4737,7 @@ namespace ICSharpCode.Decompiler.IL } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); this.value.WriteTo(output, options); @@ -4763,6 +4799,7 @@ namespace ICSharpCode.Decompiler.IL.Patterns } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('('); output.Write(')'); diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 598763260..59c19a742 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -499,6 +499,7 @@ namespace ICSharpCode.Decompiler.IL public IEnumerable WriteToBody { get { + yield return "ILRange.WriteTo(output, options);"; foreach (string line in WriteOpCodePrefix) yield return line; yield return "output.Write(OpCode);"; diff --git a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs index a1a037443..e409973ab 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs @@ -178,6 +178,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write("." + GetOperatorName(Operator)); if (CheckForOverflow) { diff --git a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs index 7085ab6a1..6248f75f7 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs @@ -113,6 +113,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write(' '); output.WriteReference(TargetLabel, (object)targetBlock ?? TargetILOffset, isLocal: true); diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs index 7b74939a2..a2380d5cf 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs @@ -91,6 +91,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("call.indirect "); ReturnType.WriteTo(output); output.Write('('); diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs index f846cb754..915ba74bc 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs @@ -76,6 +76,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (ConstrainedTo != null) { output.Write("constrained["); ConstrainedTo.WriteTo(output, ILNameSyntax.ShortTypeName); diff --git a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs index 371cc4723..b4de5e4c2 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs @@ -175,6 +175,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (options.UseLogicOperationSugar && MatchLogicNot(out var arg)) { output.Write("logic.not("); arg.WriteTo(output, options); diff --git a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs index 7d372c5cf..2b7f34e40 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs @@ -154,6 +154,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write("." + GetOperatorName(Operator)); if (CompoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue) diff --git a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs index 8ba33dec9..235170a07 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs @@ -260,6 +260,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (CheckForOverflow) { output.Write(".ovf"); diff --git a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs index 09ae5a87c..59845c679 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs @@ -78,6 +78,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); if (options.UseLogicOperationSugar) { if (MatchLogicAnd(out var lhs, out var rhs)) { output.Write("logic.and("); diff --git a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs index b654624b0..82f65eb32 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs @@ -40,6 +40,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write('.'); output.Write(resultType); diff --git a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs index 7bdabcc26..38e60cbe1 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs @@ -111,6 +111,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (targetContainer != null) { output.Write(' '); diff --git a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs index 36cd8380e..b38c399bc 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs @@ -28,6 +28,7 @@ namespace ICSharpCode.Decompiler.IL { public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("lock ("); OnExpression.WriteTo(output, options); output.WriteLine(") {"); diff --git a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs index bc8236d05..533973dc0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs @@ -41,6 +41,7 @@ namespace ICSharpCode.Decompiler.IL { if (options.UseFieldSugar) { if (this.MatchLdFld(out var target, out var field)) { + ILRange.WriteTo(output, options); output.Write("ldfld "); Disassembler.DisassemblerHelpers.WriteOperand(output, field); output.Write('('); @@ -48,6 +49,7 @@ namespace ICSharpCode.Decompiler.IL output.Write(')'); return; } else if (this.MatchLdsFld(out field)) { + ILRange.WriteTo(output, options); output.Write("ldsfld "); Disassembler.DisassemblerHelpers.WriteOperand(output, field); return; @@ -63,6 +65,7 @@ namespace ICSharpCode.Decompiler.IL { if (options.UseFieldSugar) { if (this.MatchStFld(out var target, out var field, out var value)) { + ILRange.WriteTo(output, options); output.Write("stfld "); Disassembler.DisassemblerHelpers.WriteOperand(output, field); output.Write('('); @@ -72,6 +75,7 @@ namespace ICSharpCode.Decompiler.IL output.Write(')'); return; } else if (this.MatchStsFld(out field, out value)) { + ILRange.WriteTo(output, options); output.Write("stsfld "); Disassembler.DisassemblerHelpers.WriteOperand(output, field); output.Write('('); diff --git a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs index fd4385d1d..04606493a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs @@ -91,6 +91,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); output.Write("("); valueInst.WriteTo(output, options); diff --git a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs index 18f5b6f6f..82657c6bb 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs @@ -26,6 +26,7 @@ namespace ICSharpCode.Decompiler.IL { public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); // the non-custom WriteTo would add useless parentheses } @@ -37,6 +38,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (!string.IsNullOrEmpty(Comment)) { output.Write(" // " + Comment); @@ -60,6 +62,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (!string.IsNullOrEmpty(Message)) { output.Write("(\""); @@ -86,6 +89,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (!string.IsNullOrEmpty(Message)) { output.Write("(\""); diff --git a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs index f804a3928..9ac94e591 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs @@ -32,6 +32,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("string.to.int ("); Argument.WriteTo(output, options); output.Write(", { "); diff --git a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs index ae828983f..7cba520d6 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs @@ -76,6 +76,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("switch"); if (IsLifted) output.Write(".lifted"); @@ -180,6 +181,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.WriteDefinition("case", this, isLocal: true); output.Write(' '); if (HasNullLabel) { diff --git a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs index 033d1cba0..b53611c42 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs @@ -67,6 +67,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(".try "); TryBlock.WriteTo(output, options); foreach (var handler in Handlers) { @@ -161,6 +162,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("catch "); if (variable != null) { output.WriteDefinition(variable.Name, variable); @@ -202,6 +204,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(".try "); TryBlock.WriteTo(output, options); output.Write(" finally "); @@ -297,6 +300,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(".try "); TryBlock.WriteTo(output, options); output.Write(" fault "); diff --git a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs index 52d489a0c..0773fc888 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs @@ -51,6 +51,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (IsLifted) { output.Write(".lifted"); diff --git a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs index 795be5914..2a9e79ce3 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs @@ -38,6 +38,7 @@ namespace ICSharpCode.Decompiler.IL { public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("using ("); Variable.WriteTo(output); output.Write(" = "); From 81e6f0c9bb7e2e518016bd5e60e05c7f9880f723 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 16:13:51 +0200 Subject: [PATCH 18/84] Improve ILRange output in ILAst --- ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs | 2 +- ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs index d5a79cb1a..33b5cbc88 100644 --- a/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs +++ b/ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs @@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler.IL if (interval.IsEmpty) output.Write("[empty] "); else - output.Write($"[{interval.Start}..{interval.InclusiveEnd}] "); + output.Write($"[{interval.Start:x4}..{interval.InclusiveEnd:x4}] "); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index 7fd03b666..523f6218e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -85,6 +85,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write(OpCode); if (Method != null) { output.Write(' '); From c2a7c806f0e39e78191c4ca13df4df1724b16a1d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 16:51:27 +0200 Subject: [PATCH 19/84] Add missing annotations after TranslateFunction --- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 3 ++- ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index 23f0add1a..519eb2ae2 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -323,7 +323,8 @@ namespace ICSharpCode.Decompiler.CSharp break; case OpCode.ILFunction: method = ((ILFunction)func).Method; - return expressionBuilder.TranslateFunction(inst.Method.DeclaringType, (ILFunction)func); + return expressionBuilder.TranslateFunction(inst.Method.DeclaringType, (ILFunction)func) + .WithILInstruction(inst); default: throw new ArgumentException($"Unknown instruction type: {func.OpCode}"); } diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 25ed0ddb3..f2f252d4b 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1026,7 +1026,7 @@ namespace ICSharpCode.Decompiler.CSharp return new CallBuilder(this, typeSystem, settings).Build(inst); } - internal TranslatedExpression TranslateFunction(IType delegateType, ILFunction function) + internal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function) { var method = function.Method.MemberDefinition as IMethod; Debug.Assert(method != null); @@ -1098,7 +1098,7 @@ namespace ICSharpCode.Decompiler.CSharp TranslatedExpression translatedLambda = replacement.WithILInstruction(function).WithRR(rr); return new CastExpression(ConvertType(delegateType), translatedLambda) - .WithoutILInstruction().WithRR(new ConversionResolveResult(delegateType, rr, LambdaConversion.Instance)); + .WithRR(new ConversionResolveResult(delegateType, rr, LambdaConversion.Instance)); } IType InferReturnType(BlockStatement body) From 84592fcc6fe31d1b9f5456ade3c2e91f8afa5373 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 17:20:26 +0200 Subject: [PATCH 20/84] Prevent SequencePointBuilder from combining sequence points of lambda expressions. --- ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs | 8 +++++++- ILSpy/Languages/CSharpILMixedLanguage.cs | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 463ff1e1c..2519cdd30 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -120,6 +120,12 @@ namespace ICSharpCode.Decompiler.CSharp } } + public override void VisitLambdaExpression(LambdaExpression lambdaExpression) + { + AddToSequencePoint(lambdaExpression); + VisitAsSequencePoint(lambdaExpression.Body); + } + /// /// Start a new C# statement = new sequence point. /// @@ -160,7 +166,7 @@ namespace ICSharpCode.Decompiler.CSharp void AddToSequencePoint(ILInstruction inst) { - if (!mappedInstructions.Add(inst)) { + if (!mappedInstructions.Add(inst) || inst is ILFunction) { // inst was already used by a nested sequence point within this sequence point return; } diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 73340f695..da1297021 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -69,7 +69,8 @@ namespace ICSharpCode.ILSpy CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); var st = decompiler.Decompile(method); WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem); - this.sequencePoints = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.CecilMethod == method).Value ?? (IList)EmptyList.Instance; + var mapping = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.CecilMethod == method); + this.sequencePoints = mapping.Value ?? (IList)EmptyList.Instance; this.codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); base.Disassemble(body); } finally { From b7d4636f801c2094274cc2dd403de7e899a169f1 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 17:37:33 +0200 Subject: [PATCH 21/84] Implement ILInstruction.AddILRange() --- .../IL/Instructions/ILInstruction.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index d0bce881a..433bf39d8 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -208,10 +208,26 @@ namespace ICSharpCode.Decompiler.IL /// public Interval ILRange; - public void AddILRange(Interval ilRange) + public void AddILRange(Interval newRange) { - // TODO: try to combine the two ranges - this.ILRange = ilRange; + if (newRange.IsEmpty) { + return; + } + if (this.ILRange.IsEmpty) { + this.ILRange = newRange; + return; + } + if (newRange.Start <= this.ILRange.Start) { + if (newRange.End < this.ILRange.Start) { + this.ILRange = newRange; // use the earlier range + } else { + // join overlapping ranges + this.ILRange = new Interval(newRange.Start, Math.Max(newRange.End, this.ILRange.End)); + } + } else if (newRange.Start <= this.ILRange.End) { + // join overlapping ranges + this.ILRange = new Interval(this.ILRange.Start, Math.Max(newRange.End, this.ILRange.End)); + } } /// From 5e50294c8266a124eee25eab7d4302292f1368ef Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 17:46:41 +0200 Subject: [PATCH 22/84] Fix ILRange of ILFunction in DelegateConstruction --- ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs index 42de10379..62bf0ac17 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs @@ -43,7 +43,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms foreach (var call in block.Instructions[i].Descendants.OfType()) { ILFunction f = TransformDelegateConstruction(call, out ILInstruction target); if (f != null) { - call.Arguments[0].ReplaceWith(new Nop()); + f.AddILRange(call.Arguments[0].ILRange); + f.AddILRange(call.Arguments[1].ILRange); + call.Arguments[0].ReplaceWith(new LdNull()); call.Arguments[1].ReplaceWith(f); if (target is IInstructionWithVariableOperand && !target.MatchLdThis()) targetsToReplace.Add((IInstructionWithVariableOperand)target); From f890900d4d3aff1da2a65293778a9f40e805ab4b Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 17:47:43 +0200 Subject: [PATCH 23/84] Fix AddToSequencePoint for ILFunction --- ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 2519cdd30..e86825bc5 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -166,15 +166,20 @@ namespace ICSharpCode.Decompiler.CSharp void AddToSequencePoint(ILInstruction inst) { - if (!mappedInstructions.Add(inst) || inst is ILFunction) { + if (!mappedInstructions.Add(inst)) { // inst was already used by a nested sequence point within this sequence point return; } // Add the IL range associated with this instruction to the current sequence point. if (!inst.ILRange.IsEmpty && current.Intervals != null) { current.Intervals.Add(inst.ILRange); - current.Function = inst.Ancestors.OfType().FirstOrDefault(); + current.Function = inst.Parent.Ancestors.OfType().FirstOrDefault(); } + + // Do not add instructions of lambdas/delegates. + if (inst is ILFunction) + return; + // Also add the child IL instructions, unless they were already processed by // another C# expression. foreach (var child in inst.Children) { From d2b66515074b039be4ef38bb62ddfa675a96101f Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 18:58:41 +0200 Subject: [PATCH 24/84] ILAst: show unused IL ranges --- .../CSharp/SequencePointBuilder.cs | 20 ++++++++++-- .../IL/ILAstWritingOptions.cs | 21 +++++++++++-- .../IL/Instructions/Block.cs | 1 + .../IL/Instructions/BlockContainer.cs | 1 + .../IL/Instructions/ILFunction.cs | 31 ++++++++++++++++++- 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index e86825bc5..a4528113f 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -171,9 +171,11 @@ namespace ICSharpCode.Decompiler.CSharp return; } // Add the IL range associated with this instruction to the current sequence point. - if (!inst.ILRange.IsEmpty && current.Intervals != null) { + if (HasUsableILRange(inst) && current.Intervals != null) { current.Intervals.Add(inst.ILRange); - current.Function = inst.Parent.Ancestors.OfType().FirstOrDefault(); + var function = inst.Parent.Ancestors.OfType().FirstOrDefault(); + Debug.Assert(current.Function == null || current.Function == function); + current.Function = function; } // Do not add instructions of lambdas/delegates. @@ -187,6 +189,13 @@ namespace ICSharpCode.Decompiler.CSharp } } + internal static bool HasUsableILRange(ILInstruction inst) + { + if (inst.ILRange.IsEmpty) + return false; + return !(inst is BlockContainer || inst is Block); + } + /// /// Called after the visitor is done to return the results. /// @@ -227,6 +236,13 @@ namespace ICSharpCode.Decompiler.CSharp newList.Add(sequencePoint); pos = sequencePoint.EndOffset; } + if (pos < function.CecilMethod.Body.CodeSize) { + var hidden = new SequencePoint(); + hidden.Offset = pos; + hidden.EndOffset = function.CecilMethod.Body.CodeSize; + hidden.SetHidden(); + newList.Add(hidden); + } dict[function] = newList; } return dict; diff --git a/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs index 42b8ddf66..3b6098d1c 100644 --- a/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs +++ b/ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs @@ -1,8 +1,23 @@ -using System; -using System.Collections.Generic; +// Copyright (c) 2017 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 System.ComponentModel; using System.Runtime.CompilerServices; -using System.Text; namespace ICSharpCode.Decompiler.IL { diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index 0c5f9b7cc..8548717bc 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -129,6 +129,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.Write("Block "); output.WriteDefinition(Label, this); if (Parent is BlockContainer) diff --git a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs index b70056841..099f553a4 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs @@ -107,6 +107,7 @@ namespace ICSharpCode.Decompiler.IL public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { + ILRange.WriteTo(output, options); output.WriteDefinition("BlockContainer", this); output.Write(' '); output.MarkFoldStart("{...}"); diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index 523f6218e..4424ba4f5 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -114,12 +114,41 @@ namespace ICSharpCode.Decompiler.IL } body.WriteTo(output, options); - output.WriteLine(); + + if (options.ShowILRanges) { + var unusedILRanges = FindUnusedILRanges(); + if (!unusedILRanges.IsEmpty) { + output.Write("// Unused IL Ranges: "); + output.Write(string.Join(", ", unusedILRanges.Intervals.Select( + range => $"[{range.Start:x4}..{range.InclusiveEnd:x4}]"))); + output.WriteLine(); + } + } + output.Unindent(); output.WriteLine("}"); } + LongSet FindUnusedILRanges() + { + var usedILRanges = new List(); + MarkUsedILRanges(body); + return new LongSet(new LongInterval(0, CecilMethod.Body.CodeSize)).ExceptWith(new LongSet(usedILRanges)); + + void MarkUsedILRanges(ILInstruction inst) + { + if (CSharp.SequencePointBuilder.HasUsableILRange(inst)) { + usedILRanges.Add(new LongInterval(inst.ILRange.Start, inst.ILRange.End)); + } + if (!(inst is ILFunction)) { + foreach (var child in inst.Children) { + MarkUsedILRanges(child); + } + } + } + } + protected override InstructionFlags ComputeFlags() { // Creating a lambda may throw OutOfMemoryException From 462d0da7b6449b5a22d99d59820b6120684623e2 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 14 Oct 2017 19:31:10 +0200 Subject: [PATCH 25/84] Add feature to the MethodBodyDisassembler that shows sequence points from PDB in disassembled IL. --- .../Helpers/Tester.cs | 3 +- .../Disassembler/MethodBodyDisassembler.cs | 42 +++++++++++++++---- .../Disassembler/ReflectionDisassembler.cs | 14 ++++++- ICSharpCode.Decompiler/IL/ILReader.cs | 3 +- ILSpy/Languages/CSharpILMixedLanguage.cs | 11 +++-- ILSpy/Languages/ILAstLanguage.cs | 2 +- ILSpy/Languages/ILLanguage.cs | 5 ++- 7 files changed, 63 insertions(+), 17 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index 3fa97ed6f..05de0357e 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -111,7 +111,8 @@ namespace ICSharpCode.Decompiler.Tests.Helpers using (var writer = new StreamWriter(outputFile)) { module.Name = Path.GetFileNameWithoutExtension(outputFile); var output = new PlainTextOutput(writer); - ReflectionDisassembler rd = new ReflectionDisassembler(output, false, CancellationToken.None); + ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None); + rd.DetectControlStructure = false; rd.WriteAssemblyReferences(module); if (module.Assembly != null) rd.WriteAssemblyHeader(module.Assembly); diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index c5860c7cb..24a1fb3b8 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Threading; using Mono.Cecil; using Mono.Cecil.Cil; +using Mono.Collections.Generic; namespace ICSharpCode.Decompiler.Disassembler { @@ -30,15 +31,24 @@ namespace ICSharpCode.Decompiler.Disassembler public class MethodBodyDisassembler { readonly ITextOutput output; - readonly bool detectControlStructure; readonly CancellationToken cancellationToken; - public MethodBodyDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken) + /// + /// Show .try/finally as blocks in IL code; indent loops. + /// + public bool DetectControlStructure { get; set; } = true; + + /// + /// Show sequence points if debug information is loaded in Cecil. + /// + public bool ShowSequencePoints { get; set; } + + Collection sequencePoints; + int nextSequencePointIndex; + + public MethodBodyDisassembler(ITextOutput output, CancellationToken cancellationToken) { - if (output == null) - throw new ArgumentNullException(nameof(output)); - this.output = output; - this.detectControlStructure = detectControlStructure; + this.output = output ?? throw new ArgumentNullException(nameof(output)); this.cancellationToken = cancellationToken; } @@ -55,7 +65,9 @@ namespace ICSharpCode.Decompiler.Disassembler DisassembleLocalsBlock(body); output.WriteLine(); - if (detectControlStructure && body.Instructions.Count > 0) { + sequencePoints = method.DebugInformation?.SequencePoints; + nextSequencePointIndex = 0; + if (DetectControlStructure && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; HashSet branchTargets = GetBranchTargets(body.Instructions); WriteStructureBody(new ILStructure(body), branchTargets, ref inst, method.Body.CodeSize); @@ -66,6 +78,7 @@ namespace ICSharpCode.Decompiler.Disassembler } WriteExceptionHandlers(body); } + sequencePoints = null; } private void DisassembleLocalsBlock(MethodBody body) @@ -215,6 +228,21 @@ namespace ICSharpCode.Decompiler.Disassembler protected virtual void WriteInstruction(ITextOutput output, Instruction instruction) { + if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) { + SequencePoint sp = sequencePoints[nextSequencePointIndex]; + if (sp.Offset <= instruction.Offset) { + output.Write("// sequence point: "); + if (sp.Offset != instruction.Offset) { + output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!"); + } + if (sp.IsHidden) { + output.WriteLine("hidden"); + } else { + output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.Document?.Url}"); + } + nextSequencePointIndex++; + } + } instruction.WriteTo(output); } } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index 6137fc0d5..851c47842 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -35,8 +35,18 @@ namespace ICSharpCode.Decompiler.Disassembler MethodBodyDisassembler methodBodyDisassembler; MemberReference currentMember; - public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken) - : this(output, new MethodBodyDisassembler(output, detectControlStructure, cancellationToken), cancellationToken) + public bool DetectControlStructure { + get => methodBodyDisassembler.DetectControlStructure; + set => methodBodyDisassembler.DetectControlStructure = value; + } + + public bool ShowSequencePoints { + get => methodBodyDisassembler.ShowSequencePoints; + set => methodBodyDisassembler.ShowSequencePoints = value; + } + + public ReflectionDisassembler(ITextOutput output, CancellationToken cancellationToken) + : this(output, new MethodBodyDisassembler(output, cancellationToken), cancellationToken) { } diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 866fe7afd..91689aef7 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -304,7 +304,8 @@ namespace ICSharpCode.Decompiler.IL inst.WriteTo(output, new ILAstWritingOptions()); output.WriteLine(); } - new Disassembler.MethodBodyDisassembler(output, false, cancellationToken).WriteExceptionHandlers(body); + new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false } + .WriteExceptionHandlers(body); } /// diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index da1297021..1e027fae8 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -28,7 +28,10 @@ namespace ICSharpCode.ILSpy protected override ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options) { return new ReflectionDisassembler(output, - new MixedMethodBodyDisassembler(output, detectControlStructure, options), + new MixedMethodBodyDisassembler(output, options) { + DetectControlStructure = detectControlStructure, + ShowSequencePoints = true + }, options.CancellationToken); } @@ -55,8 +58,8 @@ namespace ICSharpCode.ILSpy // lines of raw c# source code string[] codeLines; - public MixedMethodBodyDisassembler(ITextOutput output, bool detectControlStructure, DecompilationOptions options) - : base(output, detectControlStructure, options.CancellationToken) + public MixedMethodBodyDisassembler(ITextOutput output, DecompilationOptions options) + : base(output, options.CancellationToken) { this.options = options; } @@ -102,7 +105,7 @@ namespace ICSharpCode.ILSpy } else { output.Write("// "); highlightingOutput?.BeginSpan(gray); - output.WriteLine("(hidden sequence point)"); + output.WriteLine("(no C# code)"); highlightingOutput?.EndSpan(); } } diff --git a/ILSpy/Languages/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs index 416455600..88a6601e6 100644 --- a/ILSpy/Languages/ILAstLanguage.cs +++ b/ILSpy/Languages/ILAstLanguage.cs @@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { base.DecompileMethod(method, output, options); - new ReflectionDisassembler(output, false, options.CancellationToken).DisassembleMethodHeader(method); + new ReflectionDisassembler(output, options.CancellationToken).DisassembleMethodHeader(method); output.WriteLine(); output.WriteLine(); } diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index 71dec3ee7..24aeedfba 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -46,7 +46,10 @@ namespace ICSharpCode.ILSpy protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options) { - return new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + return new ReflectionDisassembler(output, options.CancellationToken) { + DetectControlStructure = detectControlStructure, + ShowSequencePoints = true + }; } public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) From 79d3ff10a32581bb30a1325bfbff70be0002b247 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 20:00:21 +0200 Subject: [PATCH 26/84] Add setting ShowDebugInfo --- ICSharpCode.Decompiler/DecompilerSettings.cs | 17 +++++++++++++++-- ILSpy/Languages/CSharpILMixedLanguage.cs | 2 +- ILSpy/Languages/ILLanguage.cs | 2 +- ILSpy/Options/DecompilerSettingsPanel.xaml | 1 + ILSpy/Options/DecompilerSettingsPanel.xaml.cs | 2 ++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index 50f744e6d..6d6e16d21 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -360,8 +360,21 @@ namespace ICSharpCode.Decompiler } } } + + bool showDebugInfo; + + public bool ShowDebugInfo { + get { return showDebugInfo; } + set { + if (showDebugInfo != value) { + showDebugInfo = value; + OnPropertyChanged(); + } + } + } + #endregion - + CSharpFormattingOptions csharpFormattingOptions; public CSharpFormattingOptions CSharpFormattingOptions { @@ -382,7 +395,7 @@ namespace ICSharpCode.Decompiler } } } - + public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 1e027fae8..39d659093 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy return new ReflectionDisassembler(output, new MixedMethodBodyDisassembler(output, options) { DetectControlStructure = detectControlStructure, - ShowSequencePoints = true + ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo }, options.CancellationToken); } diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index 24aeedfba..9e618150a 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -48,7 +48,7 @@ namespace ICSharpCode.ILSpy { return new ReflectionDisassembler(output, options.CancellationToken) { DetectControlStructure = detectControlStructure, - ShowSequencePoints = true + ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo }; } diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml b/ILSpy/Options/DecompilerSettingsPanel.xaml index ecad2b28b..e43c553d3 100644 --- a/ILSpy/Options/DecompilerSettingsPanel.xaml +++ b/ILSpy/Options/DecompilerSettingsPanel.xaml @@ -11,6 +11,7 @@ Decompile expression trees Decompile automatic properties Use variable names from debug symbols, if available + Show info from debug symbols, if available Show XML documentation in decompiled code Enable folding on all blocks in braces diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs index b013aa708..8541be53d 100644 --- a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs +++ b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs @@ -58,6 +58,7 @@ namespace ICSharpCode.ILSpy.Options s.QueryExpressions = (bool?)e.Attribute("queryExpressions") ?? s.QueryExpressions; s.ExpressionTrees = (bool?)e.Attribute("expressionTrees") ?? s.ExpressionTrees; s.UseDebugSymbols = (bool?)e.Attribute("useDebugSymbols") ?? s.UseDebugSymbols; + s.ShowDebugInfo = (bool?)e.Attribute("showDebugInfo") ?? s.ShowDebugInfo; s.ShowXmlDocumentation = (bool?)e.Attribute("xmlDoc") ?? s.ShowXmlDocumentation; s.FoldBraces = (bool?)e.Attribute("foldBraces") ?? s.FoldBraces; return s; @@ -75,6 +76,7 @@ namespace ICSharpCode.ILSpy.Options section.SetAttributeValue("queryExpressions", s.QueryExpressions); section.SetAttributeValue("expressionTrees", s.ExpressionTrees); section.SetAttributeValue("useDebugSymbols", s.UseDebugSymbols); + section.SetAttributeValue("showDebugInfo", s.ShowDebugInfo); section.SetAttributeValue("xmlDoc", s.ShowXmlDocumentation); section.SetAttributeValue("foldBraces", s.FoldBraces); From 2169d44c81a39c518d68fd8d1224f1fa4d22a5b8 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 20:00:44 +0200 Subject: [PATCH 27/84] Implement sequence points for using statement. --- ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs | 9 +++++++++ ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index a4528113f..3486542ee 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -126,6 +126,15 @@ namespace ICSharpCode.Decompiler.CSharp VisitAsSequencePoint(lambdaExpression.Body); } + public override void VisitUsingStatement(UsingStatement usingStatement) + { + StartSequencePoint(usingStatement); + usingStatement.ResourceAcquisition.AcceptVisitor(this); + VisitAsSequencePoint(usingStatement.EmbeddedStatement); + AddToSequencePoint(usingStatement); + EndSequencePoint(usingStatement.StartLocation, usingStatement.RParToken.EndLocation); + } + /// /// Start a new C# statement = new sequence point. /// diff --git a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs index 1c64d2983..3d6cd1639 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs @@ -87,7 +87,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms context.Step("UsingTransform", tryFinally); storeInst.Variable.Kind = VariableKind.UsingLocal; block.Instructions.RemoveAt(i); - block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock); + block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock) { ILRange = storeInst.ILRange }; return true; } From 4ca4d97011b289ebfe84e628548c087bb2e17905 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 14 Oct 2017 22:47:59 +0200 Subject: [PATCH 28/84] Improve SequencePointBuilder --- ICSharpCode.Decompiler/CSharp/Annotations.cs | 14 ++++++++ .../CSharp/NRefactoryExtensions.cs | 14 ++++++-- .../InsertMissingTokensDecorator.cs | 5 ++- .../CSharp/SequencePointBuilder.cs | 32 +++++++++++++++++++ .../CSharp/StatementBuilder.cs | 1 + .../ReplaceMethodCallsWithOperators.cs | 4 ++- .../ControlFlow/ControlFlowSimplification.cs | 20 +++++++++--- ICSharpCode.Decompiler/IL/ILReader.cs | 2 +- .../IL/Instructions/SimpleInstruction.cs | 11 +++++++ .../IL/Transforms/CopyPropagation.cs | 3 ++ .../IL/Transforms/LockTransform.cs | 6 ++-- 11 files changed, 100 insertions(+), 12 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Annotations.cs b/ICSharpCode.Decompiler/CSharp/Annotations.cs index dde037429..40d1b5f93 100644 --- a/ICSharpCode.Decompiler/CSharp/Annotations.cs +++ b/ICSharpCode.Decompiler/CSharp/Annotations.cs @@ -164,4 +164,18 @@ namespace ICSharpCode.Decompiler.CSharp this.Variable = v; } } + + public class ForeachAnnotation + { + public readonly ILInstruction GetEnumeratorCall; + public readonly ILInstruction MoveNextCall; + public readonly ILInstruction GetCurrentCall; + + public ForeachAnnotation(ILInstruction getEnumeratorCall, ILInstruction moveNextCall, ILInstruction getCurrentCall) + { + GetEnumeratorCall = getEnumeratorCall; + MoveNextCall = moveNextCall; + GetCurrentCall = getCurrentCall; + } + } } diff --git a/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs b/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs index af2cce2b5..a1f3bb3d2 100644 --- a/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs +++ b/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs @@ -17,8 +17,10 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; +using ICSharpCode.Decompiler.IL; namespace ICSharpCode.Decompiler.CSharp { @@ -31,7 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp node.AddAnnotation(annotation); return node; } - + public static T CopyAnnotationsFrom(this T node, AstNode other) where T : AstNode { foreach (object annotation in other.Annotations) { @@ -39,7 +41,15 @@ namespace ICSharpCode.Decompiler.CSharp } return node; } - + + public static T CopyInstructionsFrom(this T node, AstNode other) where T : AstNode + { + foreach (object annotation in other.Annotations.OfType()) { + node.AddAnnotation(annotation); + } + return node; + } + public static T Detach(this T node) where T : AstNode { node.Remove(); diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs index 1e20d061a..8748eff1b 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs @@ -88,7 +88,10 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor if (node != null) node.Location = start; } - if (t != null) currentList.Add(t); + if (t != null) { + currentList.Add(t); + t.Role = role; + } base.WriteKeyword(role, keyword); } diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 3486542ee..24aa6e164 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -135,6 +135,36 @@ namespace ICSharpCode.Decompiler.CSharp EndSequencePoint(usingStatement.StartLocation, usingStatement.RParToken.EndLocation); } + public override void VisitForeachStatement(ForeachStatement foreachStatement) + { + var foreachInfo = foreachStatement.Annotation(); + if (foreachInfo == null) { + base.VisitForeachStatement(foreachStatement); + return; + } + // TODO : Add a sequence point on foreach token (mapped to nop before using instruction). + StartSequencePoint(foreachStatement); + foreachStatement.InExpression.AcceptVisitor(this); + AddToSequencePoint(foreachInfo.GetEnumeratorCall); + EndSequencePoint(foreachStatement.InExpression.StartLocation, foreachStatement.InExpression.EndLocation); + StartSequencePoint(foreachStatement); + AddToSequencePoint(foreachInfo.MoveNextCall); + EndSequencePoint(foreachStatement.InToken.StartLocation, foreachStatement.InToken.EndLocation); + StartSequencePoint(foreachStatement); + AddToSequencePoint(foreachInfo.GetCurrentCall); + EndSequencePoint(foreachStatement.VariableType.StartLocation, foreachStatement.VariableNameToken.EndLocation); + VisitAsSequencePoint(foreachStatement.EmbeddedStatement); + } + + public override void VisitLockStatement(LockStatement lockStatement) + { + StartSequencePoint(lockStatement); + lockStatement.Expression.AcceptVisitor(this); + VisitAsSequencePoint(lockStatement.EmbeddedStatement); + AddToSequencePoint(lockStatement); + EndSequencePoint(lockStatement.StartLocation, lockStatement.RParToken.EndLocation); + } + /// /// Start a new C# statement = new sequence point. /// @@ -146,6 +176,8 @@ namespace ICSharpCode.Decompiler.CSharp void EndSequencePoint(TextLocation startLocation, TextLocation endLocation) { + Debug.Assert(!startLocation.IsEmpty, "missing startLocation"); + Debug.Assert(!endLocation.IsEmpty, "missing endLocation"); if (current.Intervals.Count > 0 && current.Function != null) { // use LongSet to deduplicate and merge the intervals var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End))); diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 909339d6d..f6cc29304 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -506,6 +506,7 @@ namespace ICSharpCode.Decompiler.CSharp }; // Add the variable annotation for highlighting (TokenTextWriter expects it directly on the ForeachStatement). foreachStmt.AddAnnotation(new ILVariableResolveResult(foreachVariable, foreachVariable.Type)); + foreachStmt.AddAnnotation(new ForeachAnnotation(inst.ResourceExpression, loop.Conditions.Single(), singleGetter)); // If there was an optional return statement, return it as well. if (optionalReturnAfterLoop != null) { return new BlockStatement { diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs index 96e9a9516..fa7001f30 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs @@ -69,7 +69,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms case "System.Type.GetTypeFromHandle": if (arguments.Length == 1) { if (typeHandleOnTypeOfPattern.IsMatch(arguments[0])) { - invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target); + Expression target = ((MemberReferenceExpression)arguments[0]).Target; + target.CopyInstructionsFrom(invocationExpression); + invocationExpression.ReplaceWith(target); return; } } diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs index a896ca11a..6e336377e 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs @@ -44,9 +44,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow foreach (var block in function.Descendants.OfType()) { context.CancellationToken.ThrowIfCancellationRequested(); - // Remove 'nop' instructions - block.Instructions.RemoveAll(inst => inst.OpCode == OpCode.Nop); - + RemoveNopInstructions(block); + InlineVariableInReturnBlock(block, context); // 1st pass SimplifySwitchInstruction before SimplifyBranchChains() // starts duplicating return instructions. @@ -55,7 +54,20 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow SimplifyBranchChains(function, context); CleanUpEmptyBlocks(function, context); } - + + private static void RemoveNopInstructions(Block block) + { + // Move ILRanges of special nop instructions to the previous non-nop instruction. + for (int i = block.Instructions.Count - 1; i > 0; i--) { + if (block.Instructions[i] is Nop nop && nop.Kind == NopKind.Pop) { + block.Instructions[i - 1].AddILRange(nop.ILRange); + } + } + + // Remove 'nop' instructions + block.Instructions.RemoveAll(inst => inst.OpCode == OpCode.Nop); + } + void InlineVariableInReturnBlock(Block block, ILTransformContext context) { // In debug mode, the C#-compiler generates 'return blocks' that diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 91689aef7..4ddfb54fb 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -650,7 +650,7 @@ namespace ICSharpCode.Decompiler.IL return BinaryNumeric(BinaryNumericOperator.BitOr); case Cil.Code.Pop: Pop(); - return new Nop(); + return new Nop() { Kind = NopKind.Pop }; case Cil.Code.Rem: return BinaryNumeric(BinaryNumericOperator.Rem, false, Sign.Signed); case Cil.Code.Rem_Un: diff --git a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs index 82657c6bb..bb3432835 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs @@ -31,15 +31,26 @@ namespace ICSharpCode.Decompiler.IL // the non-custom WriteTo would add useless parentheses } } + + public enum NopKind + { + Normal, + Pop + } partial class Nop { public string Comment; + public NopKind Kind; + public override void WriteTo(ITextOutput output, ILAstWritingOptions options) { ILRange.WriteTo(output, options); output.Write(OpCode); + if (Kind != NopKind.Normal) { + output.Write("." + Kind.ToString().ToLowerInvariant()); + } if (!string.IsNullOrEmpty(Comment)) { output.Write(" // " + Comment); } diff --git a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs index ea1e61834..91a79c6c4 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs @@ -51,9 +51,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms // dead store to stack if (copiedExpr.Flags == InstructionFlags.None) { // no-op -> delete + context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i - 1]); block.Instructions.RemoveAt(i--); } else { // evaluate the value for its side-effects + context.Step("remove dead store to stack: evaluate the value for its side-effects", block.Instructions[i]); + copiedExpr.AddILRange(block.Instructions[i].ILRange); block.Instructions[i] = copiedExpr; } } else if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) { diff --git a/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs index e09c0a2b8..cc497af74 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms context.Step("LockTransformV2", block); block.Instructions.RemoveAt(i - 1); block.Instructions.RemoveAt(i - 2); - body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock)); + body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange }); return true; } @@ -127,7 +127,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms context.Step("LockTransformV4", block); block.Instructions.RemoveAt(i - 1); tryContainer.EntryPoint.Instructions.RemoveAt(0); - body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock)); + body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange }); return true; } @@ -173,7 +173,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms block.Instructions.RemoveAt(i - 1); block.Instructions.RemoveAt(i - 2); tryContainer.EntryPoint.Instructions.RemoveAt(0); - body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock)); + body.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock) { ILRange = objectStore.ILRange }); return true; } From a0ed79156775ef2715342694d1d8e339630f5115 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 15 Oct 2017 10:17:55 +0200 Subject: [PATCH 29/84] SequencePointBuilder: add support for if-statement, while-statement and do-while-statement --- .../CSharp/SequencePointBuilder.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 24aa6e164..3e3e66e2e 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -67,6 +67,7 @@ namespace ICSharpCode.Decompiler.CSharp void VisitAsSequencePoint(AstNode node) { + if (node.IsNull) return; StartSequencePoint(node); node.AcceptVisitor(this); EndSequencePoint(node.StartLocation, node.EndLocation); @@ -165,6 +166,34 @@ namespace ICSharpCode.Decompiler.CSharp EndSequencePoint(lockStatement.StartLocation, lockStatement.RParToken.EndLocation); } + public override void VisitIfElseStatement(IfElseStatement ifElseStatement) + { + StartSequencePoint(ifElseStatement); + ifElseStatement.Condition.AcceptVisitor(this); + VisitAsSequencePoint(ifElseStatement.TrueStatement); + VisitAsSequencePoint(ifElseStatement.FalseStatement); + AddToSequencePoint(ifElseStatement); + EndSequencePoint(ifElseStatement.StartLocation, ifElseStatement.RParToken.EndLocation); + } + + public override void VisitWhileStatement(WhileStatement whileStatement) + { + StartSequencePoint(whileStatement); + whileStatement.Condition.AcceptVisitor(this); + VisitAsSequencePoint(whileStatement.EmbeddedStatement); + AddToSequencePoint(whileStatement); + EndSequencePoint(whileStatement.StartLocation, whileStatement.RParToken.EndLocation); + } + + public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement) + { + StartSequencePoint(doWhileStatement); + VisitAsSequencePoint(doWhileStatement.EmbeddedStatement); + doWhileStatement.Condition.AcceptVisitor(this); + AddToSequencePoint(doWhileStatement); + EndSequencePoint(doWhileStatement.WhileToken.StartLocation, doWhileStatement.RParToken.EndLocation); + } + /// /// Start a new C# statement = new sequence point. /// From 451104381576a349602cca77509d1016a0243041 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 15 Oct 2017 10:36:09 +0200 Subject: [PATCH 30/84] SequencePointBuilder: add support for fixed-statement --- ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 3e3e66e2e..0daf76ab6 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -194,6 +194,14 @@ namespace ICSharpCode.Decompiler.CSharp EndSequencePoint(doWhileStatement.WhileToken.StartLocation, doWhileStatement.RParToken.EndLocation); } + public override void VisitFixedStatement(FixedStatement fixedStatement) + { + foreach (var v in fixedStatement.Variables) { + VisitAsSequencePoint(v); + } + VisitAsSequencePoint(fixedStatement.EmbeddedStatement); + } + /// /// Start a new C# statement = new sequence point. /// From e34480527d6ec873afa4e558b1b8ddb1a14551ac Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 15 Oct 2017 11:08:34 +0200 Subject: [PATCH 31/84] Fix line tracking when printing single-line comments. --- .../CSharp/OutputVisitor/TextWriterOutputFormatter.cs | 6 ++++-- ILSpy/Languages/CSharpILMixedLanguage.cs | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs index 8d93ada89..a0f37ff74 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs @@ -128,7 +128,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor case CommentType.SingleLine: textWriter.Write("//"); textWriter.WriteLine(content); - column += 2 + content.Length; + column = 1; + line++; needsIndent = true; isAtStartOfLine = true; break; @@ -144,7 +145,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor case CommentType.Documentation: textWriter.Write("///"); textWriter.WriteLine(content); - column += 3 + content.Length; + column = 1; + line++; needsIndent = true; isAtStartOfLine = true; break; diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs index 39d659093..073fd61bb 100644 --- a/ILSpy/Languages/CSharpILMixedLanguage.cs +++ b/ILSpy/Languages/CSharpILMixedLanguage.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; @@ -116,6 +117,14 @@ namespace ICSharpCode.ILSpy void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn, bool isSingleLine) { + if (startColumn > text.Length) { + Debug.Fail("startColumn is invalid"); + startColumn = text.Length; + } + if (endColumn > text.Length) { + Debug.Fail("endColumn is invalid"); + endColumn = text.Length; + } output.Write("// "); output.BeginSpan(gray); if (isSingleLine) From 14b6c599c168e3a17c11612717caa9166b5355c2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 15 Oct 2017 15:47:24 +0200 Subject: [PATCH 32/84] Fix object initializers directly accessing struct members + add initializer pretty tests. --- .../ICSharpCode.Decompiler.Tests.csproj | 1 + .../PrettyTestRunner.cs | 6 + .../TestCases/Pretty/InitializerTests.cs | 92 +++++++ .../TestCases/Pretty/InitializerTests.il | 245 +++++++++++++++++ .../TestCases/Pretty/InitializerTests.opt.il | 207 +++++++++++++++ .../Pretty/InitializerTests.opt.roslyn.il | 195 ++++++++++++++ .../Pretty/InitializerTests.roslyn.il | 247 ++++++++++++++++++ ...ransformCollectionAndObjectInitializers.cs | 16 +- 8 files changed, 1004 insertions(+), 5 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 490bc4c50..1affff8f5 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -66,6 +66,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index f5eee0fb8..dd00235d2 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -188,6 +188,12 @@ namespace ICSharpCode.Decompiler.Tests Run(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler); } + [Test] + public void InitializerTests([ValueSource("defaultOptions")] CompilerOptions cscOptions) + { + Run(cscOptions: cscOptions); + } + [Test] public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize, CompilerOptions.UseRoslyn)] CompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs new file mode 100644 index 000000000..352e68a17 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -0,0 +1,92 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// 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 System.Collections.Generic; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public class InitializerTests + { + public class C + { + public int Z; + public S Y; + public List L; + } + + public struct S + { + public int A; + public int B; + + public S(int a) + { + this.A = a; + this.B = 0; + } + } + + public static C TestCall(int a, C c) + { + return c; + } + + public C Test() + { + C c = new C(); + c.L = new List(); + c.L.Add(new S(1)); + return c; + } + + public C Test2() + { + C c = new C(); + c.Z = 1; + c.Z = 2; + return c; + } + + public C Test3() + { + C c = new C(); + c.Y = new S(1); + c.Y.A = 2; + return c; + } + + public C Test3b() + { + return InitializerTests.TestCall(0, new C { + Z = 1, + Y = { + A = 2 + } + }); + } + + public C Test4() + { + C c = new C(); + c.Y.A = 1; + c.Y.B = 3; + c.Z = 2; + return c; + } + } +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il new file mode 100644 index 000000000..88dc47267 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -0,0 +1,245 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. + + + +// 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 '0zopdghu' +{ + .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 '0zopdghu.dll' +// MVID: {56C873AC-FD1E-4808-A65A-845BA0A3C2B7} +.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 +// Image base: 0x032A0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + extends [mscorlib]System.Object +{ + .class auto ansi nested public beforefieldinit C + extends [mscorlib]System.Object + { + .field public int32 Z + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S Y + .field public class [mscorlib]System.Collections.Generic.List`1 L + .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 C::.ctor + + } // end of class C + + .class sequential ansi sealed nested public beforefieldinit S + extends [mscorlib]System.ValueType + { + .field public int32 A + .field public int32 B + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 a) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0008: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_000f: ret + } // end of method S::.ctor + + } // end of class S + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + TestCall(int32 a, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::TestCall + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test() cil managed + { + // Code size 42 (0x2a) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000d: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0012: ldloc.0 + IL_0013: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0018: ldc.i4.1 + IL_0019: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_001e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.0 + IL_0025: stloc.1 + IL_0026: br.s IL_0028 + + IL_0028: ldloc.1 + IL_0029: ret + } // end of method InitializerTests::Test + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test2() cil managed + { + // Code size 27 (0x1b) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000e: ldloc.0 + IL_000f: ldc.i4.2 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0015: ldloc.0 + IL_0016: stloc.1 + IL_0017: br.s IL_0019 + + IL_0019: ldloc.1 + IL_001a: ret + } // end of method InitializerTests::Test2 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3() cil managed + { + // Code size 37 (0x25) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_000e: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0013: ldloc.0 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0019: ldc.i4.2 + IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001f: ldloc.0 + IL_0020: stloc.1 + IL_0021: br.s IL_0023 + + IL_0023: ldloc.1 + IL_0024: ret + } // end of method InitializerTests::Test3 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3b() cil managed + { + // Code size 38 (0x26) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000f: ldloc.0 + IL_0010: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0015: ldc.i4.2 + IL_0016: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001b: ldloc.0 + IL_001c: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0021: stloc.1 + IL_0022: br.s IL_0024 + + IL_0024: ldloc.1 + IL_0025: ret + } // end of method InitializerTests::Test3b + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test4() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_000d: ldc.i4.1 + IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0013: ldloc.0 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0019: ldc.i4.3 + IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0026: ldloc.0 + IL_0027: stloc.1 + IL_0028: br.s IL_002a + + IL_002a: ldloc.1 + IL_002b: ret + } // end of method InitializerTests::Test4 + + .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 InitializerTests::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\InitializerTests.res" wurde erstellt. diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il new file mode 100644 index 000000000..9045f3b19 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -0,0 +1,207 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. + + + +// 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 xvcsxiw0 +{ + .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 xvcsxiw0.dll +// MVID: {ADB73224-52C3-4DFE-AB87-E9CEDD4FB2C3} +.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 +// Image base: 0x00D20000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + extends [mscorlib]System.Object +{ + .class auto ansi nested public beforefieldinit C + extends [mscorlib]System.Object + { + .field public int32 Z + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S Y + .field public class [mscorlib]System.Collections.Generic.List`1 L + .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 C::.ctor + + } // end of class C + + .class sequential ansi sealed nested public beforefieldinit S + extends [mscorlib]System.ValueType + { + .field public int32 A + .field public int32 B + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 a) cil managed + { + // Code size 15 (0xf) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0007: ldarg.0 + IL_0008: ldc.i4.0 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_000e: ret + } // end of method S::.ctor + + } // end of class S + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + TestCall(int32 a, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } // end of method InitializerTests::TestCall + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test() cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000c: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0011: ldloc.0 + IL_0012: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0017: ldc.i4.1 + IL_0018: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0022: ldloc.0 + IL_0023: ret + } // end of method InitializerTests::Test + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test2() cil managed + { + // Code size 22 (0x16) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.1 + IL_0008: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000d: ldloc.0 + IL_000e: ldc.i4.2 + IL_000f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0014: ldloc.0 + IL_0015: ret + } // end of method InitializerTests::Test2 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3() cil managed + { + // Code size 32 (0x20) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.1 + IL_0008: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_000d: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0012: ldloc.0 + IL_0013: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0018: ldc.i4.2 + IL_0019: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001e: ldloc.0 + IL_001f: ret + } // end of method InitializerTests::Test3 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3b() cil managed + { + // Code size 33 (0x21) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: ldc.i4.0 + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000e: ldloc.0 + IL_000f: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0014: ldc.i4.2 + IL_0015: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001a: ldloc.0 + IL_001b: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0020: ret + } // end of method InitializerTests::Test3b + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test4() cil managed + { + // Code size 39 (0x27) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_000c: ldc.i4.1 + IL_000d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0012: ldloc.0 + IL_0013: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0018: ldc.i4.3 + IL_0019: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0025: ldloc.0 + IL_0026: ret + } // end of method InitializerTests::Test4 + + .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 InitializerTests::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\InitializerTests.opt.res" wurde erstellt. diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il new file mode 100644 index 000000000..b4dca5b95 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -0,0 +1,195 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. + + + +// 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 InitializerTests +{ + .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 InitializerTests.dll +// MVID: {73C118AC-648F-43DB-A2FB-1B159DF870BA} +.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 +// Image base: 0x03230000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + extends [mscorlib]System.Object +{ + .class auto ansi nested public beforefieldinit C + extends [mscorlib]System.Object + { + .field public int32 Z + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S Y + .field public class [mscorlib]System.Collections.Generic.List`1 L + .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 C::.ctor + + } // end of class C + + .class sequential ansi sealed nested public beforefieldinit S + extends [mscorlib]System.ValueType + { + .field public int32 A + .field public int32 B + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 a) cil managed + { + // Code size 15 (0xf) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0007: ldarg.0 + IL_0008: ldc.i4.0 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_000e: ret + } // end of method S::.ctor + + } // end of class S + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + TestCall(int32 a, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } // end of method InitializerTests::TestCall + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test() cil managed + { + // Code size 34 (0x22) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: dup + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000b: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0010: dup + IL_0011: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0016: ldc.i4.1 + IL_0017: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_001c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0021: ret + } // end of method InitializerTests::Test + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test2() cil managed + { + // Code size 20 (0x14) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000c: dup + IL_000d: ldc.i4.2 + IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0013: ret + } // end of method InitializerTests::Test2 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3() cil managed + { + // Code size 30 (0x1e) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_000c: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0011: dup + IL_0012: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0017: ldc.i4.2 + IL_0018: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001d: ret + } // end of method InitializerTests::Test3 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3b() cil managed + { + // Code size 31 (0x1f) + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: dup + IL_0007: ldc.i4.1 + IL_0008: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000d: dup + IL_000e: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0013: ldc.i4.2 + IL_0014: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0019: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_001e: ret + } // end of method InitializerTests::Test3b + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test4() cil managed + { + // Code size 37 (0x25) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0005: dup + IL_0006: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_000b: ldc.i4.1 + IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0011: dup + IL_0012: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0017: ldc.i4.3 + IL_0018: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_001d: dup + IL_001e: ldc.i4.2 + IL_001f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0024: ret + } // end of method InitializerTests::Test4 + + .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 InitializerTests::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il new file mode 100644 index 000000000..dab3fefa3 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -0,0 +1,247 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. + + + +// 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 InitializerTests +{ + .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 InitializerTests.dll +// MVID: {53F415C2-DC80-4EFA-8787-82F129B1AC28} +.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 +// Image base: 0x002F0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + extends [mscorlib]System.Object +{ + .class auto ansi nested public beforefieldinit C + extends [mscorlib]System.Object + { + .field public int32 Z + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S Y + .field public class [mscorlib]System.Collections.Generic.List`1 L + .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 C::.ctor + + } // end of class C + + .class sequential ansi sealed nested public beforefieldinit S + extends [mscorlib]System.ValueType + { + .field public int32 A + .field public int32 B + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 a) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0008: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_000f: ret + } // end of method S::.ctor + + } // end of class S + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + TestCall(int32 a, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::TestCall + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test() cil managed + { + // Code size 42 (0x2a) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000d: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0012: ldloc.0 + IL_0013: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0018: ldc.i4.1 + IL_0019: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_001e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.0 + IL_0025: stloc.1 + IL_0026: br.s IL_0028 + + IL_0028: ldloc.1 + IL_0029: ret + } // end of method InitializerTests::Test + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test2() cil managed + { + // Code size 27 (0x1b) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000e: ldloc.0 + IL_000f: ldc.i4.2 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0015: ldloc.0 + IL_0016: stloc.1 + IL_0017: br.s IL_0019 + + IL_0019: ldloc.1 + IL_001a: ret + } // end of method InitializerTests::Test2 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3() cil managed + { + // Code size 37 (0x25) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_000e: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0013: ldloc.0 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0019: ldc.i4.2 + IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001f: ldloc.0 + IL_0020: stloc.1 + IL_0021: br.s IL_0023 + + IL_0023: ldloc.1 + IL_0024: ret + } // end of method InitializerTests::Test3 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test3b() cil managed + { + // Code size 36 (0x24) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0007: dup + IL_0008: ldc.i4.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_000e: dup + IL_000f: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0014: ldc.i4.2 + IL_0015: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_001a: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_001f: stloc.0 + IL_0020: br.s IL_0022 + + IL_0022: ldloc.0 + IL_0023: ret + } // end of method InitializerTests::Test3b + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test4() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_000d: ldc.i4.1 + IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A + IL_0013: ldloc.0 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0019: ldc.i4.3 + IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0026: ldloc.0 + IL_0027: stloc.1 + IL_0028: br.s IL_002a + + IL_002a: ldloc.1 + IL_002b: ret + } // end of method InitializerTests::Test4 + + .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 InitializerTests::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs index bc699eaed..1e66d3b1e 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs @@ -224,17 +224,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms } } break; - case LdObj ldobj: + case LdObj ldobj: { if (ldobj.Target is LdFlda ldflda) { path.Insert(0, new AccessPathElement(ldflda.Field)); instruction = ldflda.Target; break; } goto default; - case StObj stobj: - if (stobj.Target is LdFlda ldflda2) { - path.Insert(0, new AccessPathElement(ldflda2.Field)); - instruction = ldflda2.Target; + } + case StObj stobj: { + if (stobj.Target is LdFlda ldflda) { + path.Insert(0, new AccessPathElement(ldflda.Field)); + instruction = ldflda.Target; if (values == null) { values = new List(new[] { stobj.Value }); kind = AccessPathKind.Setter; @@ -242,6 +243,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms break; } goto default; + } case LdLoc ldloc: target = ldloc.Variable; instruction = null; @@ -250,6 +252,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms target = ldloca.Variable; instruction = null; break; + case LdFlda ldflda: + path.Insert(0, new AccessPathElement(ldflda.Field)); + instruction = ldflda.Target; + break; default: kind = AccessPathKind.Invalid; instruction = null; From 381bd425999e1800fe21702f3afb710430c7c95b Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 16 Oct 2017 18:55:58 +0200 Subject: [PATCH 33/84] Fix bug mentioned in #909 --- .../TestCases/Pretty/InitializerTests.cs | 13 +++- .../TestCases/Pretty/InitializerTests.il | 56 ++++++++++++++---- .../TestCases/Pretty/InitializerTests.opt.il | 49 +++++++++++---- .../Pretty/InitializerTests.opt.roslyn.il | 39 ++++++++---- .../Pretty/InitializerTests.roslyn.il | 46 +++++++++++---- .../CSharp/ExpressionBuilder.cs | 9 ++- ...ransformCollectionAndObjectInitializers.cs | 59 ++++++++++++++++--- .../Util/CollectionExtensions.cs | 7 +++ 8 files changed, 218 insertions(+), 60 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index 352e68a17..6309f08b0 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -46,7 +46,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return c; } - public C Test() + public C Test1() { C c = new C(); c.L = new List(); @@ -54,6 +54,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return c; } + public C Test1Alternative() + { + return InitializerTests.TestCall(1, new C { + L = new List { + new S(1) + } + }); + } + public C Test2() { C c = new C(); @@ -84,8 +93,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { C c = new C(); c.Y.A = 1; - c.Y.B = 3; c.Z = 2; + c.Y.B = 3; return c; } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il index 88dc47267..29834fb53 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '0zopdghu' +.assembly '0meyjl4r' { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module '0zopdghu.dll' -// MVID: {56C873AC-FD1E-4808-A65A-845BA0A3C2B7} +.module '0meyjl4r.dll' +// MVID: {DBAD72F7-978F-407F-9C77-44D3E99CD8AD} .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 -// Image base: 0x032A0000 +// Image base: 0x02FE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -93,7 +93,7 @@ } // end of method InitializerTests::TestCall .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C - Test() cil managed + Test1() cil managed { // Code size 42 (0x2a) .maxstack 2 @@ -117,7 +117,39 @@ IL_0028: ldloc.1 IL_0029: ret - } // end of method InitializerTests::Test + } // end of method InitializerTests::Test1 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test1Alternative() cil managed + { + // Code size 45 (0x2d) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_2) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000e: stloc.1 + IL_000f: ldloc.1 + IL_0010: ldc.i4.1 + IL_0011: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001b: nop + IL_001c: ldloc.1 + IL_001d: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0022: ldloc.0 + IL_0023: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0028: stloc.2 + IL_0029: br.s IL_002b + + IL_002b: ldloc.2 + IL_002c: ret + } // end of method InitializerTests::Test1Alternative .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C Test2() cil managed @@ -212,12 +244,12 @@ IL_000d: ldc.i4.1 IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A IL_0013: ldloc.0 - IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y - IL_0019: ldc.i4.3 - IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B - IL_001f: ldloc.0 - IL_0020: ldc.i4.2 - IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0014: ldc.i4.2 + IL_0015: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_001a: ldloc.0 + IL_001b: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0020: ldc.i4.3 + IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B IL_0026: ldloc.0 IL_0027: stloc.1 IL_0028: br.s IL_002a diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il index 9045f3b19..8de6548d9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly xvcsxiw0 +.assembly u2solxiw { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module xvcsxiw0.dll -// MVID: {ADB73224-52C3-4DFE-AB87-E9CEDD4FB2C3} +.module u2solxiw.dll +// MVID: {D1507E89-2CB3-46B1-AEC7-B176088BA3F9} .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 -// Image base: 0x00D20000 +// Image base: 0x028E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -86,7 +86,7 @@ } // end of method InitializerTests::TestCall .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C - Test() cil managed + Test1() cil managed { // Code size 36 (0x24) .maxstack 2 @@ -103,7 +103,32 @@ IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) IL_0022: ldloc.0 IL_0023: ret - } // end of method InitializerTests::Test + } // end of method InitializerTests::Test1 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test1Alternative() cil managed + { + // Code size 39 (0x27) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1) + IL_0000: ldc.i4.1 + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: ldc.i4.1 + IL_0010: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_0015: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001a: ldloc.1 + IL_001b: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_0020: ldloc.0 + IL_0021: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0026: ret + } // end of method InitializerTests::Test1Alternative .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C Test2() cil managed @@ -178,12 +203,12 @@ IL_000c: ldc.i4.1 IL_000d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A IL_0012: ldloc.0 - IL_0013: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y - IL_0018: ldc.i4.3 - IL_0019: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B - IL_001e: ldloc.0 - IL_001f: ldc.i4.2 - IL_0020: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0013: ldc.i4.2 + IL_0014: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0019: ldloc.0 + IL_001a: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_001f: ldc.i4.3 + IL_0020: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B IL_0025: ldloc.0 IL_0026: ret } // end of method InitializerTests::Test4 diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il index b4dca5b95..8b03bca83 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {73C118AC-648F-43DB-A2FB-1B159DF870BA} +// MVID: {F2C6C41E-98CC-4261-BF7B-1991B54DA121} .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 -// Image base: 0x03230000 +// Image base: 0x029A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -90,7 +90,7 @@ } // end of method InitializerTests::TestCall .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C - Test() cil managed + Test1() cil managed { // Code size 34 (0x22) .maxstack 8 @@ -104,7 +104,26 @@ IL_0017: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) IL_001c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) IL_0021: ret - } // end of method InitializerTests::Test + } // end of method InitializerTests::Test1 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test1Alternative() cil managed + { + // Code size 35 (0x23) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0006: dup + IL_0007: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000c: dup + IL_000d: ldc.i4.1 + IL_000e: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_0013: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0018: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_001d: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0022: ret + } // end of method InitializerTests::Test1Alternative .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C Test2() cil managed @@ -168,12 +187,12 @@ IL_000b: ldc.i4.1 IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A IL_0011: dup - IL_0012: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y - IL_0017: ldc.i4.3 - IL_0018: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B - IL_001d: dup - IL_001e: ldc.i4.2 - IL_001f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0012: ldc.i4.2 + IL_0013: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0018: dup + IL_0019: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_001e: ldc.i4.3 + IL_001f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B IL_0024: ret } // end of method InitializerTests::Test4 diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il index dab3fefa3..383822da9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {53F415C2-DC80-4EFA-8787-82F129B1AC28} +// MVID: {7000C1D7-C4EC-4376-B053-4BE74428CE7A} .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 -// Image base: 0x002F0000 +// Image base: 0x00C90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -98,7 +98,7 @@ } // end of method InitializerTests::TestCall .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C - Test() cil managed + Test1() cil managed { // Code size 42 (0x2a) .maxstack 2 @@ -122,7 +122,33 @@ IL_0028: ldloc.1 IL_0029: ret - } // end of method InitializerTests::Test + } // end of method InitializerTests::Test1 + + .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C + Test1Alternative() cil managed + { + // Code size 41 (0x29) + .maxstack 6 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::.ctor() + IL_0007: dup + IL_0008: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000d: dup + IL_000e: ldc.i4.1 + IL_000f: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::.ctor(int32) + IL_0014: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0019: nop + IL_001a: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::L + IL_001f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C) + IL_0024: stloc.0 + IL_0025: br.s IL_0027 + + IL_0027: ldloc.0 + IL_0028: ret + } // end of method InitializerTests::Test1Alternative .method public hidebysig instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C Test2() cil managed @@ -214,12 +240,12 @@ IL_000d: ldc.i4.1 IL_000e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::A IL_0013: ldloc.0 - IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y - IL_0019: ldc.i4.3 - IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B - IL_001f: ldloc.0 - IL_0020: ldc.i4.2 - IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_0014: ldc.i4.2 + IL_0015: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Z + IL_001a: ldloc.0 + IL_001b: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C::Y + IL_0020: ldc.i4.3 + IL_0021: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/S::B IL_0026: ldloc.0 IL_0027: stloc.1 IL_0028: br.s IL_002a diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 25ed0ddb3..7aec147d5 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1427,11 +1427,10 @@ namespace ICSharpCode.Decompiler.CSharp if (currentPath == null) { currentPath = info.Path; } else { - int firstDifferenceIndex = Math.Min(currentPath.Count, info.Path.Count); - int index = 0; - while (index < firstDifferenceIndex && info.Path[index] == currentPath[index]) - index++; - firstDifferenceIndex = index; + int minLen = Math.Min(currentPath.Count, info.Path.Count); + int firstDifferenceIndex = 0; + while (firstDifferenceIndex < minLen && info.Path[firstDifferenceIndex] == currentPath[firstDifferenceIndex]) + firstDifferenceIndex++; while (elementsStack.Count - 1 > firstDifferenceIndex) { var methodElement = currentPath[elementsStack.Count - 1]; var pathElement = currentPath[elementsStack.Count - 2]; diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs index 1e66d3b1e..e01b58a84 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Linq; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.IL.Transforms { @@ -83,13 +84,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms } int initializerItemsCount = 0; var blockType = initializerBlock?.Type ?? BlockType.CollectionInitializer; - var possibleIndexVariables = new Dictionary(); + possibleIndexVariables = new Dictionary(); + currentPath = new List(); + isCollection = false; + pathStack = new Stack>(); + pathStack.Push(new HashSet()); // Detect initializer type by scanning the following statements // each must be a callvirt with ldloc v as first argument // if the method is a setter we're dealing with an object initializer // if the method is named Add and has at least 2 arguments we're dealing with a collection/dictionary initializer while (pos + initializerItemsCount + 1 < body.Instructions.Count - && IsPartOfInitializer(body.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockType, possibleIndexVariables)) { + && IsPartOfInitializer(body.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockType)) { initializerItemsCount++; } var index = possibleIndexVariables.Where(info => info.Value.Index > -1).Min(info => (int?)info.Value.Index); @@ -139,7 +144,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms return true; } - bool IsPartOfInitializer(InstructionCollection instructions, int pos, ILVariable target, IType rootType, ref BlockType blockType, Dictionary possibleIndexVariables) + Dictionary possibleIndexVariables; + List currentPath; + bool isCollection; + Stack> pathStack; + + bool IsPartOfInitializer(InstructionCollection instructions, int pos, ILVariable target, IType rootType, ref BlockType blockType) { if (instructions[pos] is StLoc stloc && stloc.Variable.Kind == VariableKind.Local && stloc.Variable.IsSingleDefinition) { if (stloc.Value.Descendants.OfType().Any(ld => ld.Variable == target && (ld is LdLoc || ld is LdLoca))) @@ -147,12 +157,40 @@ namespace ICSharpCode.Decompiler.IL.Transforms possibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value)); return true; } - (var kind, var path, var values, var targetVariable) = AccessPathElement.GetAccessPath(instructions[pos], rootType, possibleIndexVariables); + (var kind, var newPath, var values, var targetVariable) = AccessPathElement.GetAccessPath(instructions[pos], rootType, possibleIndexVariables); + if (kind == AccessPathKind.Invalid || target != targetVariable) + return false; + // Treat last element separately: + // Can either be an Add method call or property setter. + var lastElement = newPath.Last(); + newPath.RemoveLast(); + // Compare new path with current path: + int minLen = Math.Min(currentPath.Count, newPath.Count); + int firstDifferenceIndex = 0; + while (firstDifferenceIndex < minLen && newPath[firstDifferenceIndex] == currentPath[firstDifferenceIndex]) + firstDifferenceIndex++; + while (currentPath.Count > firstDifferenceIndex) { + isCollection = false; + currentPath.RemoveAt(currentPath.Count - 1); + pathStack.Pop(); + } + while (currentPath.Count < newPath.Count) { + AccessPathElement newElement = newPath[currentPath.Count]; + currentPath.Add(newElement); + if (isCollection || !pathStack.Peek().Add(newElement)) + return false; + pathStack.Push(new HashSet()); + } switch (kind) { case AccessPathKind.Adder: - return target == targetVariable; + isCollection = true; + if (pathStack.Peek().Count != 0) + return false; + return true; case AccessPathKind.Setter: - if (values.Count == 1 && target == targetVariable) { + if (isCollection || !pathStack.Peek().Add(lastElement)) + return false; + if (values.Count == 1) { blockType = BlockType.ObjectInitializer; return true; } @@ -319,7 +357,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms public bool Equals(AccessPathElement other) { - return other.Member.Equals(this.Member) && (other.Indices == this.Indices || other.Indices.SequenceEqual(this.Indices, ILInstructionMatchComparer.Instance)); + return other.Member.Equals(this.Member) + && (other.Indices == this.Indices || other.Indices.SequenceEqual(this.Indices, ILInstructionMatchComparer.Instance)); } public static bool operator ==(AccessPathElement lhs, AccessPathElement rhs) @@ -343,12 +382,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms return true; if (x == null || y == null) return false; - return x.Match(y).Success; + return SemanticHelper.IsPure(x.Flags) + && SemanticHelper.IsPure(y.Flags) + && x.Match(y).Success; } public int GetHashCode(ILInstruction obj) { - return obj.GetHashCode(); + throw new NotSupportedException(); } } } diff --git a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs index d6f67cae8..df1785c7e 100644 --- a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs +++ b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs @@ -190,5 +190,12 @@ namespace ICSharpCode.Decompiler.Util return maxElement; } } + + public static void RemoveLast(this IList list) + { + if (list == null) + throw new ArgumentNullException(nameof(list)); + list.RemoveAt(list.Count - 1); + } } } From 0b6987f1959606d8f90e561ff7812e1086c89b2f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 16 Oct 2017 22:42:15 +0200 Subject: [PATCH 34/84] Fix pretty unit tests. --- .../TestCases/Pretty/InitializerTests.il | 8 +++---- .../TestCases/Pretty/InitializerTests.opt.il | 8 +++---- .../Pretty/InitializerTests.opt.roslyn.il | 2 +- .../Pretty/InitializerTests.roslyn.il | 2 +- .../IL/Transforms/AssignVariableNames.cs | 24 +++++++++++++++++++ ...ransformCollectionAndObjectInitializers.cs | 13 ++++++++++ 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il index 29834fb53..d6a62db22 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '0meyjl4r' +.assembly umgm00go { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module '0meyjl4r.dll' -// MVID: {DBAD72F7-978F-407F-9C77-44D3E99CD8AD} +.module umgm00go.dll +// MVID: {8C42504A-ACC6-453C-81BA-626AB6649E25} .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 -// Image base: 0x02FE0000 +// Image base: 0x02AE0000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il index 8de6548d9..ac94bb18e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly u2solxiw +.assembly ecxzpbak { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module u2solxiw.dll -// MVID: {D1507E89-2CB3-46B1-AEC7-B176088BA3F9} +.module ecxzpbak.dll +// MVID: {F67EEE6A-7EFF-4261-9FC7-3F2C4A0972E9} .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 -// Image base: 0x028E0000 +// Image base: 0x02430000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il index 8b03bca83..13eb53fdd 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -32,7 +32,7 @@ .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x029A0000 +// Image base: 0x00700000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il index 383822da9..5db37abe9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -32,7 +32,7 @@ .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00C90000 +// Image base: 0x005E0000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index 520a2d18e..a8db2d911 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -196,6 +196,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms proposedName = proposedNameForLoads[0]; } } + if (string.IsNullOrEmpty(proposedName)) { + var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType() + .Select(expr => GetNameByType(GuessType(expr.Value, context))) + .Except(currentFieldNames).ToList(); + if (proposedNameForStoresFromNewObj.Count == 1) { + proposedName = proposedNameForStoresFromNewObj[0]; + } + } if (string.IsNullOrEmpty(proposedName)) { proposedName = GetNameByType(variable.Type); } @@ -349,6 +357,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms return char.ToLower(name[0]) + name.Substring(1); } + internal static IType GuessType(ILInstruction inst, ILTransformContext context) + { + switch (inst) { + case NewObj newObj: + return newObj.Method.DeclaringType; + case Call call: + return call.Method.ReturnType; + case CallVirt callVirt: + return callVirt.Method.ReturnType; + case CallIndirect calli: + return calli.ReturnType; + default: + return context.TypeSystem.Compilation.FindType(inst.ResultType.ToKnownTypeCode()); + } + } + internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null) { if (function == null) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs index e01b58a84..d927bb61f 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs @@ -97,6 +97,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms && IsPartOfInitializer(body.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockType)) { initializerItemsCount++; } + if (IsMethodCallOnVariable(body.Instructions[pos + initializerItemsCount + 1], v)) + return false; var index = possibleIndexVariables.Where(info => info.Value.Index > -1).Min(info => (int?)info.Value.Index); if (index != null) { initializerItemsCount = index.Value - pos - 1; @@ -144,6 +146,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms return true; } + bool IsMethodCallOnVariable(ILInstruction inst, ILVariable variable) + { + if (inst.MatchLdLocRef(variable)) + return true; + if (inst is CallInstruction call && call.Arguments.Count > 0 && !call.Method.IsStatic) + return IsMethodCallOnVariable(call.Arguments[0], variable); + if (inst.MatchLdFld(out var target, out _) || inst.MatchStFld(out target, out _, out _) || inst.MatchLdFlda(out target, out _)) + return IsMethodCallOnVariable(target, variable); + return false; + } + Dictionary possibleIndexVariables; List currentPath; bool isCollection; From 0ab805a6033fca5d4cc8d4bd8740062fc90656a5 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 00:19:03 +0200 Subject: [PATCH 35/84] Add regression test for foreach variable naming. --- .../TestCases/Pretty/Loops.cs | 6 +++--- .../TestCases/Pretty/Loops.il | 16 ++++++++-------- .../TestCases/Pretty/Loops.opt.il | 16 ++++++++-------- .../TestCases/Pretty/Loops.opt.roslyn.il | 10 +++++----- .../TestCases/Pretty/Loops.roslyn.il | 10 +++++----- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs index 8bacd3048..f81976a52 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs @@ -260,10 +260,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { } - public void ForEach(IEnumerable enumerable) + public void ForEach(IEnumerable alternatives) { - foreach (string item in enumerable) { - item.ToLower(); + foreach (string alternative in alternatives) { + alternative.ToLower(); } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il index ad08c43b3..4d1ec82d2 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il @@ -1,6 +1,6 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 -// Copyright (c) Microsoft Corporation. All rights reserved. +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly y5enlto2 +.assembly y1gx1hfa { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module y5enlto2.dll -// MVID: {7F6CCF81-BE23-4326-8F55-7E3BF0A8B7A2} +.module y1gx1hfa.dll +// MVID: {21EB73BD-6DA1-4305-9961-7F543EB0E1F3} .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 -// Image base: 0x009B0000 +// Image base: 0x02A00000 // =============== CLASS MEMBERS DECLARATION =================== @@ -635,7 +635,7 @@ } // end of method Loops::Operation .method public hidebysig instance void - ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { // Code size 57 (0x39) .maxstack 2 @@ -1750,4 +1750,4 @@ // ============================================================= // *********** DISASSEMBLY COMPLETE *********************** -// WARNING: Created Win32 resource file ../../../TestCases/Pretty\Loops.res +// Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\Loops.res" wurde erstellt. diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il index a1e2ed464..fbfe5756f 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il @@ -1,6 +1,6 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 -// Copyright (c) Microsoft Corporation. All rights reserved. +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly jiaqp12i +.assembly de0u0jkz { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module jiaqp12i.dll -// MVID: {34208704-52B8-49EB-BC77-C3A95E1CBA19} +.module de0u0jkz.dll +// MVID: {F3F9EFD3-F9A8-4885-B2D2-AD75367C0339} .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 -// Image base: 0x02520000 +// Image base: 0x01A60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -550,7 +550,7 @@ } // end of method Loops::Operation .method public hidebysig instance void - ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { // Code size 44 (0x2c) .maxstack 1 @@ -1361,4 +1361,4 @@ // ============================================================= // *********** DISASSEMBLY COMPLETE *********************** -// WARNING: Created Win32 resource file ../../../TestCases/Pretty\Loops.opt.res +// Warnung: Win32-Ressourcendatei "../../../TestCases/Pretty\Loops.opt.res" wurde erstellt. diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il index a3b169382..bdad1dc5d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il @@ -1,6 +1,6 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 -// Copyright (c) Microsoft Corporation. All rights reserved. +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Loops.dll -// MVID: {8D392B4A-5D21-407A-B579-FCDFA93069CE} +// MVID: {13449EE0-18A5-44A4-B482-40B5C738DFBB} .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 -// Image base: 0x00DA0000 +// Image base: 0x00D70000 // =============== CLASS MEMBERS DECLARATION =================== @@ -554,7 +554,7 @@ } // end of method Loops::Operation .method public hidebysig instance void - ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { // Code size 42 (0x2a) .maxstack 1 diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il index 864b1e5c5..5e5848cd3 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il @@ -1,6 +1,6 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 -// Copyright (c) Microsoft Corporation. All rights reserved. +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten. @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Loops.dll -// MVID: {C6DBFA5B-CB31-4084-8E6F-7BA877923008} +// MVID: {747E198F-8825-4B5B-9C27-DF069E6F35AE} .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 -// Image base: 0x00A80000 +// Image base: 0x027A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -639,7 +639,7 @@ } // end of method Loops::Operation .method public hidebysig instance void - ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 enumerable) cil managed + ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { // Code size 49 (0x31) .maxstack 1 From 11a9d901e21aa799d1cdabcfae2d4ccbff54ba8a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 09:36:43 +0200 Subject: [PATCH 36/84] Fix foreach variable naming in case of parameter in-expression. Add more tests. --- .../TestCases/Pretty/Loops.cs | 9 +++ .../TestCases/Pretty/Loops.il | 62 +++++++++++++++-- .../TestCases/Pretty/Loops.opt.il | 49 +++++++++++-- .../TestCases/Pretty/Loops.opt.roslyn.il | 58 +++++++++++++--- .../TestCases/Pretty/Loops.roslyn.il | 68 ++++++++++++++++--- .../IL/Transforms/AssignVariableNames.cs | 5 ++ 6 files changed, 222 insertions(+), 29 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs index f81976a52..8345eaf1c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs @@ -252,6 +252,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty } } + private IEnumerable alternatives; + private static void Operation(ref int item) { } @@ -260,6 +262,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { } + public void ForEachOnField() + { + foreach (string alternative in this.alternatives) { + alternative.ToLower(); + } + } + public void ForEach(IEnumerable alternatives) { foreach (string alternative in alternatives) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il index 4d1ec82d2..030f6bd46 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly y1gx1hfa +.assembly ic2bztjj { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module y1gx1hfa.dll -// MVID: {21EB73BD-6DA1-4305-9961-7F543EB0E1F3} +.module ic2bztjj.dll +// MVID: {821665CB-F67F-4600-8C6C-27617D873D36} .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 -// Image base: 0x02A00000 +// Image base: 0x01550000 // =============== CLASS MEMBERS DECLARATION =================== @@ -618,6 +618,7 @@ } // end of class '<>c__DisplayClass1' + .field private class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives .method private hidebysig static void Operation(int32& item) cil managed { // Code size 2 (0x2) @@ -634,6 +635,59 @@ IL_0001: ret } // end of method Loops::Operation + .method public hidebysig instance void + ForEachOnField() cil managed + { + // Code size 62 (0x3e) + .maxstack 2 + .locals init (string 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: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::alternatives + IL_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.1 + .try + { + IL_000e: br.s IL_0020 + + IL_0010: ldloc.1 + IL_0011: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0016: stloc.0 + IL_0017: nop + IL_0018: ldloc.0 + IL_0019: callvirt instance string [mscorlib]System.String::ToLower() + IL_001e: pop + IL_001f: nop + IL_0020: ldloc.1 + IL_0021: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0026: stloc.2 + IL_0027: ldloc.2 + IL_0028: brtrue.s IL_0010 + + IL_002a: leave.s IL_003c + + } // end .try + finally + { + IL_002c: ldloc.1 + IL_002d: ldnull + IL_002e: ceq + IL_0030: stloc.2 + IL_0031: ldloc.2 + IL_0032: brtrue.s IL_003b + + IL_0034: ldloc.1 + IL_0035: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_003a: nop + IL_003b: endfinally + } // end handler + IL_003c: nop + IL_003d: ret + } // end of method Loops::ForEachOnField + .method public hidebysig instance void ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il index fbfe5756f..50a8785a7 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly de0u0jkz +.assembly fabjeeha { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module de0u0jkz.dll -// MVID: {F3F9EFD3-F9A8-4885-B2D2-AD75367C0339} +.module fabjeeha.dll +// MVID: {4FB3AE1F-ECE0-4E7D-84DC-E693282CA0AF} .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 -// Image base: 0x01A60000 +// Image base: 0x00D90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -535,6 +535,7 @@ } // end of class '<>c__DisplayClass1' + .field private class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives .method private hidebysig static void Operation(int32& item) cil managed { // Code size 1 (0x1) @@ -549,6 +550,46 @@ IL_0000: ret } // end of method Loops::Operation + .method public hidebysig instance void + ForEachOnField() cil managed + { + // Code size 49 (0x31) + .maxstack 1 + .locals init (string V_0, + class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::alternatives + IL_0006: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000b: stloc.1 + .try + { + IL_000c: br.s IL_001c + + IL_000e: ldloc.1 + IL_000f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0014: stloc.0 + IL_0015: ldloc.0 + IL_0016: callvirt instance string [mscorlib]System.String::ToLower() + IL_001b: pop + IL_001c: ldloc.1 + IL_001d: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0022: brtrue.s IL_000e + + IL_0024: leave.s IL_0030 + + } // end .try + finally + { + IL_0026: ldloc.1 + IL_0027: brfalse.s IL_002f + + IL_0029: ldloc.1 + IL_002a: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002f: endfinally + } // end handler + IL_0030: ret + } // end of method Loops::ForEachOnField + .method public hidebysig instance void ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il index bdad1dc5d..8fc3ae3c4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Loops.dll -// MVID: {13449EE0-18A5-44A4-B482-40B5C738DFBB} +// MVID: {F03B196B-9B00-49BE-A335-2D460586E39A} .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 -// Image base: 0x00D70000 +// Image base: 0x02D60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -510,7 +510,7 @@ } // end of property CustomStructEnumeratorWithIDisposable`1::Current } // end of class CustomStructEnumeratorWithIDisposable`1 - .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass23_0' + .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass25_0' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -523,7 +523,7 @@ IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret - } // end of method '<>c__DisplayClass23_0'::.ctor + } // end of method '<>c__DisplayClass25_0'::.ctor .method assembly hidebysig instance bool 'b__0'() cil managed @@ -531,14 +531,15 @@ // Code size 10 (0xa) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::c + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::c IL_0006: ldc.i4.5 IL_0007: ceq IL_0009: ret - } // end of method '<>c__DisplayClass23_0'::'b__0' + } // end of method '<>c__DisplayClass25_0'::'b__0' - } // end of class '<>c__DisplayClass23_0' + } // end of class '<>c__DisplayClass25_0' + .field private class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives .method private hidebysig static void Operation(int32& item) cil managed { // Code size 1 (0x1) @@ -553,6 +554,43 @@ IL_0000: ret } // end of method Loops::Operation + .method public hidebysig instance void + ForEachOnField() cil managed + { + // Code size 47 (0x2f) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::alternatives + IL_0006: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000b: stloc.0 + .try + { + IL_000c: br.s IL_001a + + IL_000e: ldloc.0 + IL_000f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0014: callvirt instance string [mscorlib]System.String::ToLower() + IL_0019: pop + IL_001a: ldloc.0 + IL_001b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0020: brtrue.s IL_000e + + IL_0022: leave.s IL_002e + + } // end .try + finally + { + IL_0024: ldloc.0 + IL_0025: brfalse.s IL_002d + + IL_0027: ldloc.0 + IL_0028: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002d: endfinally + } // end handler + IL_002e: ret + } // end of method Loops::ForEachOnField + .method public hidebysig instance void ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { @@ -1063,11 +1101,11 @@ IL_0009: ldloca.s V_0 IL_000b: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator::get_Current() IL_0010: stloc.1 - IL_0011: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::.ctor() + IL_0011: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::.ctor() IL_0016: dup IL_0017: ldloc.1 - IL_0018: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::c - IL_001d: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::'b__0'() + IL_0018: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::c + IL_001d: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::'b__0'() IL_0023: newobj instance void class [mscorlib]System.Func`1::.ctor(object, native int) IL_0028: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::Operation(class [mscorlib]System.Func`1) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il index 5e5848cd3..f10e2f5ff 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Loops.dll -// MVID: {747E198F-8825-4B5B-9C27-DF069E6F35AE} +// MVID: {F66BA703-8DC0-4A56-81BC-D288A1D83D30} .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 -// Image base: 0x027A0000 +// Image base: 0x02D60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -592,7 +592,7 @@ } // end of property CustomStructEnumeratorWithIDisposable`1::Current } // end of class CustomStructEnumeratorWithIDisposable`1 - .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass23_0' + .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass25_0' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -606,7 +606,7 @@ IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop IL_0007: ret - } // end of method '<>c__DisplayClass23_0'::.ctor + } // end of method '<>c__DisplayClass25_0'::.ctor .method assembly hidebysig instance bool 'b__0'() cil managed @@ -614,14 +614,15 @@ // Code size 10 (0xa) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::c + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::c IL_0006: ldc.i4.5 IL_0007: ceq IL_0009: ret - } // end of method '<>c__DisplayClass23_0'::'b__0' + } // end of method '<>c__DisplayClass25_0'::'b__0' - } // end of class '<>c__DisplayClass23_0' + } // end of class '<>c__DisplayClass25_0' + .field private class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives .method private hidebysig static void Operation(int32& item) cil managed { // Code size 2 (0x2) @@ -638,6 +639,51 @@ IL_0001: ret } // end of method Loops::Operation + .method public hidebysig instance void + ForEachOnField() cil managed + { + // Code size 54 (0x36) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1 V_0, + string V_1) + IL_0000: nop + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::alternatives + IL_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0020 + + IL_0010: ldloc.0 + IL_0011: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0016: stloc.1 + IL_0017: nop + IL_0018: ldloc.1 + IL_0019: callvirt instance string [mscorlib]System.String::ToLower() + IL_001e: pop + IL_001f: nop + IL_0020: ldloc.0 + IL_0021: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0026: brtrue.s IL_0010 + + IL_0028: leave.s IL_0035 + + } // end .try + finally + { + IL_002a: ldloc.0 + IL_002b: brfalse.s IL_0034 + + IL_002d: ldloc.0 + IL_002e: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0033: nop + IL_0034: endfinally + } // end handler + IL_0035: ret + } // end of method Loops::ForEachOnField + .method public hidebysig instance void ForEach(class [mscorlib]System.Collections.Generic.IEnumerable`1 alternatives) cil managed { @@ -1259,7 +1305,7 @@ .maxstack 2 .locals init (valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator V_0, int32 V_1, - class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0' V_2) + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0' V_2) IL_0000: nop IL_0001: nop IL_0002: ldarg.0 @@ -1272,14 +1318,14 @@ IL_000b: ldloca.s V_0 IL_000d: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator::get_Current() IL_0012: stloc.1 - IL_0013: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::.ctor() + IL_0013: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::.ctor() IL_0018: stloc.2 IL_0019: nop IL_001a: ldloc.2 IL_001b: ldloc.1 - IL_001c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::c + IL_001c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::c IL_0021: ldloc.2 - IL_0022: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass23_0'::'b__0'() + IL_0022: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops/'<>c__DisplayClass25_0'::'b__0'() IL_0028: newobj instance void class [mscorlib]System.Func`1::.ctor(object, native int) IL_002d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Loops::Operation(class [mscorlib]System.Func`1) diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index 520a2d18e..4b705d337 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -362,6 +362,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms AddExistingName(reservedVariableNames, f); string baseName = GetNameFromInstruction(valueContext); + if (string.IsNullOrEmpty(baseName)) { + if (valueContext is LdLoc ldloc && ldloc.Variable.Kind == VariableKind.Parameter) { + baseName = ldloc.Variable.Name; + } + } string proposedName = "item"; if (!string.IsNullOrEmpty(baseName)) { From a014684918c189ebb848af6faae7a96752d18667 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 13:14:56 +0200 Subject: [PATCH 37/84] Fix regression in AssignVariableNames --- .../IL/Transforms/AssignVariableNames.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index a8db2d911..eea8dedae 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -198,7 +198,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms } if (string.IsNullOrEmpty(proposedName)) { var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType() - .Select(expr => GetNameByType(GuessType(expr.Value, context))) + .Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context))) .Except(currentFieldNames).ToList(); if (proposedNameForStoresFromNewObj.Count == 1) { proposedName = proposedNameForStoresFromNewObj[0]; @@ -357,8 +357,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms return char.ToLower(name[0]) + name.Substring(1); } - internal static IType GuessType(ILInstruction inst, ILTransformContext context) + internal static IType GuessType(IType variableType, ILInstruction inst, ILTransformContext context) { + if (!variableType.IsKnownType(KnownTypeCode.Object)) + return variableType; + switch (inst) { case NewObj newObj: return newObj.Method.DeclaringType; From 60894a02a4887f3982bab9a5ef45fab9ffe45b85 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 13:15:52 +0200 Subject: [PATCH 38/84] Fix missing ILStackWasEmpty-flag on call after conversion to newobj --- .../IL/Transforms/EarlyExpressionTransforms.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs index e5b667734..bba216c13 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs @@ -104,6 +104,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms var newObj = new NewObj(inst.Method); newObj.ILRange = inst.ILRange; newObj.Arguments.AddRange(inst.Arguments.Skip(1)); + newObj.ILStackWasEmpty = inst.ILStackWasEmpty; var expr = new StObj(inst.Arguments[0], newObj, inst.Method.DeclaringType); inst.ReplaceWith(expr); return expr; From e1baac3a9c18a25d168148184ae3634dd112fe8d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 13:16:47 +0200 Subject: [PATCH 39/84] Fix output of space before array initializer expression. --- .../CSharp/OutputVisitor/CSharpOutputVisitor.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index 076ae703b..8eb432e8b 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -90,6 +90,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor Space(policy.SpaceBeforeBracketComma); // TODO: Comma policy has changed. writer.WriteToken(Roles.Comma, ","); + isAfterSpace = false; Space(!noSpaceAfterComma && policy.SpaceAfterBracketComma); // TODO: Comma policy has changed. } @@ -194,6 +195,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor #region Write tokens protected bool isAtStartOfLine = true; + protected bool isAfterSpace; /// /// Writes a keyword, and all specials up to @@ -207,18 +209,21 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { writer.WriteKeyword(tokenRole, token); isAtStartOfLine = false; + isAfterSpace = false; } protected virtual void WriteIdentifier(Identifier identifier) { writer.WriteIdentifier(identifier); isAtStartOfLine = false; + isAfterSpace = false; } protected virtual void WriteIdentifier(string identifier) { AstType.Create(identifier).AcceptVisitor(this); isAtStartOfLine = false; + isAfterSpace = false; } protected virtual void WriteToken(TokenRole tokenRole) @@ -230,6 +235,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { writer.WriteToken(tokenRole, token); isAtStartOfLine = false; + isAfterSpace = false; } protected virtual void LPar() @@ -260,8 +266,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor /// protected virtual void Space(bool addSpace = true) { - if (addSpace) { + if (addSpace && !isAfterSpace) { writer.Space(); + isAfterSpace = true; } } @@ -269,6 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { writer.NewLine(); isAtStartOfLine = true; + isAfterSpace = false; } protected virtual void OpenBrace(BraceStyle style) @@ -278,7 +286,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor case BraceStyle.EndOfLine: case BraceStyle.BannerStyle: if (!isAtStartOfLine) - writer.Space(); + Space(); writer.WriteToken(Roles.LBrace, "{"); break; case BraceStyle.EndOfLineWithoutSpace: @@ -937,6 +945,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(primitiveExpression); writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue); + isAfterSpace = false; EndNode(primitiveExpression); } #endregion From 20d772ed65e4fab83e8d3b3e254e6f8f22542c21 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 17 Oct 2017 13:27:12 +0200 Subject: [PATCH 40/84] Add more tests --- .../TestCases/Pretty/InitializerTests.cs | 371 +++++- .../TestCases/Pretty/InitializerTests.il | 1125 +++++++++++++++- .../TestCases/Pretty/InitializerTests.opt.il | 947 +++++++++++++- .../Pretty/InitializerTests.opt.roslyn.il | 988 +++++++++++++- .../Pretty/InitializerTests.roslyn.il | 1143 ++++++++++++++++- 5 files changed, 4559 insertions(+), 15 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index 6309f08b0..63439bcb7 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -17,11 +17,15 @@ // DEALINGS IN THE SOFTWARE. using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { public class InitializerTests { + #region Types and helpers public class C { public int Z; @@ -41,10 +45,102 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty } } + private enum MyEnum + { + a = 0, + b = 1 + } + + private enum MyEnum2 + { + c = 0, + d = 1 + } + + private class Data + { + public List FieldList = new List(); + public MyEnum a { + get; + set; + } + public MyEnum b { + get; + set; + } + public List PropertyList { + get; + set; + } + + public Data MoreData { + get; + set; + } + + public StructData NestedStruct { + get; + set; + } + + public Data this[int i] { + get { + return null; + } + set { + } + } + + public Data this[int i, string j] { + get { + return null; + } + set { + } + } + } + + private struct StructData + { + public int Field; + public int Property { + get; + set; + } + + public Data MoreData { + get; + set; + } + + public StructData(int initialValue) + { + this = default(StructData); + this.Field = initialValue; + this.Property = initialValue; + } + } + + // Helper methods used to ensure initializers used within expressions work correctly + private static void X(object a, object b) + { + } + + private static object Y() + { + return null; + } + + public static void TestCall(int a, Thread thread) + { + + } + public static C TestCall(int a, C c) { return c; } + #endregion public C Test1() { @@ -83,7 +179,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { return InitializerTests.TestCall(0, new C { Z = 1, - Y = { + Y = { A = 2 } }); @@ -97,5 +193,278 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty c.Y.B = 3; return c; } + + + public static void CollectionInitializerList() + { + InitializerTests.X(InitializerTests.Y(), new List { + 1, + 2, + 3 + }); + } + + public static object RecursiveCollectionInitializer() + { + List list = new List(); + list.Add(list); + return list; + } + + public static void CollectionInitializerDictionary() + { + InitializerTests.X(InitializerTests.Y(), new Dictionary { + { + "First", + 1 + }, + { + "Second", + 2 + }, + { + "Third", + 3 + } + }); + } + + public static void CollectionInitializerDictionaryWithEnumTypes() + { + InitializerTests.X(InitializerTests.Y(), new Dictionary { + { + MyEnum.a, + MyEnum2.c + }, + { + MyEnum.b, + MyEnum2.d + } + }); + } + + public static void NotACollectionInitializer() + { + List list = new List(); + list.Add(1); + list.Add(2); + list.Add(3); + InitializerTests.X(InitializerTests.Y(), list); + } + + public static void ObjectInitializer() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.a + }); + } + + public static void NotAnObjectInitializer() + { + Data data = new Data(); + data.a = MyEnum.a; + InitializerTests.X(InitializerTests.Y(), data); + } + + public static void ObjectInitializerAssignCollectionToField() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.a, + FieldList = new List { + MyEnum2.c, + MyEnum2.d + } + }); + } + + public static void ObjectInitializerAddToCollectionInField() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.a, + FieldList = { + MyEnum2.c, + MyEnum2.d + } + }); + } + + public static void ObjectInitializerAssignCollectionToProperty() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.a, + PropertyList = new List { + MyEnum2.c, + MyEnum2.d + } + }); + } + + public static void ObjectInitializerAddToCollectionInProperty() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.a, + PropertyList = { + MyEnum2.c, + MyEnum2.d + } + }); + } + + public static void ObjectInitializerWithInitializationOfNestedObjects() + { + InitializerTests.X(InitializerTests.Y(), new Data { + MoreData = { + a = MyEnum.a, + MoreData = { + a = MyEnum.b + } + } + }); + } + + private static int GetInt() + { + return 1; + } + + private static string GetString() + { + return "Test"; + } + +#if !LEGACY_CSC + public static void SimpleDictInitializer() + { + InitializerTests.X(InitializerTests.Y(), new Data { + MoreData = { + a = MyEnum.a, + [2] = (Data)null + } + }); + } + + public static void MixedObjectAndDictInitializer() + { + InitializerTests.X(InitializerTests.Y(), new Data { + MoreData = { + a = MyEnum.a, + [GetInt()] = { + a = MyEnum.b, + FieldList = { MyEnum2.c }, + [GetInt(), GetString()] = new Data(), + [2] = (Data)null + } + } + }); + } +#endif + + public static void ObjectInitializerWithInitializationOfDeeplyNestedObjects() + { + InitializerTests.X(InitializerTests.Y(), new Data { + a = MyEnum.b, + MoreData = { + a = MyEnum.a, + MoreData = { + MoreData = { + MoreData = { + MoreData = { + MoreData = { + MoreData = { + a = MyEnum.b + } + } + } + } + } + } + } + }); + } + + public static void CollectionInitializerInsideObjectInitializers() + { + InitializerTests.X(InitializerTests.Y(), new Data { + MoreData = new Data { + a = MyEnum.a, + b = MyEnum.b, + PropertyList = { + MyEnum2.c + } + } + }); + } + + public static void NotAStructInitializer_DefaultConstructor() + { + StructData structData = new StructData(); + structData.Field = 1; + structData.Property = 2; + InitializerTests.X(InitializerTests.Y(), structData); + } + + public static void StructInitializer_DefaultConstructor() + { + InitializerTests.X(InitializerTests.Y(), new StructData { + Field = 1, + Property = 2 + }); + } + + public static void NotAStructInitializer_ExplicitConstructor() + { + StructData structData = new StructData(0); + structData.Field = 1; + structData.Property = 2; + InitializerTests.X(InitializerTests.Y(), structData); + } + + public static void StructInitializer_ExplicitConstructor() + { + InitializerTests.X(InitializerTests.Y(), new StructData(0) { + Field = 1, + Property = 2 + }); + } + + public static void StructInitializerWithInitializationOfNestedObjects() + { + InitializerTests.X(InitializerTests.Y(), new StructData { + MoreData = { + a = MyEnum.a, + FieldList = { + MyEnum2.c, + MyEnum2.d + } + } + }); + } + + public static void StructInitializerWithinObjectInitializer() + { + InitializerTests.X(InitializerTests.Y(), new Data { + NestedStruct = new StructData(2) { + Field = 1, + Property = 2 + } + }); + } + + public static void Bug270_NestedInitialisers() + { + NumberFormatInfo[] source = null; + + InitializerTests.TestCall(0, new Thread(InitializerTests.Bug270_NestedInitialisers) { + Priority = ThreadPriority.BelowNormal, + CurrentCulture = new CultureInfo(0) { + DateTimeFormat = new DateTimeFormatInfo { + ShortDatePattern = "ddmmyy" + }, + NumberFormat = (from format in source + where format.CurrencySymbol == "$" + select format).First() + } + }); + } } } \ 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 d6a62db22..3e9c08183 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -10,25 +10,30 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly umgm00go +.assembly extern System.Core +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly xws4p1nr { - .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. + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 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 umgm00go.dll -// MVID: {8C42504A-ACC6-453C-81BA-626AB6649E25} +.module xws4p1nr.dll +// MVID: {D353AAAB-C54F-4C62-88DC-E9FF995570BA} .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 -// Image base: 0x02AE0000 +// Image base: 0x002F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -76,6 +81,430 @@ } // end of class S + .class auto ansi sealed nested private MyEnum + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b = int32(0x00000001) + } // end of class MyEnum + + .class auto ansi sealed nested private MyEnum2 + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 c = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 d = int32(0x00000001) + } // end of class MyEnum2 + + .class auto ansi nested private beforefieldinit Data + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. + .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [mscorlib]System.Collections.Generic.List`1 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_a() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method Data::get_a + + .method public hidebysig specialname + instance void set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_a + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_b() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method Data::get_b + + .method public hidebysig specialname + instance void set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_b + + .method public hidebysig specialname + instance class [mscorlib]System.Collections.Generic.List`1 + get_PropertyList() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method Data::get_PropertyList + + .method public hidebysig specialname + instance void set_PropertyList(class [mscorlib]System.Collections.Generic.List`1 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_PropertyList + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method Data::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_MoreData + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + get_NestedStruct() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method Data::get_NestedStruct + + .method public hidebysig specialname + instance void set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_NestedStruct + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method Data::set_Item + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i, + string j) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + string j, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method Data::set_Item + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_000b: ldarg.0 + IL_000c: call instance void [mscorlib]System.Object::.ctor() + IL_0011: nop + IL_0012: ret + } // end of method Data::.ctor + + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + a() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_a() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::a + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + b() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + } // end of property Data::b + .property instance class [mscorlib]System.Collections.Generic.List`1 + PropertyList() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + } // end of property Data::PropertyList + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::MoreData + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + NestedStruct() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + } // end of property Data::NestedStruct + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32, + string) + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32, + string) + } // end of property Data::Item + } // end of class Data + + .class sequential ansi sealed nested private beforefieldinit StructData + extends [mscorlib]System.ValueType + { + .field public int32 Field + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance int32 get_Property() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method StructData::get_Property + + .method public hidebysig specialname + instance void set_Property(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_Property + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method StructData::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_MoreData + + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 initialValue) cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_000f: ldarg.0 + IL_0010: ldarg.1 + IL_0011: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0016: nop + IL_0017: ret + } // end of method StructData::.ctor + + .property instance int32 Property() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + } // end of property StructData::Property + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property StructData::MoreData + } // end of class StructData + + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1a' + .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 + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method InitializerTests::X + + .method private hidebysig static object + Y() cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (object V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::Y + + .method public hidebysig static void TestCall(int32 a, + class [mscorlib]System.Threading.Thread thread) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method InitializerTests::TestCall + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C TestCall(int32 a, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed @@ -258,6 +687,674 @@ IL_002b: ret } // end of method InitializerTests::Test4 + .method public hidebysig static void CollectionInitializerList() cil managed + { + // Code size 44 (0x2c) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: ldc.i4.2 + IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001b: nop + IL_001c: ldloc.0 + IL_001d: ldc.i4.3 + IL_001e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.0 + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::CollectionInitializerList + + .method public hidebysig static object + RecursiveCollectionInitializer() cil managed + { + // Code size 21 (0x15) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0, + object V_1) + IL_0000: nop + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldloc.0 + IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000e: nop + IL_000f: ldloc.0 + IL_0010: stloc.1 + IL_0011: br.s IL_0013 + + IL_0013: ldloc.1 + IL_0014: ret + } // end of method InitializerTests::RecursiveCollectionInitializer + + .method public hidebysig static void CollectionInitializerDictionary() cil managed + { + // Code size 59 (0x3b) + .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::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 "First" + IL_0012: ldc.i4.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: ldstr "Second" + IL_001f: ldc.i4.2 + IL_0020: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0025: nop + IL_0026: ldloc.0 + IL_0027: ldstr "Third" + IL_002c: ldc.i4.3 + IL_002d: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0032: nop + IL_0033: ldloc.0 + IL_0034: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0039: nop + IL_003a: ret + } // end of method InitializerTests::CollectionInitializerDictionary + + .method public hidebysig static void CollectionInitializerDictionaryWithEnumTypes() cil managed + { + // Code size 38 (0x26) + .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::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0014: nop + IL_0015: ldloc.0 + IL_0016: ldc.i4.1 + IL_0017: ldc.i4.1 + IL_0018: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_001d: nop + IL_001e: ldloc.0 + IL_001f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0024: nop + IL_0025: ret + } // end of method InitializerTests::CollectionInitializerDictionaryWithEnumTypes + + .method public hidebysig static void NotACollectionInitializer() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: nop + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000e: nop + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0016: nop + IL_0017: ldloc.0 + IL_0018: ldc.i4.3 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: nop + IL_001f: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0024: ldloc.0 + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::NotACollectionInitializer + + .method public hidebysig static void ObjectInitializer() cil managed + { + // Code size 28 (0x1c) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_001a: nop + IL_001b: ret + } // end of method InitializerTests::ObjectInitializer + + .method public hidebysig static void NotAnObjectInitializer() cil managed + { + // Code size 28 (0x1c) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.0 + IL_0009: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_000e: nop + IL_000f: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0014: ldloc.0 + IL_0015: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_001a: nop + IL_001b: ret + } // end of method InitializerTests::NotAnObjectInitializer + + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed + { + // Code size 57 (0x39) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.0 + IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0022: nop + IL_0023: ldloc.1 + IL_0024: ldc.i4.1 + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0031: ldloc.0 + IL_0032: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0037: nop + IL_0038: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToField + + .method public hidebysig static void ObjectInitializerAddToCollectionInField() cil managed + { + // Code size 54 (0x36) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: nop + IL_0021: ldloc.0 + IL_0022: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0027: ldc.i4.1 + IL_0028: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002d: nop + IL_002e: ldloc.0 + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: nop + IL_0035: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInField + + .method public hidebysig static void ObjectInitializerAssignCollectionToProperty() cil managed + { + // Code size 58 (0x3a) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.0 + IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0022: nop + IL_0023: ldloc.1 + IL_0024: ldc.i4.1 + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + IL_0031: nop + IL_0032: ldloc.0 + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0038: nop + IL_0039: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToProperty + + .method public hidebysig static void ObjectInitializerAddToCollectionInProperty() cil managed + { + // Code size 54 (0x36) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: nop + IL_0021: ldloc.0 + IL_0022: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0027: ldc.i4.1 + IL_0028: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002d: nop + IL_002e: ldloc.0 + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: nop + IL_0035: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInProperty + + .method public hidebysig static void ObjectInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 51 (0x33) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0012: ldc.i4.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0018: nop + IL_0019: ldloc.0 + IL_001a: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0024: ldc.i4.1 + IL_0025: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_002a: nop + IL_002b: ldloc.0 + IL_002c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0031: nop + IL_0032: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfNestedObjects + + .method private hidebysig static int32 + GetInt() cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::GetInt + + .method private hidebysig static string + GetString() cil managed + { + // Code size 11 (0xb) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldstr "Test" + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method InitializerTests::GetString + + .method public hidebysig static void ObjectInitializerWithInitializationOfDeeplyNestedObjects() cil managed + { + // Code size 84 (0x54) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0013: nop + IL_0014: ldloc.0 + IL_0015: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0020: nop + IL_0021: ldloc.0 + IL_0022: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0027: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_002c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0031: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0036: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_003b: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0040: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0045: ldc.i4.1 + IL_0046: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_004b: nop + IL_004c: ldloc.0 + IL_004d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0052: nop + IL_0053: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfDeeplyNestedObjects + + .method public hidebysig static void CollectionInitializerInsideObjectInitializers() cil managed + { + // Code size 63 (0x3f) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_1) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0012: stloc.1 + IL_0013: ldloc.1 + IL_0014: ldc.i4.0 + IL_0015: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001a: nop + IL_001b: ldloc.1 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0022: nop + IL_0023: ldloc.1 + IL_0024: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0029: ldc.i4.0 + IL_002a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002f: nop + IL_0030: ldloc.1 + IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0036: nop + IL_0037: ldloc.0 + IL_0038: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_003d: nop + IL_003e: ret + } // end of method InitializerTests::CollectionInitializerInsideObjectInitializers + + .method public hidebysig static void NotAStructInitializer_DefaultConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: ldloca.s V_0 + IL_0003: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0009: ldloca.s V_0 + IL_000b: ldc.i4.1 + IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.2 + IL_0014: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0019: nop + IL_001a: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::NotAStructInitializer_DefaultConstructor + + .method public hidebysig static void StructInitializer_DefaultConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.1 + IL_0011: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.2 + IL_0019: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001e: nop + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::StructInitializer_DefaultConstructor + + .method public hidebysig static void NotAStructInitializer_ExplicitConstructor() cil managed + { + // Code size 45 (0x2d) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: ldloca.s V_0 + IL_0003: ldc.i4.0 + IL_0004: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0009: nop + IL_000a: ldloca.s V_0 + IL_000c: ldc.i4.1 + IL_000d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0012: ldloca.s V_0 + IL_0014: ldc.i4.2 + IL_0015: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001a: nop + IL_001b: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0020: ldloc.0 + IL_0021: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002b: nop + IL_002c: ret + } // end of method InitializerTests::NotAStructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializer_ExplicitConstructor() cil managed + { + // Code size 45 (0x2d) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: ldc.i4.0 + IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_000e: nop + IL_000f: ldloca.s V_0 + IL_0011: ldc.i4.1 + IL_0012: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0017: ldloca.s V_0 + IL_0019: ldc.i4.2 + IL_001a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001f: nop + IL_0020: ldloc.0 + IL_0021: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002b: nop + IL_002c: ret + } // end of method InitializerTests::StructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 79 (0x4f) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000e: ldloca.s V_0 + IL_0010: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0015: ldc.i4.0 + IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001b: nop + IL_001c: ldloca.s V_0 + IL_001e: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0023: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0028: ldc.i4.0 + IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002e: nop + IL_002f: ldloca.s V_0 + IL_0031: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0036: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_003b: ldc.i4.1 + IL_003c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0041: nop + IL_0042: ldloc.0 + IL_0043: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0048: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_004d: nop + IL_004e: ret + } // end of method InitializerTests::StructInitializerWithInitializationOfNestedObjects + + .method public hidebysig static void StructInitializerWithinObjectInitializer() cil managed + { + // Code size 54 (0x36) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_1) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldloca.s V_1 + IL_000f: ldc.i4.2 + IL_0010: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0015: nop + IL_0016: ldloca.s V_1 + IL_0018: ldc.i4.1 + IL_0019: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_001e: ldloca.s V_1 + IL_0020: ldc.i4.2 + IL_0021: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0026: nop + IL_0027: ldloc.1 + IL_0028: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + IL_002d: nop + IL_002e: ldloc.0 + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: nop + IL_0035: ret + } // end of method InitializerTests::StructInitializerWithinObjectInitializer + + .method public hidebysig static void Bug270_NestedInitialisers() cil managed + { + // Code size 128 (0x80) + .maxstack 6 + .locals init (class [mscorlib]System.Globalization.NumberFormatInfo[] V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Globalization.CultureInfo V_2, + class [mscorlib]System.Globalization.DateTimeFormatInfo V_3) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: ldc.i4.0 + IL_0004: ldnull + IL_0005: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Bug270_NestedInitialisers() + IL_000b: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0010: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0015: stloc.1 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: callvirt instance void [mscorlib]System.Threading.Thread::set_Priority(valuetype [mscorlib]System.Threading.ThreadPriority) + IL_001d: nop + IL_001e: ldloc.1 + IL_001f: ldc.i4.0 + IL_0020: newobj instance void [mscorlib]System.Globalization.CultureInfo::.ctor(int32) + IL_0025: stloc.2 + IL_0026: ldloc.2 + IL_0027: newobj instance void [mscorlib]System.Globalization.DateTimeFormatInfo::.ctor() + IL_002c: stloc.3 + IL_002d: ldloc.3 + IL_002e: ldstr "ddmmyy" + IL_0033: callvirt instance void [mscorlib]System.Globalization.DateTimeFormatInfo::set_ShortDatePattern(string) + IL_0038: nop + IL_0039: ldloc.3 + IL_003a: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_DateTimeFormat(class [mscorlib]System.Globalization.DateTimeFormatInfo) + 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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0047: brtrue.s IL_005c + + IL_0049: ldnull + IL_004a: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__19'(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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_005a: br.s IL_005c + + IL_005c: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1a' + 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) + IL_006b: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_NumberFormat(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0070: nop + IL_0071: ldloc.2 + IL_0072: callvirt instance void [mscorlib]System.Threading.Thread::set_CurrentCulture(class [mscorlib]System.Globalization.CultureInfo) + IL_0077: nop + IL_0078: ldloc.1 + IL_0079: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class [mscorlib]System.Threading.Thread) + IL_007e: nop + IL_007f: ret + } // end of method InitializerTests::Bug270_NestedInitialisers + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -268,6 +1365,24 @@ IL_0006: ret } // end of method InitializerTests::.ctor + .method private hidebysig static bool 'b__19'(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) + .maxstack 2 + .locals init (bool V_0) + IL_0000: ldarg.0 + IL_0001: callvirt instance string [mscorlib]System.Globalization.NumberFormatInfo::get_CurrencySymbol() + IL_0006: ldstr "$" + IL_000b: call bool [mscorlib]System.String::op_Equality(string, + string) + IL_0010: stloc.0 + IL_0011: br.s IL_0013 + + IL_0013: ldloc.0 + IL_0014: ret + } // end of method InitializerTests::'b__19' + } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il index ac94bb18e..f7dcef8e8 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -10,25 +10,30 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly ecxzpbak +.assembly extern System.Core +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly '3csuofts' { - .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. + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 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 ecxzpbak.dll -// MVID: {F67EEE6A-7EFF-4261-9FC7-3F2C4A0972E9} +.module '3csuofts.dll' +// MVID: {F78A061E-BAE5-4B9C-AFCF-4B60D826C849} .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 -// Image base: 0x02430000 +// Image base: 0x00D80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -75,6 +80,370 @@ } // end of class S + .class auto ansi sealed nested private MyEnum + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b = int32(0x00000001) + } // end of class MyEnum + + .class auto ansi sealed nested private MyEnum2 + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 c = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 d = int32(0x00000001) + } // end of class MyEnum2 + + .class auto ansi nested private beforefieldinit Data + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. + .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [mscorlib]System.Collections.Generic.List`1 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_a() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_a + + .method public hidebysig specialname + instance void set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_a + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_b() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_b + + .method public hidebysig specialname + instance void set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_b + + .method public hidebysig specialname + instance class [mscorlib]System.Collections.Generic.List`1 + get_PropertyList() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_PropertyList + + .method public hidebysig specialname + instance void set_PropertyList(class [mscorlib]System.Collections.Generic.List`1 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_PropertyList + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_MoreData + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + get_NestedStruct() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_NestedStruct + + .method public hidebysig specialname + instance void set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_NestedStruct + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method Data::set_Item + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i, + string j) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + string j, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method Data::set_Item + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_000b: ldarg.0 + IL_000c: call instance void [mscorlib]System.Object::.ctor() + IL_0011: ret + } // end of method Data::.ctor + + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + a() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_a() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::a + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + b() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + } // end of property Data::b + .property instance class [mscorlib]System.Collections.Generic.List`1 + PropertyList() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + } // end of property Data::PropertyList + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::MoreData + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + NestedStruct() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + } // end of property Data::NestedStruct + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32, + string) + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32, + string) + } // end of property Data::Item + } // end of class Data + + .class sequential ansi sealed nested private beforefieldinit StructData + extends [mscorlib]System.ValueType + { + .field public int32 Field + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance int32 get_Property() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_Property + + .method public hidebysig specialname + instance void set_Property(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_Property + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_MoreData + + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 initialValue) cil managed + { + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0007: ldarg.0 + IL_0008: ldarg.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_000e: ldarg.0 + IL_000f: ldarg.1 + IL_0010: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0015: ret + } // end of method StructData::.ctor + + .property instance int32 Property() + { + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + } // end of property StructData::Property + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property StructData::MoreData + } // end of class StructData + + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1a' + .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 + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method InitializerTests::X + + .method private hidebysig static object + Y() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method InitializerTests::Y + + .method public hidebysig static void TestCall(int32 a, + class [mscorlib]System.Threading.Thread thread) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method InitializerTests::TestCall + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C TestCall(int32 a, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed @@ -213,6 +582,561 @@ IL_0026: ret } // end of method InitializerTests::Test4 + .method public hidebysig static void CollectionInitializerList() cil managed + { + // Code size 39 (0x27) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.1 + IL_000d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0012: ldloc.0 + IL_0013: ldc.i4.2 + IL_0014: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0019: ldloc.0 + IL_001a: ldc.i4.3 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: ldloc.0 + IL_0021: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0026: ret + } // end of method InitializerTests::CollectionInitializerList + + .method public hidebysig static object + RecursiveCollectionInitializer() cil managed + { + // Code size 15 (0xf) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldloc.0 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldloc.0 + IL_000e: ret + } // end of method InitializerTests::RecursiveCollectionInitializer + + .method public hidebysig static void CollectionInitializerDictionary() cil managed + { + // Code size 54 (0x36) + .maxstack 4 + .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::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 "First" + IL_0011: ldc.i4.1 + IL_0012: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0017: ldloc.0 + IL_0018: ldstr "Second" + IL_001d: ldc.i4.2 + IL_001e: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0023: ldloc.0 + IL_0024: ldstr "Third" + IL_0029: ldc.i4.3 + IL_002a: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_002f: ldloc.0 + IL_0030: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0035: ret + } // end of method InitializerTests::CollectionInitializerDictionary + + .method public hidebysig static void CollectionInitializerDictionaryWithEnumTypes() cil managed + { + // Code size 34 (0x22) + .maxstack 4 + .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2 V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0013: ldloc.0 + IL_0014: ldc.i4.1 + IL_0015: ldc.i4.1 + IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_001b: ldloc.0 + IL_001c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0021: ret + } // end of method InitializerTests::CollectionInitializerDictionaryWithEnumTypes + + .method public hidebysig static void NotACollectionInitializer() cil managed + { + // Code size 39 (0x27) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.1 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldloc.0 + IL_000e: ldc.i4.2 + IL_000f: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0014: ldloc.0 + IL_0015: ldc.i4.3 + IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001b: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0020: ldloc.0 + IL_0021: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0026: ret + } // end of method InitializerTests::NotACollectionInitializer + + .method public hidebysig static void ObjectInitializer() cil managed + { + // Code size 25 (0x19) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0018: ret + } // end of method InitializerTests::ObjectInitializer + + .method public hidebysig static void NotAnObjectInitializer() cil managed + { + // Code size 25 (0x19) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.0 + IL_0008: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_000d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0012: ldloc.0 + IL_0013: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0018: ret + } // end of method InitializerTests::NotAnObjectInitializer + + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed + { + // Code size 52 (0x34) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0018: stloc.1 + IL_0019: ldloc.1 + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: ldloc.1 + IL_0021: ldc.i4.1 + IL_0022: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0027: ldloc.1 + IL_0028: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_002d: ldloc.0 + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0033: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToField + + .method public hidebysig static void ObjectInitializerAddToCollectionInField() cil managed + { + // Code size 49 (0x31) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0018: ldc.i4.0 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: ldloc.0 + IL_001f: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0024: ldc.i4.1 + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002a: ldloc.0 + IL_002b: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0030: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInField + + .method public hidebysig static void ObjectInitializerAssignCollectionToProperty() cil managed + { + // Code size 52 (0x34) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class [mscorlib]System.Collections.Generic.List`1 V_1) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0018: stloc.1 + IL_0019: ldloc.1 + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: ldloc.1 + IL_0021: ldc.i4.1 + IL_0022: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0027: ldloc.1 + IL_0028: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + IL_002d: ldloc.0 + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0033: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToProperty + + .method public hidebysig static void ObjectInitializerAddToCollectionInProperty() cil managed + { + // Code size 49 (0x31) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0018: ldc.i4.0 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: ldloc.0 + IL_001f: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0024: ldc.i4.1 + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002a: ldloc.0 + IL_002b: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0030: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInProperty + + .method public hidebysig static void ObjectInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 47 (0x2f) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0011: ldc.i4.0 + IL_0012: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0017: ldloc.0 + IL_0018: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001d: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0022: ldc.i4.1 + IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0028: ldloc.0 + IL_0029: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002e: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfNestedObjects + + .method private hidebysig static int32 + GetInt() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } // end of method InitializerTests::GetInt + + .method private hidebysig static string + GetString() cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "Test" + IL_0005: ret + } // end of method InitializerTests::GetString + + .method public hidebysig static void ObjectInitializerWithInitializationOfDeeplyNestedObjects() cil managed + { + // Code size 79 (0x4f) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.1 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: ldloc.0 + IL_0013: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0018: ldc.i4.0 + IL_0019: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001e: ldloc.0 + IL_001f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0024: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0029: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_002e: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0033: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0038: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_003d: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0042: ldc.i4.1 + IL_0043: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0048: ldloc.0 + IL_0049: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_004e: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfDeeplyNestedObjects + + .method public hidebysig static void CollectionInitializerInsideObjectInitializers() cil managed + { + // Code size 57 (0x39) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_1) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0011: stloc.1 + IL_0012: ldloc.1 + IL_0013: ldc.i4.0 + IL_0014: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0019: ldloc.1 + IL_001a: ldc.i4.1 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0020: ldloc.1 + IL_0021: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0026: ldc.i4.0 + IL_0027: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002c: ldloc.1 + IL_002d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0032: ldloc.0 + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0038: ret + } // end of method InitializerTests::CollectionInitializerInsideObjectInitializers + + .method public hidebysig static void NotAStructInitializer_DefaultConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0010: ldloca.s V_0 + IL_0012: ldc.i4.2 + IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0018: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::NotAStructInitializer_DefaultConstructor + + .method public hidebysig static void StructInitializer_DefaultConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.1 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0015: ldloca.s V_0 + IL_0017: ldc.i4.2 + IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::StructInitializer_DefaultConstructor + + .method public hidebysig static void NotAStructInitializer_ExplicitConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.0 + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0010: ldloca.s V_0 + IL_0012: ldc.i4.2 + IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0018: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::NotAStructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializer_ExplicitConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: ldc.i4.0 + IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.1 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0015: ldloca.s V_0 + IL_0017: ldc.i4.2 + IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::StructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 74 (0x4a) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000d: ldloca.s V_0 + IL_000f: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0014: ldc.i4.0 + IL_0015: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001a: ldloca.s V_0 + IL_001c: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0021: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0026: ldc.i4.0 + IL_0027: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002c: ldloca.s V_0 + IL_002e: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0033: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0038: ldc.i4.1 + IL_0039: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_003e: ldloc.0 + IL_003f: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0044: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0049: ret + } // end of method InitializerTests::StructInitializerWithInitializationOfNestedObjects + + .method public hidebysig static void StructInitializerWithinObjectInitializer() cil managed + { + // Code size 49 (0x31) + .maxstack 4 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_1) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldloca.s V_1 + IL_000e: ldc.i4.2 + IL_000f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0014: ldloca.s V_1 + IL_0016: ldc.i4.1 + IL_0017: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_001c: ldloca.s V_1 + IL_001e: ldc.i4.2 + IL_001f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0024: ldloc.1 + IL_0025: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + IL_002a: ldloc.0 + IL_002b: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0030: ret + } // end of method InitializerTests::StructInitializerWithinObjectInitializer + + .method public hidebysig static void Bug270_NestedInitialisers() cil managed + { + // Code size 119 (0x77) + .maxstack 6 + .locals init (class [mscorlib]System.Globalization.NumberFormatInfo[] V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Globalization.CultureInfo V_2, + class [mscorlib]System.Globalization.DateTimeFormatInfo V_3) + IL_0000: ldnull + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: ldnull + IL_0004: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Bug270_NestedInitialisers() + IL_000a: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000f: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: callvirt instance void [mscorlib]System.Threading.Thread::set_Priority(valuetype [mscorlib]System.Threading.ThreadPriority) + IL_001c: ldloc.1 + IL_001d: ldc.i4.0 + IL_001e: newobj instance void [mscorlib]System.Globalization.CultureInfo::.ctor(int32) + IL_0023: stloc.2 + IL_0024: ldloc.2 + IL_0025: newobj instance void [mscorlib]System.Globalization.DateTimeFormatInfo::.ctor() + IL_002a: stloc.3 + IL_002b: ldloc.3 + IL_002c: ldstr "ddmmyy" + IL_0031: callvirt instance void [mscorlib]System.Globalization.DateTimeFormatInfo::set_ShortDatePattern(string) + IL_0036: ldloc.3 + 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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0043: brtrue.s IL_0056 + + IL_0045: ldnull + IL_0046: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__19'(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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0056: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1a' + 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) + IL_0065: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_NumberFormat(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_006a: ldloc.2 + IL_006b: callvirt instance void [mscorlib]System.Threading.Thread::set_CurrentCulture(class [mscorlib]System.Globalization.CultureInfo) + IL_0070: ldloc.1 + IL_0071: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class [mscorlib]System.Threading.Thread) + IL_0076: ret + } // end of method InitializerTests::Bug270_NestedInitialisers + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -223,6 +1147,19 @@ IL_0006: ret } // end of method InitializerTests::.ctor + .method private hidebysig static bool 'b__19'(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) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance string [mscorlib]System.Globalization.NumberFormatInfo::get_CurrencySymbol() + IL_0006: ldstr "$" + IL_000b: call bool [mscorlib]System.String::op_Equality(string, + string) + IL_0010: ret + } // end of method InitializerTests::'b__19' + } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il index 13eb53fdd..0f0385cd5 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -10,6 +10,11 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } +.assembly extern System.Core +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} .assembly InitializerTests { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) @@ -25,14 +30,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {F2C6C41E-98CC-4261-BF7B-1991B54DA121} +// MVID: {4B0BA9B1-521C-4C45-A2B8-8774D5BE797E} .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 -// Image base: 0x00700000 +// Image base: 0x01500000 // =============== CLASS MEMBERS DECLARATION =================== @@ -79,6 +84,409 @@ } // end of class S + .class auto ansi sealed nested private MyEnum + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b = int32(0x00000001) + } // end of class MyEnum + + .class auto ansi sealed nested private MyEnum2 + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 c = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 d = int32(0x00000001) + } // end of class MyEnum2 + + .class auto ansi nested private beforefieldinit Data + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. + .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [mscorlib]System.Collections.Generic.List`1 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_a() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_a + + .method public hidebysig specialname + instance void set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_a + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_b() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_b + + .method public hidebysig specialname + instance void set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_b + + .method public hidebysig specialname + instance class [mscorlib]System.Collections.Generic.List`1 + get_PropertyList() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_PropertyList + + .method public hidebysig specialname + instance void set_PropertyList(class [mscorlib]System.Collections.Generic.List`1 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_PropertyList + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_MoreData + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + get_NestedStruct() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_NestedStruct + + .method public hidebysig specialname + instance void set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_NestedStruct + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method Data::set_Item + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i, + string j) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + string j, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method Data::set_Item + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_000b: ldarg.0 + IL_000c: call instance void [mscorlib]System.Object::.ctor() + IL_0011: ret + } // end of method Data::.ctor + + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + a() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_a() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::a + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + b() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::b + .property instance class [mscorlib]System.Collections.Generic.List`1 + PropertyList() + { + .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + } // end of property Data::PropertyList + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::MoreData + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + NestedStruct() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + } // end of property Data::NestedStruct + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32, + string) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32, + string) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + } // end of class Data + + .class sequential ansi sealed nested private beforefieldinit StructData + extends [mscorlib]System.ValueType + { + .field public int32 Field + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname + instance int32 get_Property() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_Property + + .method public hidebysig specialname + instance void set_Property(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_Property + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_MoreData + + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 initialValue) cil managed + { + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0007: ldarg.0 + IL_0008: ldarg.1 + IL_0009: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_000e: ldarg.0 + IL_000f: ldarg.1 + IL_0010: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0015: ret + } // end of method StructData::.ctor + + .property instance int32 Property() + { + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + } // end of property StructData::Property + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property StructData::MoreData + } // end of class StructData + + .class auto ansi serializable sealed nested private beforefieldinit '<>c' + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' '<>9' + .field public static class [mscorlib]System.Func`2 '<>9__40_0' + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::.ctor() + IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_000a: ret + } // end of method '<>c'::.cctor + + .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 '<>c'::.ctor + + .method assembly hidebysig instance bool + 'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + { + // Code size 17 (0x11) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: callvirt instance string [mscorlib]System.Globalization.NumberFormatInfo::get_CurrencySymbol() + IL_0006: ldstr "$" + IL_000b: call bool [mscorlib]System.String::op_Equality(string, + string) + IL_0010: ret + } // end of method '<>c'::'b__40_0' + + } // end of class '<>c' + + .method private hidebysig static void X(object a, + object b) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method InitializerTests::X + + .method private hidebysig static object + Y() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method InitializerTests::Y + + .method public hidebysig static void TestCall(int32 a, + class [mscorlib]System.Threading.Thread thread) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method InitializerTests::TestCall + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C TestCall(int32 a, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed @@ -196,6 +604,582 @@ IL_0024: ret } // end of method InitializerTests::Test4 + .method public hidebysig static void CollectionInitializerList() cil managed + { + // Code size 37 (0x25) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000a: dup + IL_000b: ldc.i4.1 + IL_000c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0011: dup + IL_0012: ldc.i4.2 + IL_0013: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0018: dup + IL_0019: ldc.i4.3 + IL_001a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0024: ret + } // end of method InitializerTests::CollectionInitializerList + + .method public hidebysig static object + RecursiveCollectionInitializer() cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0005: dup + IL_0006: dup + IL_0007: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000c: ret + } // end of method InitializerTests::RecursiveCollectionInitializer + + .method public hidebysig static void CollectionInitializerDictionary() cil managed + { + // Code size 52 (0x34) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000a: dup + IL_000b: ldstr "First" + IL_0010: ldc.i4.1 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0016: dup + IL_0017: ldstr "Second" + IL_001c: ldc.i4.2 + IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0022: dup + IL_0023: ldstr "Third" + IL_0028: ldc.i4.3 + IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0033: ret + } // end of method InitializerTests::CollectionInitializerDictionary + + .method public hidebysig static void CollectionInitializerDictionaryWithEnumTypes() cil managed + { + // Code size 32 (0x20) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0012: dup + IL_0013: ldc.i4.1 + IL_0014: ldc.i4.1 + IL_0015: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_001a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_001f: ret + } // end of method InitializerTests::CollectionInitializerDictionaryWithEnumTypes + + .method public hidebysig static void NotACollectionInitializer() cil managed + { + // Code size 39 (0x27) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.1 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldloc.0 + IL_000e: ldc.i4.2 + IL_000f: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0014: ldloc.0 + IL_0015: ldc.i4.3 + IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001b: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0020: ldloc.0 + IL_0021: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0026: ret + } // end of method InitializerTests::NotACollectionInitializer + + .method public hidebysig static void ObjectInitializer() cil managed + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0016: ret + } // end of method InitializerTests::ObjectInitializer + + .method public hidebysig static void NotAnObjectInitializer() cil managed + { + // Code size 25 (0x19) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldc.i4.0 + IL_0008: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_000d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0012: ldloc.0 + IL_0013: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0018: ret + } // end of method InitializerTests::NotAnObjectInitializer + + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed + { + // Code size 48 (0x30) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: dup + IL_0012: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0017: dup + IL_0018: ldc.i4.0 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: dup + IL_001f: ldc.i4.1 + IL_0020: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0025: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_002a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002f: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToField + + .method public hidebysig static void ObjectInitializerAddToCollectionInField() cil managed + { + // Code size 47 (0x2f) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: dup + IL_0012: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0017: ldc.i4.0 + IL_0018: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001d: dup + IL_001e: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0023: ldc.i4.1 + IL_0024: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0029: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002e: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInField + + .method public hidebysig static void ObjectInitializerAssignCollectionToProperty() cil managed + { + // Code size 48 (0x30) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: dup + IL_0012: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0017: dup + IL_0018: ldc.i4.0 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: dup + IL_001f: ldc.i4.1 + IL_0020: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0025: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + IL_002a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002f: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToProperty + + .method public hidebysig static void ObjectInitializerAddToCollectionInProperty() cil managed + { + // Code size 47 (0x2f) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.0 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: dup + IL_0012: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0017: ldc.i4.0 + IL_0018: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001d: dup + IL_001e: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0023: ldc.i4.1 + IL_0024: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0029: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002e: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInProperty + + .method public hidebysig static void ObjectInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 45 (0x2d) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0010: ldc.i4.0 + IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0016: dup + IL_0017: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0021: ldc.i4.1 + IL_0022: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0027: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002c: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfNestedObjects + + .method private hidebysig static int32 + GetInt() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } // end of method InitializerTests::GetInt + + .method private hidebysig static string + GetString() cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "Test" + IL_0005: ret + } // end of method InitializerTests::GetString + + .method public hidebysig static void SimpleDictInitializer() cil managed + { + // Code size 41 (0x29) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0010: ldc.i4.0 + IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0016: dup + IL_0017: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001c: ldc.i4.2 + IL_001d: ldnull + IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::SimpleDictInitializer + + .method public hidebysig static void MixedObjectAndDictInitializer() cil managed + { + // Code size 130 (0x82) + .maxstack 6 + .locals init (int32 V_0, + int32 V_1, + string V_2) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0010: ldc.i4.0 + IL_0011: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0016: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetInt() + IL_001b: stloc.0 + IL_001c: dup + IL_001d: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0022: ldloc.0 + IL_0023: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_0028: ldc.i4.1 + IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_002e: dup + IL_002f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0034: ldloc.0 + IL_0035: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_003a: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_003f: ldc.i4.0 + IL_0040: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0045: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetInt() + IL_004a: stloc.1 + IL_004b: call string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetString() + IL_0050: stloc.2 + IL_0051: dup + IL_0052: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0057: ldloc.0 + IL_0058: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_005d: ldloc.1 + IL_005e: ldloc.2 + IL_005f: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0064: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0069: dup + IL_006a: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_006f: ldloc.0 + IL_0070: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_0075: ldc.i4.2 + IL_0076: ldnull + IL_0077: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_007c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0081: ret + } // end of method InitializerTests::MixedObjectAndDictInitializer + + .method public hidebysig static void ObjectInitializerWithInitializationOfDeeplyNestedObjects() cil managed + { + // Code size 77 (0x4d) + .maxstack 4 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldc.i4.1 + IL_000c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0011: dup + IL_0012: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0017: ldc.i4.0 + IL_0018: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001d: dup + IL_001e: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0023: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0028: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_002d: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0032: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0037: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_003c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0041: ldc.i4.1 + IL_0042: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0047: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_004c: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfDeeplyNestedObjects + + .method public hidebysig static void CollectionInitializerInsideObjectInitializers() cil managed + { + // Code size 53 (0x35) + .maxstack 8 + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0010: dup + IL_0011: ldc.i4.0 + IL_0012: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0017: dup + IL_0018: ldc.i4.1 + IL_0019: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001e: dup + IL_001f: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0024: ldc.i4.0 + IL_0025: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: ret + } // end of method InitializerTests::CollectionInitializerInsideObjectInitializers + + .method public hidebysig static void NotAStructInitializer_DefaultConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0010: ldloca.s V_0 + IL_0012: ldc.i4.2 + IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0018: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::NotAStructInitializer_DefaultConstructor + + .method public hidebysig static void StructInitializer_DefaultConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.1 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0015: ldloca.s V_0 + IL_0017: ldc.i4.2 + IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::StructInitializer_DefaultConstructor + + .method public hidebysig static void NotAStructInitializer_ExplicitConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.0 + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0010: ldloca.s V_0 + IL_0012: ldc.i4.2 + IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0018: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::NotAStructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializer_ExplicitConstructor() cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: ldc.i4.0 + IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.1 + IL_0010: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0015: ldloca.s V_0 + IL_0017: ldc.i4.2 + IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001d: ldloc.0 + IL_001e: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: ret + } // end of method InitializerTests::StructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 74 (0x4a) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: ldloca.s V_0 + IL_0007: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000d: ldloca.s V_0 + IL_000f: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0014: ldc.i4.0 + IL_0015: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001a: ldloca.s V_0 + IL_001c: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0021: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0026: ldc.i4.0 + IL_0027: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002c: ldloca.s V_0 + IL_002e: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0033: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0038: ldc.i4.1 + IL_0039: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_003e: ldloc.0 + IL_003f: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0044: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0049: ret + } // end of method InitializerTests::StructInitializerWithInitializationOfNestedObjects + + .method public hidebysig static void StructInitializerWithinObjectInitializer() cil managed + { + // Code size 47 (0x2f) + .maxstack 5 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000a: dup + IL_000b: ldloca.s V_0 + IL_000d: ldc.i4.2 + IL_000e: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0013: ldloca.s V_0 + IL_0015: ldc.i4.1 + IL_0016: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_001b: ldloca.s V_0 + IL_001d: ldc.i4.2 + IL_001e: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0023: ldloc.0 + IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + IL_0029: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002e: ret + } // end of method InitializerTests::StructInitializerWithinObjectInitializer + + .method public hidebysig static void Bug270_NestedInitialisers() cil managed + { + // Code size 115 (0x73) + .maxstack 8 + .locals init (class [mscorlib]System.Globalization.NumberFormatInfo[] V_0) + IL_0000: ldnull + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: ldnull + IL_0004: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Bug270_NestedInitialisers() + IL_000a: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000f: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0014: dup + IL_0015: ldc.i4.1 + IL_0016: callvirt instance void [mscorlib]System.Threading.Thread::set_Priority(valuetype [mscorlib]System.Threading.ThreadPriority) + IL_001b: dup + IL_001c: ldc.i4.0 + IL_001d: newobj instance void [mscorlib]System.Globalization.CultureInfo::.ctor(int32) + IL_0022: dup + IL_0023: newobj instance void [mscorlib]System.Globalization.DateTimeFormatInfo::.ctor() + IL_0028: dup + IL_0029: ldstr "ddmmyy" + IL_002e: callvirt instance void [mscorlib]System.Globalization.DateTimeFormatInfo::set_ShortDatePattern(string) + 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/'<>c'::'<>9__40_0' + IL_003f: dup + IL_0040: brtrue.s IL_0059 + + IL_0042: pop + IL_0043: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_0048: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__40_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/'<>c'::'<>9__40_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) + IL_0063: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_NumberFormat(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0068: callvirt instance void [mscorlib]System.Threading.Thread::set_CurrentCulture(class [mscorlib]System.Globalization.CultureInfo) + IL_006d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class [mscorlib]System.Threading.Thread) + IL_0072: ret + } // end of method InitializerTests::Bug270_NestedInitialisers + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il index 5db37abe9..d25f8725e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -10,6 +10,11 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } +.assembly extern System.Core +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} .assembly InitializerTests { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) @@ -25,14 +30,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {7000C1D7-C4EC-4376-B053-4BE74428CE7A} +// MVID: {EA222E3F-8F60-413B-AF03-0814FF05742B} .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 -// Image base: 0x005E0000 +// Image base: 0x00C80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -81,6 +86,442 @@ } // end of class S + .class auto ansi sealed nested private MyEnum + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b = int32(0x00000001) + } // end of class MyEnum + + .class auto ansi sealed nested private MyEnum2 + extends [mscorlib]System.Enum + { + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 c = int32(0x00000000) + .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum2 d = int32(0x00000001) + } // end of class MyEnum2 + + .class auto ansi nested private beforefieldinit Data + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. + .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private class [mscorlib]System.Collections.Generic.List`1 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_a() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_a + + .method public hidebysig specialname + instance void set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_a + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + get_b() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_b + + .method public hidebysig specialname + instance void set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_b + + .method public hidebysig specialname + instance class [mscorlib]System.Collections.Generic.List`1 + get_PropertyList() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_PropertyList + + .method public hidebysig specialname + instance void set_PropertyList(class [mscorlib]System.Collections.Generic.List`1 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_PropertyList + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_MoreData + + .method public hidebysig specialname + instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + get_NestedStruct() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0006: ret + } // end of method Data::get_NestedStruct + + .method public hidebysig specialname + instance void set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::'k__BackingField' + IL_0007: ret + } // end of method Data::set_NestedStruct + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method Data::set_Item + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_Item(int32 i, + string j) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method Data::get_Item + + .method public hidebysig specialname + instance void set_Item(int32 i, + string j, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method Data::set_Item + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_000b: ldarg.0 + IL_000c: call instance void [mscorlib]System.Object::.ctor() + IL_0011: nop + IL_0012: ret + } // end of method Data::.ctor + + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + a() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_a() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::a + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum + b() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + } // end of property Data::b + .property instance class [mscorlib]System.Collections.Generic.List`1 + PropertyList() + { + .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + } // end of property Data::PropertyList + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::MoreData + .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + NestedStruct() + { + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + } // end of property Data::NestedStruct + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + Item(int32, + string) + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32, + string) + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property Data::Item + } // end of class Data + + .class sequential ansi sealed nested private beforefieldinit StructData + extends [mscorlib]System.ValueType + { + .field public int32 Field + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname + instance int32 get_Property() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_Property + + .method public hidebysig specialname + instance void set_Property(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_Property + + .method public hidebysig specialname + instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + get_MoreData() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0006: ret + } // end of method StructData::get_MoreData + + .method public hidebysig specialname + instance void set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::'k__BackingField' + IL_0007: ret + } // end of method StructData::set_MoreData + + .method public hidebysig specialname rtspecialname + instance void .ctor(int32 initialValue) cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_000f: ldarg.0 + IL_0010: ldarg.1 + IL_0011: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0016: nop + IL_0017: ret + } // end of method StructData::.ctor + + .property instance int32 Property() + { + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + } // end of property StructData::Property + .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data + MoreData() + { + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + } // end of property StructData::MoreData + } // end of class StructData + + .class auto ansi serializable sealed nested private beforefieldinit '<>c' + extends [mscorlib]System.Object + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' '<>9' + .field public static class [mscorlib]System.Func`2 '<>9__40_0' + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::.ctor() + IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_000a: ret + } // end of method '<>c'::.cctor + + .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 '<>c'::.ctor + + .method assembly hidebysig instance bool + 'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + { + // Code size 17 (0x11) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: callvirt instance string [mscorlib]System.Globalization.NumberFormatInfo::get_CurrencySymbol() + IL_0006: ldstr "$" + IL_000b: call bool [mscorlib]System.String::op_Equality(string, + string) + IL_0010: ret + } // end of method '<>c'::'b__40_0' + + } // end of class '<>c' + + .method private hidebysig static void X(object a, + object b) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method InitializerTests::X + + .method private hidebysig static object + Y() cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (object V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::Y + + .method public hidebysig static void TestCall(int32 a, + class [mscorlib]System.Threading.Thread thread) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method InitializerTests::TestCall + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C TestCall(int32 a, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/C c) cil managed @@ -254,6 +695,704 @@ IL_002b: ret } // end of method InitializerTests::Test4 + .method public hidebysig static void CollectionInitializerList() cil managed + { + // Code size 42 (0x2a) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_000b: dup + IL_000c: ldc.i4.1 + IL_000d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0012: nop + IL_0013: dup + IL_0014: ldc.i4.2 + IL_0015: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001a: nop + IL_001b: dup + IL_001c: ldc.i4.3 + IL_001d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0022: nop + IL_0023: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0028: nop + IL_0029: ret + } // end of method InitializerTests::CollectionInitializerList + + .method public hidebysig static object + RecursiveCollectionInitializer() cil managed + { + // Code size 21 (0x15) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0, + object V_1) + IL_0000: nop + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldloc.0 + IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000e: nop + IL_000f: ldloc.0 + IL_0010: stloc.1 + IL_0011: br.s IL_0013 + + IL_0013: ldloc.1 + IL_0014: ret + } // end of method InitializerTests::RecursiveCollectionInitializer + + .method public hidebysig static void CollectionInitializerDictionary() cil managed + { + // Code size 57 (0x39) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000b: dup + IL_000c: ldstr "First" + IL_0011: ldc.i4.1 + IL_0012: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0017: nop + IL_0018: dup + IL_0019: ldstr "Second" + IL_001e: ldc.i4.2 + IL_001f: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0024: nop + IL_0025: dup + IL_0026: ldstr "Third" + IL_002b: ldc.i4.3 + IL_002c: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0031: nop + IL_0032: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0037: nop + IL_0038: ret + } // end of method InitializerTests::CollectionInitializerDictionary + + .method public hidebysig static void CollectionInitializerDictionaryWithEnumTypes() cil managed + { + // Code size 36 (0x24) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: ldc.i4.0 + IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_0013: nop + IL_0014: dup + IL_0015: ldc.i4.1 + IL_0016: ldc.i4.1 + IL_0017: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, + !1) + IL_001c: nop + IL_001d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0022: nop + IL_0023: ret + } // end of method InitializerTests::CollectionInitializerDictionaryWithEnumTypes + + .method public hidebysig static void NotACollectionInitializer() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (class [mscorlib]System.Collections.Generic.List`1 V_0) + IL_0000: nop + IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000e: nop + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0016: nop + IL_0017: ldloc.0 + IL_0018: ldc.i4.3 + IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001e: nop + IL_001f: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0024: ldloc.0 + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::NotACollectionInitializer + + .method public hidebysig static void ObjectInitializer() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0018: nop + IL_0019: ret + } // end of method InitializerTests::ObjectInitializer + + .method public hidebysig static void NotAnObjectInitializer() cil managed + { + // Code size 28 (0x1c) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.0 + IL_0009: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_000e: nop + IL_000f: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0014: ldloc.0 + IL_0015: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_001a: nop + IL_001b: ret + } // end of method InitializerTests::NotAnObjectInitializer + + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed + { + // Code size 53 (0x35) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: dup + IL_0014: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0019: dup + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: nop + IL_0021: dup + IL_0022: ldc.i4.1 + IL_0023: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0028: nop + IL_0029: stfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0033: nop + IL_0034: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToField + + .method public hidebysig static void ObjectInitializerAddToCollectionInField() cil managed + { + // Code size 52 (0x34) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: dup + IL_0014: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0019: ldc.i4.0 + IL_001a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001f: nop + IL_0020: dup + IL_0021: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0026: ldc.i4.1 + IL_0027: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002c: nop + IL_002d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0032: nop + IL_0033: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInField + + .method public hidebysig static void ObjectInitializerAssignCollectionToProperty() cil managed + { + // Code size 54 (0x36) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: dup + IL_0014: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor() + IL_0019: dup + IL_001a: ldc.i4.0 + IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0020: nop + IL_0021: dup + IL_0022: ldc.i4.1 + IL_0023: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0028: nop + IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) + IL_002e: nop + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: nop + IL_0035: ret + } // end of method InitializerTests::ObjectInitializerAssignCollectionToProperty + + .method public hidebysig static void ObjectInitializerAddToCollectionInProperty() cil managed + { + // Code size 52 (0x34) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.0 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: dup + IL_0014: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0019: ldc.i4.0 + IL_001a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001f: nop + IL_0020: dup + IL_0021: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0026: ldc.i4.1 + IL_0027: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002c: nop + IL_002d: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0032: nop + IL_0033: ret + } // end of method InitializerTests::ObjectInitializerAddToCollectionInProperty + + .method public hidebysig static void ObjectInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 49 (0x31) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0011: ldc.i4.0 + IL_0012: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0017: nop + IL_0018: dup + IL_0019: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001e: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0023: ldc.i4.1 + IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0029: nop + IL_002a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002f: nop + IL_0030: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfNestedObjects + + .method private hidebysig static int32 + GetInt() cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method InitializerTests::GetInt + + .method private hidebysig static string + GetString() cil managed + { + // Code size 11 (0xb) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldstr "Test" + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method InitializerTests::GetString + + .method public hidebysig static void SimpleDictInitializer() cil managed + { + // Code size 45 (0x2d) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0011: ldc.i4.0 + IL_0012: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0017: nop + IL_0018: dup + IL_0019: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_001e: ldc.i4.2 + IL_001f: ldnull + IL_0020: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0025: nop + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002b: nop + IL_002c: ret + } // end of method InitializerTests::SimpleDictInitializer + + .method public hidebysig static void MixedObjectAndDictInitializer() cil managed + { + // Code size 137 (0x89) + .maxstack 6 + .locals init (int32 V_0, + int32 V_1, + string V_2) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0011: ldc.i4.0 + IL_0012: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0017: nop + IL_0018: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetInt() + IL_001d: stloc.0 + IL_001e: dup + IL_001f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0024: ldloc.0 + IL_0025: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_002a: ldc.i4.1 + IL_002b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0030: nop + IL_0031: dup + IL_0032: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0037: ldloc.0 + IL_0038: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_003d: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0042: ldc.i4.0 + IL_0043: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0048: nop + IL_0049: call int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetInt() + IL_004e: stloc.1 + IL_004f: call string ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::GetString() + IL_0054: stloc.2 + IL_0055: dup + IL_0056: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_005b: ldloc.0 + IL_005c: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_0061: ldloc.1 + IL_0062: ldloc.2 + IL_0063: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0068: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + string, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_006d: nop + IL_006e: dup + IL_006f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0074: ldloc.0 + IL_0075: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) + IL_007a: ldc.i4.2 + IL_007b: ldnull + IL_007c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0081: nop + IL_0082: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0087: nop + IL_0088: ret + } // end of method InitializerTests::MixedObjectAndDictInitializer + + .method public hidebysig static void ObjectInitializerWithInitializationOfDeeplyNestedObjects() cil managed + { + // Code size 82 (0x52) + .maxstack 4 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldc.i4.1 + IL_000d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0012: nop + IL_0013: dup + IL_0014: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0019: ldc.i4.0 + IL_001a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001f: nop + IL_0020: dup + IL_0021: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0026: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_002b: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0030: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0035: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_003a: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_003f: callvirt instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() + IL_0044: ldc.i4.1 + IL_0045: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_004a: nop + IL_004b: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0050: nop + IL_0051: ret + } // end of method InitializerTests::ObjectInitializerWithInitializationOfDeeplyNestedObjects + + .method public hidebysig static void CollectionInitializerInsideObjectInitializers() cil managed + { + // Code size 59 (0x3b) + .maxstack 8 + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0011: dup + IL_0012: ldc.i4.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0018: nop + IL_0019: dup + IL_001a: ldc.i4.1 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_0020: nop + IL_0021: dup + IL_0022: callvirt instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + IL_0027: ldc.i4.0 + IL_0028: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002d: nop + IL_002e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + IL_0033: nop + IL_0034: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0039: nop + IL_003a: ret + } // end of method InitializerTests::CollectionInitializerInsideObjectInitializers + + .method public hidebysig static void NotAStructInitializer_DefaultConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: ldloca.s V_0 + IL_0003: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0009: ldloca.s V_0 + IL_000b: ldc.i4.1 + IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.2 + IL_0014: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0019: nop + IL_001a: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::NotAStructInitializer_DefaultConstructor + + .method public hidebysig static void StructInitializer_DefaultConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.1 + IL_0011: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.2 + IL_0019: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001e: nop + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::StructInitializer_DefaultConstructor + + .method public hidebysig static void NotAStructInitializer_ExplicitConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: ldloca.s V_0 + IL_0003: ldc.i4.0 + IL_0004: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0009: ldloca.s V_0 + IL_000b: ldc.i4.1 + IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.2 + IL_0014: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0019: nop + IL_001a: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::NotAStructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializer_ExplicitConstructor() cil managed + { + // Code size 44 (0x2c) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: ldc.i4.0 + IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.1 + IL_0011: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.2 + IL_0019: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_001e: nop + IL_001f: ldloc.0 + IL_0020: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0025: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_002a: nop + IL_002b: ret + } // end of method InitializerTests::StructInitializer_ExplicitConstructor + + .method public hidebysig static void StructInitializerWithInitializationOfNestedObjects() cil managed + { + // Code size 79 (0x4f) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: ldloca.s V_0 + IL_0008: initobj ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_000e: ldloca.s V_0 + IL_0010: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0015: ldc.i4.0 + IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_a(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) + IL_001b: nop + IL_001c: ldloca.s V_0 + IL_001e: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0023: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_0028: ldc.i4.0 + IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_002e: nop + IL_002f: ldloca.s V_0 + IL_0031: call instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_MoreData() + IL_0036: ldfld class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::FieldList + IL_003b: ldc.i4.1 + IL_003c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0041: nop + IL_0042: ldloc.0 + IL_0043: box ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData + IL_0048: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_004d: nop + IL_004e: ret + } // end of method InitializerTests::StructInitializerWithInitializationOfNestedObjects + + .method public hidebysig static void StructInitializerWithinObjectInitializer() cil managed + { + // Code size 51 (0x33) + .maxstack 5 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData V_0) + IL_0000: nop + IL_0001: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_000b: dup + IL_000c: ldloca.s V_0 + IL_000e: ldc.i4.2 + IL_000f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::.ctor(int32) + IL_0014: ldloca.s V_0 + IL_0016: ldc.i4.1 + IL_0017: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::Field + IL_001c: ldloca.s V_0 + IL_001e: ldc.i4.2 + IL_001f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) + IL_0024: nop + IL_0025: ldloc.0 + IL_0026: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + IL_002b: nop + IL_002c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0031: nop + IL_0032: ret + } // end of method InitializerTests::StructInitializerWithinObjectInitializer + + .method public hidebysig static void Bug270_NestedInitialisers() cil managed + { + // Code size 122 (0x7a) + .maxstack 8 + .locals init (class [mscorlib]System.Globalization.NumberFormatInfo[] V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: ldc.i4.0 + IL_0004: ldnull + IL_0005: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Bug270_NestedInitialisers() + IL_000b: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0010: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0015: dup + IL_0016: ldc.i4.1 + IL_0017: callvirt instance void [mscorlib]System.Threading.Thread::set_Priority(valuetype [mscorlib]System.Threading.ThreadPriority) + IL_001c: nop + IL_001d: dup + IL_001e: ldc.i4.0 + IL_001f: newobj instance void [mscorlib]System.Globalization.CultureInfo::.ctor(int32) + IL_0024: dup + IL_0025: newobj instance void [mscorlib]System.Globalization.DateTimeFormatInfo::.ctor() + IL_002a: dup + IL_002b: ldstr "ddmmyy" + IL_0030: callvirt instance void [mscorlib]System.Globalization.DateTimeFormatInfo::set_ShortDatePattern(string) + IL_0035: nop + IL_0036: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_DateTimeFormat(class [mscorlib]System.Globalization.DateTimeFormatInfo) + IL_003b: nop + IL_003c: dup + IL_003d: ldloc.0 + IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__40_0' + IL_0043: dup + IL_0044: brtrue.s IL_005d + + IL_0046: pop + IL_0047: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_004c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__40_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/'<>c'::'<>9__40_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) + IL_0067: callvirt instance void [mscorlib]System.Globalization.CultureInfo::set_NumberFormat(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_006c: nop + IL_006d: callvirt instance void [mscorlib]System.Threading.Thread::set_CurrentCulture(class [mscorlib]System.Globalization.CultureInfo) + IL_0072: nop + IL_0073: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::TestCall(int32, + class [mscorlib]System.Threading.Thread) + IL_0078: nop + IL_0079: ret + } // end of method InitializerTests::Bug270_NestedInitialisers + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { From e48dfb7cb29f83fd0371b7d6871086135f2d9a5d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 18 Oct 2017 09:22:17 +0200 Subject: [PATCH 41/84] Add ILStackWasEmpty flag to default.value --- .../ICSharpCode.Decompiler.csproj | 1 + ICSharpCode.Decompiler/IL/ILReader.cs | 4 ++- .../IL/Instructions/DefaultValue.cs | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index a1e17edfd..c07e50946 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -273,6 +273,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 866fe7afd..3e84e95bb 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -1010,7 +1010,9 @@ namespace ICSharpCode.Decompiler.IL ILInstruction InitObj(ILInstruction target, IType type) { - return new StObj(target, new DefaultValue(type), type); + var value = new DefaultValue(type); + value.ILStackWasEmpty = currentStack.IsEmpty; + return new StObj(target, value, type); } private ILInstruction DecodeConstrainedCall() diff --git a/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs b/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs new file mode 100644 index 000000000..b8ecea156 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2017 Siegfried Pammer +// +// 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 System; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.Decompiler.IL +{ + partial class DefaultValue + { + /// + /// Gets whether the IL stack was empty at the point of this instruction. + /// (not counting the argument of the instruction itself) + /// + public bool ILStackWasEmpty; + } +} From 08dcead162917d086f9d865852b9e1c7c383c108 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 18 Oct 2017 09:23:22 +0200 Subject: [PATCH 42/84] Fix false positive in struct initializers with default.value init --- .../TestCases/Pretty/InitializerTests.cs | 14 ++++++++------ .../TransformCollectionAndObjectInitializers.cs | 7 +++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index 63439bcb7..9a3b12ff4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -338,7 +338,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty InitializerTests.X(InitializerTests.Y(), new Data { MoreData = { a = MyEnum.a, - [2] = (Data)null + [2] = null } }); } @@ -348,11 +348,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty InitializerTests.X(InitializerTests.Y(), new Data { MoreData = { a = MyEnum.a, - [GetInt()] = { + [InitializerTests.GetInt()] = { a = MyEnum.b, - FieldList = { MyEnum2.c }, - [GetInt(), GetString()] = new Data(), - [2] = (Data)null + FieldList = { + MyEnum2.c + }, + [InitializerTests.GetInt(), InitializerTests.GetString()] = new Data(), + [2] = null } } }); @@ -397,7 +399,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void NotAStructInitializer_DefaultConstructor() { - StructData structData = new StructData(); + StructData structData = default(StructData); structData.Field = 1; structData.Property = 2; InitializerTests.X(InitializerTests.Y(), structData); diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs index d927bb61f..7813a84fd 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs @@ -66,6 +66,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms instType = newObjInst.Method.DeclaringType; break; case DefaultValue defaultVal: + if (defaultVal.ILStackWasEmpty && v.Kind == VariableKind.Local && !context.Function.Method.IsConstructor) { + // on statement level (no other expressions on IL stack), + // prefer to keep local variables (but not stack slots), + // unless we are in a constructor (where inlining object initializers might be critical + // for the base ctor call) + return false; + } instType = defaultVal.Type; break; case Block existingInitializer: From 461e59bd3f983563f04321baba5ca1957bc59319 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 18 Oct 2017 10:40:20 +0200 Subject: [PATCH 43/84] Clean up and documentation --- ...ransformCollectionAndObjectInitializers.cs | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs index 7813a84fd..12f9db004 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs @@ -46,7 +46,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms ILInstruction inst = body.Instructions[pos]; // Match stloc(v, newobj) if (inst.MatchStLoc(out var v, out var initInst) && (v.Kind == VariableKind.Local || v.Kind == VariableKind.StackSlot)) { - Block initializerBlock = null; IType instType; switch (initInst) { case NewObj newObjInst: @@ -75,22 +74,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms } instType = defaultVal.Type; break; - case Block existingInitializer: - if (existingInitializer.Type == BlockType.CollectionInitializer || existingInitializer.Type == BlockType.ObjectInitializer) { - initializerBlock = existingInitializer; - var value = ((StLoc)initializerBlock.Instructions[0]).Value; - if (value is NewObj no) - instType = no.Method.DeclaringType; - else - instType = ((DefaultValue)value).Type; - break; - } - return false; default: return false; } int initializerItemsCount = 0; - var blockType = initializerBlock?.Type ?? BlockType.CollectionInitializer; + var blockType = BlockType.CollectionInitializer; possibleIndexVariables = new Dictionary(); currentPath = new List(); isCollection = false; @@ -104,24 +92,28 @@ namespace ICSharpCode.Decompiler.IL.Transforms && IsPartOfInitializer(body.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockType)) { initializerItemsCount++; } + // Do not convert the statements into an initializer if there's an incompatible usage of the initializer variable + // directly after the possible initializer. if (IsMethodCallOnVariable(body.Instructions[pos + initializerItemsCount + 1], v)) return false; + // Calculate the correct number of statements inside the initializer: + // All index variables that were used in the initializer have Index set to -1. + // We fetch the first unused variable from the list and remove all instructions after its + // first usage (i.e. the init store) from the initializer. var index = possibleIndexVariables.Where(info => info.Value.Index > -1).Min(info => (int?)info.Value.Index); if (index != null) { initializerItemsCount = index.Value - pos - 1; } + // The initializer would be empty, there's nothing to do here. if (initializerItemsCount <= 0) return false; context.Step("CollectionOrObjectInitializer", inst); - ILVariable finalSlot; - if (initializerBlock == null) { - initializerBlock = new Block(blockType); - finalSlot = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type); - initializerBlock.FinalInstruction = new LdLoc(finalSlot); - initializerBlock.Instructions.Add(new StLoc(finalSlot, initInst.Clone())); - } else { - finalSlot = ((LdLoc)initializerBlock.FinalInstruction).Variable; - } + // Create a new block and final slot (initializer target variable) + var initializerBlock = new Block(blockType); + ILVariable finalSlot = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type); + initializerBlock.FinalInstruction = new LdLoc(finalSlot); + initializerBlock.Instructions.Add(new StLoc(finalSlot, initInst.Clone())); + // Move all instructions to the initializer block. for (int i = 1; i <= initializerItemsCount; i++) { switch (body.Instructions[i + pos]) { case CallInstruction call: @@ -171,6 +163,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms bool IsPartOfInitializer(InstructionCollection instructions, int pos, ILVariable target, IType rootType, ref BlockType blockType) { + // Include any stores to local variables that are single-assigned and do not reference the initializer-variable + // in the list of possible index variables. + // Index variables are used to implement dictionary initializers. if (instructions[pos] is StLoc stloc && stloc.Variable.Kind == VariableKind.Local && stloc.Variable.IsSingleDefinition) { if (stloc.Value.Descendants.OfType().Any(ld => ld.Variable == target && (ld is LdLoc || ld is LdLoca))) return false; @@ -241,7 +236,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms public override string ToString() => $"[{Member}, {Indices}]"; - public static (AccessPathKind Kind, List Path, List Values, ILVariable Target) GetAccessPath(ILInstruction instruction, IType rootType, Dictionary possibleIndexVariables = null) + public static (AccessPathKind Kind, List Path, List Values, ILVariable Target) GetAccessPath( + ILInstruction instruction, IType rootType, Dictionary possibleIndexVariables = null) { List path = new List(); ILVariable target = null; @@ -261,6 +257,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms var isGetter = property?.Getter == method; var indices = call.Arguments.Skip(1).Take(call.Arguments.Count - (isGetter ? 1 : 2)).ToArray(); if (possibleIndexVariables != null) { + // Mark all index variables as used foreach (var index in indices.OfType()) { if (possibleIndexVariables.TryGetValue(index.Variable, out var info)) possibleIndexVariables[index.Variable] = (-1, info.Value); From bec2f9da2b3bd0ab23d438a5e39e77d6fd5fae3a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 18 Oct 2017 10:50:46 +0200 Subject: [PATCH 44/84] Add event test case. --- .../TestCases/Pretty/InitializerTests.cs | 12 ++ .../TestCases/Pretty/InitializerTests.il | 166 ++++++++++++++++-- .../TestCases/Pretty/InitializerTests.opt.il | 148 ++++++++++++++-- .../Pretty/InitializerTests.opt.roslyn.il | 132 +++++++++++++- .../Pretty/InitializerTests.roslyn.il | 137 ++++++++++++++- 5 files changed, 543 insertions(+), 52 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs index 9a3b12ff4..e272fcd9c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -98,6 +99,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty set { } } + + public event EventHandler TestEvent; } private struct StructData @@ -266,6 +269,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty InitializerTests.X(InitializerTests.Y(), data); } + public static void NotAnObjectInitializerWithEvent() + { + Data data = new Data(); + data.TestEvent += delegate(object sender, EventArgs e) { + Console.WriteLine(); + }; + InitializerTests.X(InitializerTests.Y(), data); + } + public static void ObjectInitializerAssignCollectionToField() { InitializerTests.X(InitializerTests.Y(), new Data { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il index 3e9c08183..04af92cf4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.il @@ -15,25 +15,25 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly xws4p1nr +.assembly n0iwoj0v { + .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. - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 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 xws4p1nr.dll -// MVID: {D353AAAB-C54F-4C62-88DC-E9FF995570BA} +.module n0iwoj0v.dll +// MVID: {04AC1961-FA71-4E8B-A77B-45FF217A617C} .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 -// Image base: 0x002F0000 +// Image base: 0x009A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -102,6 +102,7 @@ { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private class [mscorlib]System.EventHandler TestEvent .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' @@ -311,6 +312,86 @@ IL_0001: ret } // end of method Data::set_Item + .method public hidebysig specialname + instance void add_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 48 (0x30) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2, + bool V_3) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: ceq + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: stloc.3 + IL_002c: ldloc.3 + IL_002d: brtrue.s IL_0007 + + IL_002f: ret + } // end of method Data::add_TestEvent + + .method public hidebysig specialname + instance void remove_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 48 (0x30) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2, + bool V_3) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: ceq + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: stloc.3 + IL_002c: ldloc.3 + IL_002d: brtrue.s IL_0007 + + IL_002f: ret + } // end of method Data::remove_TestEvent + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -325,6 +406,11 @@ IL_0012: ret } // end of method Data::.ctor + .event [mscorlib]System.EventHandler TestEvent + { + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::remove_TestEvent(class [mscorlib]System.EventHandler) + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + } // end of event Data::TestEvent .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a() { @@ -334,33 +420,33 @@ .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) } // end of property Data::b .property instance class [mscorlib]System.Collections.Generic.List`1 PropertyList() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) } // end of property Data::PropertyList .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data MoreData() { - .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() } // end of property Data::MoreData .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData NestedStruct() { - .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() } // end of property Data::NestedStruct .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data Item(int32) { - .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) } // end of property Data::Item .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data Item(int32, @@ -459,8 +545,8 @@ .property instance int32 Property() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) } // end of property StructData::Property .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data MoreData() @@ -470,7 +556,9 @@ } // end of property StructData::MoreData } // end of class StructData - .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1a' + .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate8' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1c' .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 @@ -867,6 +955,37 @@ IL_001b: ret } // end of method InitializerTests::NotAnObjectInitializer + .method public hidebysig static void NotAnObjectInitializerWithEvent() cil managed + { + // Code size 58 (0x3a) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_000d: brtrue.s IL_0022 + + IL_000f: ldnull + IL_0010: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__7'(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::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0020: br.s IL_0022 + + IL_0022: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + IL_002c: nop + IL_002d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0032: ldloc.0 + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0038: nop + IL_0039: ret + } // end of method InitializerTests::NotAnObjectInitializerWithEvent + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed { // Code size 57 (0x39) @@ -1329,17 +1448,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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0042: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' IL_0047: brtrue.s IL_005c IL_0049: ldnull - IL_004a: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__19'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_004a: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__1b'(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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0055: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' IL_005a: br.s IL_005c - IL_005c: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_005c: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' 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) @@ -1365,7 +1484,18 @@ IL_0006: ret } // end of method InitializerTests::.ctor - .method private hidebysig static bool 'b__19'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + .method private hidebysig static void 'b__7'(object sender, + class [mscorlib]System.EventArgs e) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: call void [mscorlib]System.Console::WriteLine() + IL_0005: nop + IL_0006: ret + } // end of method InitializerTests::'b__7' + + .method private hidebysig static bool 'b__1b'(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) @@ -1381,7 +1511,7 @@ IL_0013: ldloc.0 IL_0014: ret - } // end of method InitializerTests::'b__19' + } // end of method InitializerTests::'b__1b' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il index f7dcef8e8..bf86fbc0c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.il @@ -15,25 +15,25 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '3csuofts' +.assembly mo2wq1js { + .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. - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 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 '3csuofts.dll' -// MVID: {F78A061E-BAE5-4B9C-AFCF-4B60D826C849} +.module mo2wq1js.dll +// MVID: {99F5978B-D68E-4578-9D8F-7D47C1F63A30} .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 -// Image base: 0x00D80000 +// Image base: 0x027A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -101,6 +101,7 @@ { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. .field public class [mscorlib]System.Collections.Generic.List`1 FieldList + .field private class [mscorlib]System.EventHandler TestEvent .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum 'k__BackingField' @@ -271,6 +272,74 @@ IL_0000: ret } // end of method Data::set_Item + .method public hidebysig specialname + instance void add_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::add_TestEvent + + .method public hidebysig specialname + instance void remove_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::remove_TestEvent + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -284,6 +353,11 @@ IL_0011: ret } // end of method Data::.ctor + .event [mscorlib]System.EventHandler TestEvent + { + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::remove_TestEvent(class [mscorlib]System.EventHandler) + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + } // end of event Data::TestEvent .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a() { @@ -293,33 +367,33 @@ .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum b() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_b() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_b(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum) } // end of property Data::b .property instance class [mscorlib]System.Collections.Generic.List`1 PropertyList() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) .get instance class [mscorlib]System.Collections.Generic.List`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_PropertyList() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_PropertyList(class [mscorlib]System.Collections.Generic.List`1) } // end of property Data::PropertyList .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data MoreData() { - .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_MoreData(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_MoreData() } // end of property Data::MoreData .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData NestedStruct() { - .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_NestedStruct(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData) + .get instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_NestedStruct() } // end of property Data::NestedStruct .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data Item(int32) { - .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::set_Item(int32, class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data) + .get instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::get_Item(int32) } // end of property Data::Item .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data Item(int32, @@ -406,8 +480,8 @@ .property instance int32 Property() { - .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::get_Property() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData::set_Property(int32) } // end of property StructData::Property .property instance class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data MoreData() @@ -417,7 +491,9 @@ } // end of property StructData::MoreData } // end of class StructData - .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1a' + .field private static class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate8' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate1c' .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 @@ -730,6 +806,32 @@ IL_0018: ret } // end of method InitializerTests::NotAnObjectInitializer + .method public hidebysig static void NotAnObjectInitializerWithEvent() cil managed + { + // Code size 53 (0x35) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_000c: brtrue.s IL_001f + + IL_000e: ldnull + IL_000f: ldftn void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__7'(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::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_001f: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate8' + IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + IL_0029: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_002e: ldloc.0 + IL_002f: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0034: ret + } // end of method InitializerTests::NotAnObjectInitializerWithEvent + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed { // Code size 52 (0x34) @@ -1116,15 +1218,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::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' IL_0043: brtrue.s IL_0056 IL_0045: ldnull - IL_0046: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__19'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0046: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'b__1b'(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::'CS$<>9__CachedAnonymousMethodDelegate1a' - IL_0056: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1a' + IL_0051: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' + IL_0056: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::'CS$<>9__CachedAnonymousMethodDelegate1c' 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) @@ -1147,7 +1249,17 @@ IL_0006: ret } // end of method InitializerTests::.ctor - .method private hidebysig static bool 'b__19'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + .method private hidebysig static void 'b__7'(object sender, + class [mscorlib]System.EventArgs e) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 6 (0x6) + .maxstack 8 + IL_0000: call void [mscorlib]System.Console::WriteLine() + IL_0005: ret + } // end of method InitializerTests::'b__7' + + .method private hidebysig static bool 'b__1b'(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) @@ -1158,7 +1270,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method InitializerTests::'b__19' + } // end of method InitializerTests::'b__1b' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il index 0f0385cd5..22e3c0319 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.opt.roslyn.il @@ -30,14 +30,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {4B0BA9B1-521C-4C45-A2B8-8774D5BE797E} +// MVID: {1A200C9E-AB38-4402-A1D6-E7C3307A45E2} .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 -// Image base: 0x01500000 +// Image base: 0x02C80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -115,6 +115,8 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [mscorlib]System.EventHandler TestEvent + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method public hidebysig specialname instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum get_a() cil managed @@ -275,6 +277,76 @@ IL_0000: ret } // end of method Data::set_Item + .method public hidebysig specialname + instance void add_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::add_TestEvent + + .method public hidebysig specialname + instance void remove_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::remove_TestEvent + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -288,6 +360,11 @@ IL_0011: ret } // end of method Data::.ctor + .event [mscorlib]System.EventHandler TestEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::remove_TestEvent(class [mscorlib]System.EventHandler) + } // end of event Data::TestEvent .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a() { @@ -426,7 +503,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/'<>c' '<>9' - .field public static class [mscorlib]System.Func`2 '<>9__40_0' + .field public static class [mscorlib]System.EventHandler '<>9__23_0' + .field public static class [mscorlib]System.Func`2 '<>9__41_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -447,8 +525,18 @@ IL_0006: ret } // end of method '<>c'::.ctor + .method assembly hidebysig instance void + 'b__23_0'(object sender, + class [mscorlib]System.EventArgs e) cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: call void [mscorlib]System.Console::WriteLine() + IL_0005: ret + } // end of method '<>c'::'b__23_0' + .method assembly hidebysig instance bool - 'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + 'b__41_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { // Code size 17 (0x11) .maxstack 8 @@ -458,7 +546,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method '<>c'::'b__40_0' + } // end of method '<>c'::'b__41_0' } // end of class '<>c' @@ -737,6 +825,34 @@ IL_0018: ret } // end of method InitializerTests::NotAnObjectInitializer + .method public hidebysig static void NotAnObjectInitializerWithEvent() cil managed + { + // Code size 55 (0x37) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__23_0' + IL_000c: dup + IL_000d: brtrue.s IL_0026 + + IL_000f: pop + IL_0010: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_0015: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__23_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/'<>c'::'<>9__23_0' + IL_0026: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + IL_002b: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0030: ldloc.0 + IL_0031: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0036: ret + } // end of method InitializerTests::NotAnObjectInitializerWithEvent + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed { // Code size 48 (0x30) @@ -1159,17 +1275,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/'<>c'::'<>9__40_0' + IL_003a: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__41_0' IL_003f: dup IL_0040: brtrue.s IL_0059 IL_0042: pop IL_0043: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' - IL_0048: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_0048: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__41_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/'<>c'::'<>9__40_0' + IL_0054: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__41_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) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il index d25f8725e..69b897be6 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.roslyn.il @@ -30,14 +30,14 @@ .ver 0:0:0:0 } .module InitializerTests.dll -// MVID: {EA222E3F-8F60-413B-AF03-0814FF05742B} +// MVID: {764AEFFE-E491-413B-876B-B40EBE774D84} .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 -// Image base: 0x00C80000 +// Image base: 0x00FC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -122,6 +122,9 @@ .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/StructData 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private class [mscorlib]System.EventHandler TestEvent + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .method public hidebysig specialname instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum get_a() cil managed @@ -296,6 +299,76 @@ IL_0001: ret } // end of method Data::set_Item + .method public hidebysig specialname + instance void add_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::add_TestEvent + + .method public hidebysig specialname + instance void remove_TestEvent(class [mscorlib]System.EventHandler 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 3 + .locals init (class [mscorlib]System.EventHandler V_0, + class [mscorlib]System.EventHandler V_1, + class [mscorlib]System.EventHandler V_2) + IL_0000: ldarg.0 + IL_0001: ldfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: ldarg.1 + IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, + class [mscorlib]System.Delegate) + IL_0010: castclass [mscorlib]System.EventHandler + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldflda class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::TestEvent + IL_001c: ldloc.2 + IL_001d: ldloc.1 + IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, + !!0, + !!0) + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: ldloc.1 + IL_0026: bne.un.s IL_0007 + + IL_0028: ret + } // end of method Data::remove_TestEvent + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -310,6 +383,11 @@ IL_0012: ret } // end of method Data::.ctor + .event [mscorlib]System.EventHandler TestEvent + { + .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::remove_TestEvent(class [mscorlib]System.EventHandler) + } // end of event Data::TestEvent .property instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/MyEnum a() { @@ -452,7 +530,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/'<>c' '<>9' - .field public static class [mscorlib]System.Func`2 '<>9__40_0' + .field public static class [mscorlib]System.EventHandler '<>9__23_0' + .field public static class [mscorlib]System.Func`2 '<>9__41_0' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -474,8 +553,19 @@ IL_0007: ret } // end of method '<>c'::.ctor + .method assembly hidebysig instance void + 'b__23_0'(object sender, + class [mscorlib]System.EventArgs e) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: call void [mscorlib]System.Console::WriteLine() + IL_0005: nop + IL_0006: ret + } // end of method '<>c'::'b__23_0' + .method assembly hidebysig instance bool - 'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed + 'b__41_0'(class [mscorlib]System.Globalization.NumberFormatInfo format) cil managed { // Code size 17 (0x11) .maxstack 8 @@ -485,7 +575,7 @@ IL_000b: call bool [mscorlib]System.String::op_Equality(string, string) IL_0010: ret - } // end of method '<>c'::'b__40_0' + } // end of method '<>c'::'b__41_0' } // end of class '<>c' @@ -863,6 +953,37 @@ IL_001b: ret } // end of method InitializerTests::NotAnObjectInitializer + .method public hidebysig static void NotAnObjectInitializerWithEvent() cil managed + { + // Code size 58 (0x3a) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldsfld class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__23_0' + IL_000d: dup + IL_000e: brtrue.s IL_0027 + + IL_0010: pop + IL_0011: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' + IL_0016: ldftn instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__23_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/'<>c'::'<>9__23_0' + IL_0027: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/Data::add_TestEvent(class [mscorlib]System.EventHandler) + IL_002c: nop + IL_002d: call object ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::Y() + IL_0032: ldloc.0 + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests::X(object, + object) + IL_0038: nop + IL_0039: ret + } // end of method InitializerTests::NotAnObjectInitializerWithEvent + .method public hidebysig static void ObjectInitializerAssignCollectionToField() cil managed { // Code size 53 (0x35) @@ -1369,17 +1490,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/'<>c'::'<>9__40_0' + IL_003e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__41_0' IL_0043: dup IL_0044: brtrue.s IL_005d IL_0046: pop IL_0047: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9' - IL_004c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__40_0'(class [mscorlib]System.Globalization.NumberFormatInfo) + IL_004c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'b__41_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/'<>c'::'<>9__40_0' + IL_0058: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests/'<>c'::'<>9__41_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) From 7e9f60533b8aee19cdab94975264e5d3247e1f8f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 18 Oct 2017 23:56:59 +0200 Subject: [PATCH 45/84] Use proposedNameForStoresFromNewObj only in case of stack slots. --- ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index eea8dedae..1cbf92cee 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -196,7 +196,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms proposedName = proposedNameForLoads[0]; } } - if (string.IsNullOrEmpty(proposedName)) { + if (string.IsNullOrEmpty(proposedName) && variable.Kind == VariableKind.StackSlot) { var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType() .Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context))) .Except(currentFieldNames).ToList(); From 818a90af95f2f55c114fa87f726877959f7bec4e Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 19 Oct 2017 09:07:07 +0200 Subject: [PATCH 46/84] #918: CallBuilder: Add fix-up logic for lambda expressions with anonymous parameter types to ensure the correct overload is called after removing the 'implicit' call to 'new Nullable(T value)'. --- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 38 ++++++++++++++++++- .../CSharp/Resolver/LambdaResolveResult.cs | 2 +- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index 6fb6bc9f7..525758a73 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -143,10 +143,16 @@ namespace ICSharpCode.Decompiler.CSharp .WithILInstruction(inst) .WithRR(rr); } else { + if (IsUnambiguousCall(inst, target, method, Array.Empty(), arguments) != OverloadResolutionErrors.None) { for (int i = 0; i < arguments.Count; i++) { - if (!settings.AnonymousTypes || !expectedParameters[i].Type.ContainsAnonymousType()) + if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType()) { + if (arguments[i].Expression is LambdaExpression lambda) { + ModifyReturnTypeOfLambda(lambda); + } + } else { arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder); + } } } return new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), arguments.SelectArray(arg => arg.Expression)) @@ -180,8 +186,13 @@ namespace ICSharpCode.Decompiler.CSharp if (!argumentsCasted) { argumentsCasted = true; for (int i = 0; i < arguments.Count; i++) { - if (!settings.AnonymousTypes || !expectedParameters[i].Type.ContainsAnonymousType()) + if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType()) { + if (arguments[i].Expression is LambdaExpression lambda) { + ModifyReturnTypeOfLambda(lambda); + } + } else { arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder); + } } } else if (!targetCasted) { targetCasted = true; @@ -213,6 +224,29 @@ namespace ICSharpCode.Decompiler.CSharp } } + private void ModifyReturnTypeOfLambda(LambdaExpression lambda) + { + var resolveResult = (DecompiledLambdaResolveResult)lambda.GetResolveResult(); + if (lambda.Body is Expression exprBody) + lambda.Body = new TranslatedExpression(exprBody.Detach()).ConvertTo(resolveResult.ReturnType, expressionBuilder); + else + ModifyReturnStatementInsideLambda(resolveResult.ReturnType, lambda); + resolveResult.InferredReturnType = resolveResult.ReturnType; + } + + private void ModifyReturnStatementInsideLambda(IType returnType, AstNode parent) + { + foreach (var child in parent.Children) { + if (child is LambdaExpression || child is AnonymousMethodExpression) + continue; + if (child is ReturnStatement ret) { + ret.Expression = new TranslatedExpression(ret.Expression.Detach()).ConvertTo(returnType, expressionBuilder); + continue; + } + ModifyReturnStatementInsideLambda(returnType, child); + } + } + private bool IsDelegateEqualityComparison(IMethod method, IList arguments) { // Comparison on a delegate type is a C# builtin operator diff --git a/ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs b/ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs index e699e15d6..eb6e33475 100644 --- a/ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs +++ b/ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs @@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver /// Can differ from ReturnType if a return statement /// performs an implicit conversion. /// - public readonly IType InferredReturnType; + public IType InferredReturnType; public DecompiledLambdaResolveResult(IL.ILFunction function, IType delegateType, From d783fc68efbe49e5dbba708ca55ddb5fd2eb261a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 19 Oct 2017 09:10:10 +0200 Subject: [PATCH 47/84] Fix #918: Conversion of bool literals to bool? not pretty --- .../CSharp/ExpressionBuilder.cs | 11 +++++-- .../CSharp/TranslatedExpression.cs | 30 ++++++++++++------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 7b8d4ef91..6a0a7d2f3 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -325,8 +325,15 @@ namespace ICSharpCode.Decompiler.CSharp internal ExpressionWithResolveResult GetDefaultValueExpression(IType type) { - var expr = type.IsReferenceType == true ? (Expression)new NullReferenceExpression() : new DefaultValueExpression(ConvertType(type)); - var constantType = type.IsReferenceType == true ? SpecialType.NullType : type; + Expression expr; + IType constantType; + if (type.IsReferenceType == true || type.IsKnownType(KnownTypeCode.NullableOfT)) { + expr = new NullReferenceExpression(); + constantType = SpecialType.NullType; + } else { + expr = new DefaultValueExpression(ConvertType(type)); + constantType = type; + } return expr.WithRR(new ConstantResolveResult(constantType, null)); } diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index 3c1c86d84..34075fa46 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -173,16 +173,26 @@ namespace ICSharpCode.Decompiler.CSharp var type = this.Type; if (type.Equals(targetType)) { // Make explicit conversion implicit, if possible - if (allowImplicitConversion && ResolveResult is ConversionResolveResult conversion) { - if (Expression is CastExpression cast - && (type.IsKnownType(KnownTypeCode.Object) && conversion.Conversion.IsBoxingConversion - || type.Kind == TypeKind.Delegate && conversion.Conversion.IsAnonymousFunctionConversion - )) { - return this.UnwrapChild(cast.Expression); - } else if (Expression is ObjectCreateExpression oce && conversion.Conversion.IsMethodGroupConversion - && oce.Arguments.Count == 1 && expressionBuilder.settings.UseImplicitMethodGroupConversion) - { - return this.UnwrapChild(oce.Arguments.Single()); + if (allowImplicitConversion) { + switch (ResolveResult) { + case ConversionResolveResult conversion: { + if (Expression is CastExpression cast + && (type.IsKnownType(KnownTypeCode.Object) && conversion.Conversion.IsBoxingConversion + || type.Kind == TypeKind.Delegate && conversion.Conversion.IsAnonymousFunctionConversion + )) { + return this.UnwrapChild(cast.Expression); + } else if (Expression is ObjectCreateExpression oce && conversion.Conversion.IsMethodGroupConversion + && oce.Arguments.Count == 1 && expressionBuilder.settings.UseImplicitMethodGroupConversion) { + return this.UnwrapChild(oce.Arguments.Single()); + } + break; + } + case InvocationResolveResult invocation: { + if (Expression is ObjectCreateExpression oce && oce.Arguments.Count == 1 && invocation.Type.IsKnownType(KnownTypeCode.NullableOfT)) { + return this.UnwrapChild(oce.Arguments.Single()); + } + break; + } } } return this; From 9630acd8b7e3705f50467fdf6497da4a8e3208e7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 19 Oct 2017 09:13:21 +0200 Subject: [PATCH 48/84] SwitchOnNullableTransform: Fix another special case produced by the Roslyn compiler. --- .../TestCases/Pretty/Switch.cs | 26 +++--- .../TestCases/Pretty/Switch.il | 80 +++++++++++++++---- .../TestCases/Pretty/Switch.opt.il | 72 +++++++++++++---- .../TestCases/Pretty/Switch.opt.roslyn.il | 45 ++++++++++- .../TestCases/Pretty/Switch.roslyn.il | 54 ++++++++++++- .../Transforms/SwitchOnNullableTransform.cs | 41 +++++++--- 6 files changed, 258 insertions(+), 60 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs index 4f19a857f..0b118981a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs @@ -60,19 +60,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty } } - //public static bool? SwitchOverNullableEnum(State? state) - //{ - // switch (state) { - // case State.False: - // return false; - // case State.True: - // return true; - // case State.Null: - // return null; - // default: - // throw new InvalidOperationException(); - // } - //} + public static bool? SwitchOverNullableEnum(State? state) + { + switch (state) { + case State.False: + return false; + case State.True: + return true; + case State.Null: + return null; + default: + throw new InvalidOperationException(); + } + } public static string SparseIntegerSwitch(int i) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il index 581dfad62..9db363234 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly mhfw1ujx +.assembly o03zflju { .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. @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module mhfw1ujx.dll -// MVID: {2E35825E-3352-4C5E-B230-3B3F7055B304} +.module o03zflju.dll +// MVID: {0EF64C57-A49E-4138-9C3F-BDAB86B2E450} .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 -// Image base: 0x005A0000 +// Image base: 0x01330000 // =============== CLASS MEMBERS DECLARATION =================== @@ -142,6 +142,52 @@ IL_0034: ret } // end of method Switch::SwitchOverNullableBool + .method public hidebysig static valuetype [mscorlib]System.Nullable`1 + SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1 state) cil managed + { + // Code size 75 (0x4b) + .maxstack 2 + .locals init (valuetype [mscorlib]System.Nullable`1 V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_1, + valuetype [mscorlib]System.Nullable`1 V_2) + IL_0000: nop + IL_0001: ldarga.s state + IL_0003: dup + IL_0004: call instance !0 valuetype [mscorlib]System.Nullable`1::GetValueOrDefault() + IL_0009: stloc.1 + IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1::get_HasValue() + IL_000f: brfalse.s IL_0043 + + IL_0011: ldloc.1 + IL_0012: switch ( + IL_0025, + IL_002e, + IL_0037) + IL_0023: br.s IL_0043 + + IL_0025: ldc.i4.0 + IL_0026: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_002b: stloc.0 + IL_002c: br.s IL_0049 + + IL_002e: ldc.i4.1 + IL_002f: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_0034: stloc.0 + IL_0035: br.s IL_0049 + + IL_0037: ldloca.s V_2 + IL_0039: initobj valuetype [mscorlib]System.Nullable`1 + IL_003f: ldloc.2 + IL_0040: stloc.0 + IL_0041: br.s IL_0049 + + IL_0043: newobj instance void [mscorlib]System.InvalidOperationException::.ctor() + IL_0048: throw + + IL_0049: ldloc.0 + IL_004a: ret + } // end of method Switch::SwitchOverNullableEnum + .method public hidebysig static string SparseIntegerSwitch(int32 i) cil managed { @@ -834,7 +880,7 @@ IL_0015: brfalse IL_00e9 IL_001a: volatile. - IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1' + IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1' IL_0021: brtrue.s IL_0084 IL_0023: ldc.i4.7 @@ -875,9 +921,9 @@ IL_0078: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_007d: volatile. - IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1' + IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1' IL_0084: volatile. - IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1' + IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1' IL_008b: ldloc.1 IL_008c: ldloca.s V_2 IL_008e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -949,7 +995,7 @@ IL_0013: brfalse IL_0158 IL_0018: volatile. - IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1' + IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1' IL_001f: brtrue IL_00b8 IL_0024: ldc.i4.s 11 @@ -1010,9 +1056,9 @@ IL_00ac: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_00b1: volatile. - IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1' + IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1' IL_00b8: volatile. - IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1' + IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1' IL_00bf: ldloc.1 IL_00c0: ldloca.s V_2 IL_00c2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -1297,7 +1343,7 @@ IL_0030: brfalse IL_0121 IL_0035: volatile. - IL_0037: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1' + IL_0037: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1' IL_003c: brtrue.s IL_0093 IL_003e: ldc.i4.6 @@ -1333,9 +1379,9 @@ IL_0087: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_008c: volatile. - IL_008e: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1' + IL_008e: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1' IL_0093: volatile. - IL_0095: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1' + IL_0095: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1' IL_009a: ldloc.s V_5 IL_009c: ldloca.s V_6 IL_009e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -1562,14 +1608,14 @@ } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch -.class private auto ansi '{2E35825E-3352-4C5E-B230-3B3F7055B304}' +.class private auto ansi '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000c-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000d-1' - .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x6000012-1' -} // end of class '{2E35825E-3352-4C5E-B230-3B3F7055B304}' + .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000e-1' + .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x6000013-1' +} // end of class '{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}' // ============================================================= diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il index 0dbe1fff9..c4fc03c00 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly okac2jza +.assembly pryqrprl { .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. @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module okac2jza.dll -// MVID: {7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F} +.module pryqrprl.dll +// MVID: {FFEEBB9C-152A-467A-A4B4-51CF03878E20} .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 -// Image base: 0x01A40000 +// Image base: 0x00B70000 // =============== CLASS MEMBERS DECLARATION =================== @@ -126,6 +126,44 @@ IL_002b: throw } // end of method Switch::SwitchOverNullableBool + .method public hidebysig static valuetype [mscorlib]System.Nullable`1 + SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1 state) cil managed + { + // Code size 66 (0x42) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_0, + valuetype [mscorlib]System.Nullable`1 V_1) + IL_0000: ldarga.s state + IL_0002: dup + IL_0003: call instance !0 valuetype [mscorlib]System.Nullable`1::GetValueOrDefault() + IL_0008: stloc.0 + IL_0009: call instance bool valuetype [mscorlib]System.Nullable`1::get_HasValue() + IL_000e: brfalse.s IL_003c + + IL_0010: ldloc.0 + IL_0011: switch ( + IL_0024, + IL_002b, + IL_0032) + IL_0022: br.s IL_003c + + IL_0024: ldc.i4.0 + IL_0025: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_002a: ret + + IL_002b: ldc.i4.1 + IL_002c: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_0031: ret + + IL_0032: ldloca.s V_1 + IL_0034: initobj valuetype [mscorlib]System.Nullable`1 + IL_003a: ldloc.1 + IL_003b: ret + + IL_003c: newobj instance void [mscorlib]System.InvalidOperationException::.ctor() + IL_0041: throw + } // end of method Switch::SwitchOverNullableEnum + .method public hidebysig static string SparseIntegerSwitch(int32 i) cil managed { @@ -711,7 +749,7 @@ IL_0013: brfalse IL_00db IL_0018: volatile. - IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1' + IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1' IL_001f: brtrue.s IL_0082 IL_0021: ldc.i4.7 @@ -752,9 +790,9 @@ IL_0076: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_007b: volatile. - IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1' + IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1' IL_0082: volatile. - IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1' + IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1' IL_0089: ldloc.0 IL_008a: ldloca.s V_1 IL_008c: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -812,7 +850,7 @@ IL_0011: brfalse IL_013d IL_0016: volatile. - IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1' + IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1' IL_001d: brtrue IL_00b6 IL_0022: ldc.i4.s 11 @@ -873,9 +911,9 @@ IL_00aa: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_00af: volatile. - IL_00b1: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1' + IL_00b1: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1' IL_00b6: volatile. - IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1' + IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1' IL_00bd: ldloc.0 IL_00be: ldloca.s V_1 IL_00c0: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -1099,7 +1137,7 @@ IL_002d: brfalse IL_0115 IL_0032: volatile. - IL_0034: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1' + IL_0034: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1' IL_0039: brtrue.s IL_0090 IL_003b: ldc.i4.6 @@ -1135,9 +1173,9 @@ IL_0084: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2::Add(!0, !1) IL_0089: volatile. - IL_008b: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1' + IL_008b: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1' IL_0090: volatile. - IL_0092: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1' + IL_0092: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2 '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1' IL_0097: ldloc.s V_5 IL_0099: ldloca.s V_6 IL_009b: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, @@ -1331,14 +1369,14 @@ } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch -.class private auto ansi '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}' +.class private auto ansi '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000c-1' .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000d-1' - .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x6000012-1' -} // end of class '{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}' + .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x600000e-1' + .field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2 '$$method0x6000013-1' +} // end of class '{FFEEBB9C-152A-467A-A4B4-51CF03878E20}' // ============================================================= diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il index 359906595..c2c1f5cae 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Switch.dll -// MVID: {6F3B5958-B8BE-48C6-82B8-5D3026DEACD1} +// MVID: {5D628BA5-FC59-43EC-A162-63729510F134} .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 -// Image base: 0x03160000 +// Image base: 0x01390000 // =============== CLASS MEMBERS DECLARATION =================== @@ -136,6 +136,47 @@ IL_0027: throw } // end of method Switch::SwitchOverNullableBool + .method public hidebysig static valuetype [mscorlib]System.Nullable`1 + SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1 state) cil managed + { + // Code size 69 (0x45) + .maxstack 1 + .locals init (valuetype [mscorlib]System.Nullable`1 V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_1, + valuetype [mscorlib]System.Nullable`1 V_2) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1::get_HasValue() + IL_0009: brfalse.s IL_003f + + IL_000b: ldloca.s V_0 + IL_000d: call instance !0 valuetype [mscorlib]System.Nullable`1::GetValueOrDefault() + IL_0012: stloc.1 + IL_0013: ldloc.1 + IL_0014: switch ( + IL_0027, + IL_002e, + IL_0035) + IL_0025: br.s IL_003f + + IL_0027: ldc.i4.0 + IL_0028: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_002d: ret + + IL_002e: ldc.i4.1 + IL_002f: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_0034: ret + + IL_0035: ldloca.s V_2 + IL_0037: initobj valuetype [mscorlib]System.Nullable`1 + IL_003d: ldloc.2 + IL_003e: ret + + IL_003f: newobj instance void [mscorlib]System.InvalidOperationException::.ctor() + IL_0044: throw + } // end of method Switch::SwitchOverNullableEnum + .method public hidebysig static string SparseIntegerSwitch(int32 i) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il index 7cce7b604..ea25c483e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il @@ -25,7 +25,7 @@ .ver 0:0:0:0 } .module Switch.dll -// MVID: {7ADDBD28-42D6-469D-B92D-065C803347D0} +// MVID: {EF7D776C-0F54-445C-8A74-2D49ADE35F46} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 @@ -152,6 +152,58 @@ IL_0034: ret } // end of method Switch::SwitchOverNullableBool + .method public hidebysig static valuetype [mscorlib]System.Nullable`1 + SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1 state) cil managed + { + // Code size 81 (0x51) + .maxstack 1 + .locals init (valuetype [mscorlib]System.Nullable`1 V_0, + valuetype [mscorlib]System.Nullable`1 V_1, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_2, + valuetype [mscorlib]System.Nullable`1 V_3, + valuetype [mscorlib]System.Nullable`1 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: stloc.0 + IL_0005: ldloca.s V_0 + IL_0007: call instance bool valuetype [mscorlib]System.Nullable`1::get_HasValue() + IL_000c: brfalse.s IL_0049 + + IL_000e: ldloca.s V_0 + IL_0010: call instance !0 valuetype [mscorlib]System.Nullable`1::GetValueOrDefault() + IL_0015: stloc.2 + IL_0016: ldloc.2 + IL_0017: switch ( + IL_002a, + IL_0033, + IL_003c) + IL_0028: br.s IL_0049 + + IL_002a: ldc.i4.0 + IL_002b: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_0030: stloc.3 + IL_0031: br.s IL_004f + + IL_0033: ldc.i4.1 + IL_0034: newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + IL_0039: stloc.3 + IL_003a: br.s IL_004f + + IL_003c: ldloca.s V_4 + IL_003e: initobj valuetype [mscorlib]System.Nullable`1 + IL_0044: ldloc.s V_4 + IL_0046: stloc.3 + IL_0047: br.s IL_004f + + IL_0049: newobj instance void [mscorlib]System.InvalidOperationException::.ctor() + IL_004e: throw + + IL_004f: ldloc.3 + IL_0050: ret + } // end of method Switch::SwitchOverNullableEnum + .method public hidebysig static string SparseIntegerSwitch(int32 i) cil managed { diff --git a/ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs index ed538ca8b..af7cc6ae7 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs @@ -142,22 +142,43 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (!condition.MatchLogicNot(out var getHasValue) || !NullableLiftingTransform.MatchHasValueCall(getHasValue, out ILVariable target1) || target1 != tmp) return false; // match second block: switchBlock + // note: I have seen cases where switchVar is inlined into the switch. // stloc switchVar(call GetValueOrDefault(ldloca tmp)) // switch (ldloc switchVar) { // case [0..1): br caseBlock1 // ... more cases ... // case [long.MinValue..0),[1..5),[6..10),[11..long.MaxValue]: br defaultBlock // } - if (switchBlock.Instructions.Count != 2 || switchBlock.IncomingEdgeCount != 1) - return false; - if (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault)) - return false; - if (!switchVar.IsSingleDefinition || switchVar.LoadCount != 1) - return false; - if (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, tmp)) - return false; - if (!(switchBlock.Instructions[1] is SwitchInstruction switchInst)) - return false; + if (switchBlock.IncomingEdgeCount != 1) + return false; + SwitchInstruction switchInst; + switch (switchBlock.Instructions.Count) { + case 2: { + // this is the normal case described by the pattern above + if (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault)) + return false; + if (!switchVar.IsSingleDefinition || switchVar.LoadCount != 1) + return false; + if (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, tmp)) + return false; + if (!(switchBlock.Instructions[1] is SwitchInstruction si)) + return false; + switchInst = si; + break; + } + case 1: { + // this is the special case where `call GetValueOrDefault(ldloca tmp)` is inlined into the switch. + if (!(switchBlock.Instructions[0] is SwitchInstruction si)) + return false; + if (!NullableLiftingTransform.MatchGetValueOrDefault(si.Value, tmp)) + return false; + switchInst = si; + break; + } + default: { + return false; + } + } newSwitch = BuildLiftedSwitch(nullCaseBlock, switchInst, switchValue); return true; } From d645166f3e81dd3d960e6c66d029d7830a9104cc Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 21 Oct 2017 00:22:07 +0200 Subject: [PATCH 49/84] * Fix #920: [Bug]Click one reference will navigate to another. * Add references to constructors of builtin types (decimal and string). --- ICSharpCode.Decompiler/Output/TextTokenWriter.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs index f0d26ef11..5ce584f1d 100644 --- a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs +++ b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs @@ -116,7 +116,7 @@ namespace ICSharpCode.Decompiler if (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression) { symbol = node.Parent.GetSymbol(); } - if (symbol != null && node.Parent is ObjectCreateExpression) { + if (symbol != null && node.Role == Roles.Type && node.Parent is ObjectCreateExpression) { symbol = node.Parent.GetSymbol(); } if (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member) { @@ -335,9 +335,15 @@ namespace ICSharpCode.Decompiler case "char": case "string": case "object": - var typeSymbol = (nodeStack.Peek().GetSymbol() as IType)?.GetDefinition(); - if (typeSymbol == null) goto default; - output.WriteReference(type, typeSystem.GetCecil(typeSymbol)); + var node = nodeStack.Peek(); + ISymbol symbol; + if (node.Role == Roles.Type && node.Parent is ObjectCreateExpression) { + symbol = node.Parent.GetSymbol(); + } else { + symbol = nodeStack.Peek().GetSymbol(); + } + if (symbol == null) goto default; + output.WriteReference(type, SymbolToCecil(symbol)); break; default: output.Write(type); From cdaa3e29c968145157a6bc299c1a520055c4ec59 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 21 Oct 2017 16:14:21 +0200 Subject: [PATCH 50/84] Fix highlighting of 'where' keyword in LINQ query clauses. --- ILSpy/Languages/CSharpHighlightingTokenWriter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs index 633ac75e6..6d91a6a11 100644 --- a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs +++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs @@ -127,9 +127,14 @@ namespace ICSharpCode.ILSpy case "global": case "dynamic": case "await": - case "where": color = structureKeywordsColor; break; + case "where": + if (nodeStack.PeekOrDefault() is QueryClause) + color = queryKeywordsColor; + else + color = structureKeywordsColor; + break; case "in": if (nodeStack.PeekOrDefault() is ForeachStatement) color = structureKeywordsColor; From 425d1ae6973859cb7eb217f1934a4e9bc601fd5c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 21 Oct 2017 16:57:50 +0200 Subject: [PATCH 51/84] Fix ArgumentOutOfRangeException in CopyPropagation while decompiling System.Security.Cryptography.CryptoStream.ReadAsyncInternal from mscorlib.v4 --- ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs index 91a79c6c4..1ef40d116 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs @@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms // dead store to stack if (copiedExpr.Flags == InstructionFlags.None) { // no-op -> delete - context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i - 1]); + context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i]); block.Instructions.RemoveAt(i--); } else { // evaluate the value for its side-effects From 79dec0145a700d452343c534c72d907703ec6578 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 22 Oct 2017 11:21:50 +0200 Subject: [PATCH 52/84] Fix #928: Null literal white space formatting issue --- .../CSharp/OutputVisitor/CSharpOutputVisitor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index 8eb432e8b..cc3708c81 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -890,6 +890,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(nullReferenceExpression); writer.WritePrimitiveValue(null); + isAfterSpace = false; EndNode(nullReferenceExpression); } From 22eb1a10ed02effeb668281b73339e2fcd97ef33 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Mon, 23 Oct 2017 06:54:10 +0200 Subject: [PATCH 53/84] Update nuspec dependencies --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec index 93cd2f8fb..ac0c969ca 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec @@ -2,7 +2,7 @@ ICSharpCode.Decompiler - 3.0.0-alpha3 + 3.0.0-beta1 ILSpy Decompiler Engine Daniel Grunwald, David Srbecky, Ed Harvey, Siegfried Pammer Daniel Grunwald, SharpDevelop @@ -15,9 +15,10 @@ Copyright 2011-2017 AlphaSierraPapa C# Decompiler ILSpy - - - + + + + From 3bf182860df0caa6919e692b3c8915eacb501e3f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 23 Oct 2017 21:00:26 +0200 Subject: [PATCH 54/84] Fix #934: Project generation: absolute path used for AssemblyInfo.cs module --- ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs b/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs index 4b36a47db..a36ae5869 100644 --- a/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs @@ -283,8 +283,8 @@ namespace ICSharpCode.Decompiler.CSharp const string prop = "Properties"; if (directories.Add(prop)) Directory.CreateDirectory(Path.Combine(targetDirectory, prop)); - string assemblyInfo = Path.Combine(targetDirectory, prop, "AssemblyInfo.cs"); - using (StreamWriter w = new StreamWriter(assemblyInfo)) { + string assemblyInfo = Path.Combine(prop, "AssemblyInfo.cs"); + using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, assemblyInfo))) { syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions)); } return new Tuple[] { Tuple.Create("Compile", assemblyInfo) }; From 106ac87b665607b1877305ab78e74cdd68bacc41 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 25 Oct 2017 17:56:41 +0200 Subject: [PATCH 55/84] Fix location of assembly reference warning message when selecting assembly tree node. --- ILSpy/Languages/CSharpLanguage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index 0c1836845..4be6e9518 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -327,9 +327,9 @@ namespace ICSharpCode.ILSpy decompiler.ProjectGuid = App.CommandLineArguments.FixedGuid; decompiler.DecompileProject(assembly.ModuleDefinition, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken); } else { - base.DecompileAssembly(assembly, output, options); AddReferenceWarningMessage(assembly.AssemblyDefinition, output); output.WriteLine(); + base.DecompileAssembly(assembly, output, options); ModuleDefinition mainModule = assembly.ModuleDefinition; if (mainModule.Types.Count > 0) { output.Write("// Global type: "); From 4626ba3fc89ec5e8f35642d22c739b4780895668 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 25 Oct 2017 17:58:38 +0200 Subject: [PATCH 56/84] Do not treat missing deps.json file as error. - Fixes #908: Assembly loader issue (very minor) --- ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs b/ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs index 5d4478c34..01c54137d 100644 --- a/ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs +++ b/ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler var depsJsonFileName = Path.Combine(basePath, $"{assemblyName}.deps.json"); if (!File.Exists(depsJsonFileName)) { - loadInfo.AddMessage(assemblyName, MessageKind.Error, $"{assemblyName}.deps.json could not be found!"); + loadInfo.AddMessage(assemblyName, MessageKind.Warning, $"{assemblyName}.deps.json could not be found!"); return; } From 4885299816d5300107c1b1dfdde24866ca91b93e Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 25 Oct 2017 22:03:37 +0200 Subject: [PATCH 57/84] Fix #582: Collapse All button for the assemblies list --- ILSpy/Commands/SortAssemblyListCommand.cs | 24 +++++++++++++++++++++- ILSpy/ILSpy.csproj | 1 + ILSpy/Images/CollapseAll.png | Bin 0 -> 436 bytes 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ILSpy/Images/CollapseAll.png diff --git a/ILSpy/Commands/SortAssemblyListCommand.cs b/ILSpy/Commands/SortAssemblyListCommand.cs index 2020cf21d..3f8bc3920 100644 --- a/ILSpy/Commands/SortAssemblyListCommand.cs +++ b/ILSpy/Commands/SortAssemblyListCommand.cs @@ -18,12 +18,13 @@ using System; using System.Collections.Generic; +using ICSharpCode.TreeView; namespace ICSharpCode.ILSpy { [ExportMainMenuCommand(Menu = "_View", Header = "Sort assembly list by name", MenuIcon = "Images/Sort.png", MenuCategory = "View")] [ExportToolbarCommand(ToolTip = "Sort assembly list by name", ToolbarIcon = "Images/Sort.png", ToolbarCategory = "View")] - class SortAssemblyListCommand : SimpleCommand, IComparer + sealed class SortAssemblyListCommand : SimpleCommand, IComparer { public override void Execute(object parameter) { @@ -36,4 +37,25 @@ namespace ICSharpCode.ILSpy return string.Compare(x.ShortName, y.ShortName, StringComparison.CurrentCulture); } } + + [ExportMainMenuCommand(Menu = "_View", Header = "Collapse all tree nodes", MenuIcon = "Images/CollapseAll.png", MenuCategory = "View")] + [ExportToolbarCommand(ToolTip = "Collapse all tree nodes", ToolbarIcon = "Images/CollapseAll.png", ToolbarCategory = "View")] + sealed class CollapseAllCommand : SimpleCommand + { + public override void Execute(object parameter) + { + using (MainWindow.Instance.treeView.LockUpdates()) + CollapseChildren(MainWindow.Instance.treeView.Root); + + void CollapseChildren(SharpTreeNode node) + { + foreach (var child in node.Children) { + if (!child.IsExpanded) + continue; + CollapseChildren(child); + child.IsExpanded = false; + } + } + } + } } diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 9411c6544..304e82ca8 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -346,6 +346,7 @@ + diff --git a/ILSpy/Images/CollapseAll.png b/ILSpy/Images/CollapseAll.png new file mode 100644 index 0000000000000000000000000000000000000000..5e23dbc8101d5b29ea77efc18dcb648e729250bb GIT binary patch literal 436 zcmV;l0ZaagP)-;1p#7!9TZhash#k@NvuL0%D|VN{Qd0z z^lX1SLI~7xKp4xzi%qPLd%_tfVu>7I&SukIw+pY=L*RJ^8@`XA--k!JN9%i&$w^Zr zlu}K;dlkpn9-r1z=I1rO#~qILX*mDsz>T5^VmQQNv1s+)B?qV;9OGbFpe#!iMS(O; zTLr=}B!SXx6#&6;9E?VzmEtVRQ17t{bo6}?T-QaO=PLrt>pi8i3rHye26&LxBWS)& zpmD%QSb7~3hW`f#onIa3F0eQ-e2akiy8~%Gf@mC6Rb_QxcqP9aygfoN$(O@T*7N~$ zI=2XDUP*!XC*U^L4t!b|&^X{lL2u2UrY*P^@R0{pyhGDm3lMm6og~RIZnmD+e&+e> eOI;&B1sDMOI=@rxNH9SF0000 Date: Thu, 26 Oct 2017 19:47:30 +0200 Subject: [PATCH 58/84] Update appveyor.yml to allow publishing nightly nupkgs. --- BuildTools/appveyor-install.ps1 | 6 ++++-- appveyor.yml | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/BuildTools/appveyor-install.ps1 b/BuildTools/appveyor-install.ps1 index 58b1801f9..63afea63c 100644 --- a/BuildTools/appveyor-install.ps1 +++ b/BuildTools/appveyor-install.ps1 @@ -32,5 +32,7 @@ if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { $revision = [Int32]::Parse((git rev-list --count "$baseCommit..HEAD")) + $baseCommitRev; $newVersion="$major.$minor.$build.$revision"; -$env:appveyor_build_version="$newVersion$branch$versionName$suffix"; -appveyor UpdateBuild -Version "$newVersion$branch$versionName$suffix"; \ No newline at end of file +$env:APPVEYOR_BUILD_VERSION="$newVersion$branch$versionName$suffix"; +$env:ILSPY_VERSION_NUMBER="$newVersion$branch$versionName$suffix"; +appveyor UpdateBuild -Version "$newVersion$branch$versionName$suffix"; +Write-Host "new version: $newVersion$branch$versionName$suffix"; \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 33d571e9d..ad8006791 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,4 +20,6 @@ after_test: - python BuildTools\tidy.py artifacts: - path: ILSpy_binaries.zip - name: ILSpy %APPVEYOR_REPO_BRANCH% %ILSPY_VERSION_NUMBER% binaries \ No newline at end of file + name: ILSpy %APPVEYOR_REPO_BRANCH% %ILSPY_VERSION_NUMBER% binaries + - path: '**\*.nupkg' + name: ICSharpCode.Decompiler %APPVEYOR_REPO_BRANCH% %ILSPY_VERSION_NUMBER% NuGet \ No newline at end of file From 42e41c3f167fc82fbd827dca71b469182c211001 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 26 Oct 2017 20:18:38 +0200 Subject: [PATCH 59/84] Automate versioning of nupkg. Remarks: Edit ICSharpCode.Decompiler.nuspec.template --- BuildTools/update-assemblyinfo.ps1 | 1 + ...compiler.nuspec => ICSharpCode.Decompiler.nuspec.template} | 4 ++-- ILSpy/Properties/AssemblyInfo.template.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename ICSharpCode.Decompiler/{ICSharpCode.Decompiler.nuspec => ICSharpCode.Decompiler.nuspec.template} (93%) diff --git a/BuildTools/update-assemblyinfo.ps1 b/BuildTools/update-assemblyinfo.ps1 index 38a0f0df4..fbf59b6f9 100644 --- a/BuildTools/update-assemblyinfo.ps1 +++ b/BuildTools/update-assemblyinfo.ps1 @@ -42,6 +42,7 @@ function gitBranch() { $templateFiles = ( @{Input=$globalAssemblyInfoTemplateFile; Output="ILSpy/Properties/AssemblyInfo.cs"}, @{Input="ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs"; Output="ICSharpCode.Decompiler/Properties/AssemblyInfo.cs"}, + @{Input="ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template"; Output="ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec"}, @{Input="ILSpy/Properties/app.config.template"; Output = "ILSpy/app.config"} ); [string]$mutexId = "ILSpyUpdateAssemblyInfo" + $PSScriptRoot.GetHashCode(); diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template similarity index 93% rename from ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec rename to ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template index ac0c969ca..62f6a6603 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template @@ -2,7 +2,7 @@ ICSharpCode.Decompiler - 3.0.0-beta1 + $INSERTVERSION$$INSERTVERSIONNAMEPOSTFIX$ ILSpy Decompiler Engine Daniel Grunwald, David Srbecky, Ed Harvey, Siegfried Pammer Daniel Grunwald, SharpDevelop @@ -12,7 +12,7 @@ false ICSharpCode.Decompiler is the decompiler engine used in ILSpy. - Copyright 2011-2017 AlphaSierraPapa + Copyright 2011-$INSERTYEAR$ AlphaSierraPapa C# Decompiler ILSpy diff --git a/ILSpy/Properties/AssemblyInfo.template.cs b/ILSpy/Properties/AssemblyInfo.template.cs index b40fac15c..140434136 100644 --- a/ILSpy/Properties/AssemblyInfo.template.cs +++ b/ILSpy/Properties/AssemblyInfo.template.cs @@ -42,7 +42,7 @@ internal static class RevisionClass public const string Minor = "0"; public const string Build = "0"; public const string Revision = "$INSERTREVISION$"; - public const string VersionName = null; + public const string VersionName = "beta1"; public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$"; } From 472c4fb9365e9c6349d4293153e2baab911d57ee Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 07:21:30 +0200 Subject: [PATCH 60/84] Add EmbedSources flag to allow source stepping in nupkg. --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index f8dec72a7..af6e556a3 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -32,6 +32,7 @@ full true + true True $(DefineConstants);STEP @@ -39,6 +40,7 @@ pdbonly true + true @@ -587,4 +589,13 @@ + + + + + + + \ No newline at end of file From 8c5b1faec76c5e800c3f89540ef2ca9a532977f8 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 07:32:07 +0200 Subject: [PATCH 61/84] Change DebugType to portable. --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index af6e556a3..e87b0b7ef 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -30,7 +30,7 @@ - full + portable true true True @@ -38,7 +38,7 @@ - pdbonly + portable true true From f035fa822de0af72110a545fa54704e9d7a63aff Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 08:12:52 +0200 Subject: [PATCH 62/84] Test nuget specific options in appveyor.yml --- appveyor.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ad8006791..7879119a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,8 +6,16 @@ image: Visual Studio 2017 install: - git submodule update --init --recursive - ps: .\BuildTools\appveyor-install.ps1 +nuget: + account_feed: true + project_feed: true + disable_publish_on_pr: true before_build: - nuget restore ILSpy.sln +build: + publish_nuget: true + publish_nuget_symbols: true + include_nuget_references: true build_script: - msbuild ILSpy.sln /v:minimal /p:ResolveNuGetPackages=false "/logger:%ProgramFiles%\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" after_build: From 0d041952360c45adb93294a8254239309fc157a5 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 09:17:43 +0200 Subject: [PATCH 63/84] Revert "Test nuget specific options in appveyor.yml" This reverts commit f035fa822de0af72110a545fa54704e9d7a63aff. --- appveyor.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7879119a2..ad8006791 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,16 +6,8 @@ image: Visual Studio 2017 install: - git submodule update --init --recursive - ps: .\BuildTools\appveyor-install.ps1 -nuget: - account_feed: true - project_feed: true - disable_publish_on_pr: true before_build: - nuget restore ILSpy.sln -build: - publish_nuget: true - publish_nuget_symbols: true - include_nuget_references: true build_script: - msbuild ILSpy.sln /v:minimal /p:ResolveNuGetPackages=false "/logger:%ProgramFiles%\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" after_build: From efb2d3d2b907e452f3cd9298ffc4feca04c74de5 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 09:46:56 +0200 Subject: [PATCH 64/84] Fix IncludeSymbolsInPackage --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index e87b0b7ef..d94c974fc 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -24,7 +24,7 @@ true - true + true ICSharpCode.Decompiler.nuspec Configuration=$(Configuration) @@ -591,9 +591,7 @@ - + From a3baaa67973d3ae3a195efc05cb9f8d8c1f4de28 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 10:26:13 +0200 Subject: [PATCH 65/84] Remove src from nupkg as we now embed the source code in the pdb. --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template index 62f6a6603..030ad559d 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template @@ -31,9 +31,5 @@ - - - - \ No newline at end of file From 4b23b14a819385d0571c77e0ac96e95f34f8219c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 27 Oct 2017 11:54:43 +0200 Subject: [PATCH 66/84] WIP on #722: Add accelerator keys to OpenListDialog --- ILSpy/OpenListDialog.xaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ILSpy/OpenListDialog.xaml b/ILSpy/OpenListDialog.xaml index edac744f6..8428df3fa 100644 --- a/ILSpy/OpenListDialog.xaml +++ b/ILSpy/OpenListDialog.xaml @@ -28,14 +28,14 @@ - + - - - - + + + + From 14448071a3eaf48842692fd7385c070ac12d6cb2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 Oct 2017 16:45:06 +0200 Subject: [PATCH 67/84] Fix #939: Enum values in bitwise operations are not properly decompiled --- ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 6a0a7d2f3..8c5e3ea8c 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -694,6 +694,12 @@ namespace ICSharpCode.Decompiler.CSharp } } + if ((op == BinaryOperatorType.BitwiseAnd || op == BinaryOperatorType.BitwiseOr || op == BinaryOperatorType.ExclusiveOr) + && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum)) { + left = AdjustConstantExpressionToType(left, right.Type); + right = AdjustConstantExpressionToType(right, left.Type); + } + var rr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult); if (rr.IsError || NullableType.GetUnderlyingType(rr.Type).GetStackType() != inst.UnderlyingResultType || !IsCompatibleWithSign(left.Type, inst.Sign) || !IsCompatibleWithSign(right.Type, inst.Sign)) From 255fab7bd64c2ceb61728f6d690e0d535e645966 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Oct 2017 18:04:26 +0200 Subject: [PATCH 68/84] Fix short-circuiting operators when the rhs is a comparison with 0. --- .../TestCases/Pretty/ShortCircuit.cs | 11 ++++ .../TestCases/Pretty/ShortCircuit.il | 60 +++++++++++++++++-- .../TestCases/Pretty/ShortCircuit.opt.il | 43 +++++++++++-- .../Pretty/ShortCircuit.opt.roslyn.il | 37 +++++++++++- .../TestCases/Pretty/ShortCircuit.roslyn.il | 53 +++++++++++++++- .../CSharp/ExpressionBuilder.cs | 3 +- .../IL/Instructions/IfInstruction.cs | 19 ++++++ .../IL/Transforms/ExpressionTransforms.cs | 14 +---- 8 files changed, 208 insertions(+), 32 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs index 89fc7a27c..1bfb799a4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs @@ -27,6 +27,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { public abstract void B(bool b); public abstract bool F(int i); + public abstract int GetInt(int i); public abstract void M1(); public abstract void M2(); public abstract void E(); @@ -91,6 +92,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty this.E(); } + public void StmtOr4() + { + if (this.GetInt(0) != 0 || this.GetInt(1) != 0) { + this.M1(); + } else { + this.M2(); + } + this.E(); + } + public void StmtComplex() { if (this.F(0) && this.F(1) && !this.F(2) && (this.F(3) || this.F(4))) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il index cd6298230..912180bb9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '0fqx5k1s' +.assembly bqtfnoxz { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module '0fqx5k1s.dll' -// MVID: {40923C21-ED40-40E0-8D2A-58DE2CA84852} +.module bqtfnoxz.dll +// MVID: {E41D831E-089A-4F86-AA5D-FD2CB6D7C452} .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 -// Image base: 0x031A0000 +// Image base: 0x03120000 // =============== CLASS MEMBERS DECLARATION =================== @@ -46,6 +46,11 @@ { } // end of method ShortCircuit::F + .method public hidebysig newslot abstract virtual + instance int32 GetInt(int32 i) cil managed + { + } // end of method ShortCircuit::GetInt + .method public hidebysig newslot abstract virtual instance void M1() cil managed { @@ -348,6 +353,49 @@ IL_0040: ret } // end of method ShortCircuit::StmtOr3 + .method public hidebysig instance void + StmtOr4() cil managed + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0008: brtrue.s IL_0016 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.0 + IL_0017: nop + IL_0018: stloc.0 + IL_0019: ldloc.0 + IL_001a: brtrue.s IL_0027 + + IL_001c: nop + IL_001d: ldarg.0 + IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0023: nop + IL_0024: nop + IL_0025: br.s IL_0030 + + IL_0027: nop + IL_0028: ldarg.0 + IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_002e: nop + IL_002f: nop + IL_0030: ldarg.0 + IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0036: nop + IL_0037: ret + } // end of method ShortCircuit::StmtOr4 + .method public hidebysig instance void StmtComplex() cil managed { @@ -588,4 +636,4 @@ // ============================================================= // *********** DISASSEMBLY COMPLETE *********************** -// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\ShortCircuit.res +// WARNING: Created Win32 resource file ../../../TestCases/Pretty\ShortCircuit.res diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il index eb065bab6..afa808e96 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly gbge3vmw +.assembly '4yyrmwig' { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module gbge3vmw.dll -// MVID: {39FE0BDC-C8CF-421C-936D-85782F68AEF4} +.module '4yyrmwig.dll' +// MVID: {A53FB590-72B6-46AB-809D-9F6F92B64475} .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 -// Image base: 0x00C00000 +// Image base: 0x015D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -46,6 +46,11 @@ { } // end of method ShortCircuit::F + .method public hidebysig newslot abstract virtual + instance int32 GetInt(int32 i) cil managed + { + } // end of method ShortCircuit::GetInt + .method public hidebysig newslot abstract virtual instance void M1() cil managed { @@ -268,6 +273,32 @@ IL_002f: ret } // end of method ShortCircuit::StmtOr3 + .method public hidebysig instance void + StmtOr4() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0007: brtrue.s IL_0012 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0010: brfalse.s IL_001a + + IL_0012: ldarg.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0018: br.s IL_0020 + + IL_001a: ldarg.0 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0020: ldarg.0 + IL_0021: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0026: ret + } // end of method ShortCircuit::StmtOr4 + .method public hidebysig instance void StmtComplex() cil managed { @@ -433,4 +464,4 @@ // ============================================================= // *********** DISASSEMBLY COMPLETE *********************** -// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\ShortCircuit.opt.res +// WARNING: Created Win32 resource file ../../../TestCases/Pretty\ShortCircuit.opt.res diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il index 5717bd613..537cc5503 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module ShortCircuit.dll -// MVID: {A27E149C-542B-41C0-AB29-FA01A65D43CB} +// MVID: {FAFDF41B-AD51-4575-890D-F2652CF85283} .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 -// Image base: 0x02490000 +// Image base: 0x00710000 // =============== CLASS MEMBERS DECLARATION =================== @@ -50,6 +50,11 @@ { } // end of method ShortCircuit::F + .method public hidebysig newslot abstract virtual + instance int32 GetInt(int32 i) cil managed + { + } // end of method ShortCircuit::GetInt + .method public hidebysig newslot abstract virtual instance void M1() cil managed { @@ -272,6 +277,32 @@ IL_002f: ret } // end of method ShortCircuit::StmtOr3 + .method public hidebysig instance void + StmtOr4() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0007: brtrue.s IL_0012 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.1 + IL_000b: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0010: brfalse.s IL_001a + + IL_0012: ldarg.0 + IL_0013: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0018: br.s IL_0020 + + IL_001a: ldarg.0 + IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_0020: ldarg.0 + IL_0021: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0026: ret + } // end of method ShortCircuit::StmtOr4 + .method public hidebysig instance void StmtComplex() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il index 20803869a..efcd7043a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.17929 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module ShortCircuit.dll -// MVID: {5FB25D31-D6C4-4D39-B72D-A6EBD832225B} +// MVID: {B0D8F5AF-A2A3-4091-846A-B19B13874A74} .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 -// Image base: 0x00D60000 +// Image base: 0x00AD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -50,6 +50,11 @@ { } // end of method ShortCircuit::F + .method public hidebysig newslot abstract virtual + instance int32 GetInt(int32 i) cil managed + { + } // end of method ShortCircuit::GetInt + .method public hidebysig newslot abstract virtual instance void M1() cil managed { @@ -336,6 +341,48 @@ IL_003c: ret } // end of method ShortCircuit::StmtOr3 + .method public hidebysig instance void + StmtOr4() cil managed + { + // Code size 55 (0x37) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0008: brtrue.s IL_0016 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::GetInt(int32) + IL_0011: ldc.i4.0 + IL_0012: cgt.un + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.1 + IL_0017: stloc.0 + IL_0018: ldloc.0 + IL_0019: brfalse.s IL_0026 + + IL_001b: nop + IL_001c: ldarg.0 + IL_001d: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1() + IL_0022: nop + IL_0023: nop + IL_0024: br.s IL_002f + + IL_0026: nop + IL_0027: ldarg.0 + IL_0028: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2() + IL_002d: nop + IL_002e: nop + IL_002f: ldarg.0 + IL_0030: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E() + IL_0035: nop + IL_0036: ret + } // end of method ShortCircuit::StmtOr4 + .method public hidebysig instance void StmtComplex() cil managed { diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 8c5e3ea8c..d9ac60f1a 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1673,7 +1673,8 @@ namespace ICSharpCode.Decompiler.CSharp // ILAst LogicAnd/LogicOr can return a different value than 0 or 1 // if the rhs is evaluated. // We can only correctly translate it to C# if the rhs is of type boolean: - if (op != BinaryOperatorType.Any && rhs.Type.IsKnownType(KnownTypeCode.Boolean)) { + if (op != BinaryOperatorType.Any && (rhs.Type.IsKnownType(KnownTypeCode.Boolean) || IfInstruction.IsInConditionSlot(inst))) { + rhs = rhs.ConvertToBoolean(this); return new BinaryOperatorExpression(condition, op, rhs) .WithILInstruction(inst) .WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean))); diff --git a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs index 59845c679..93fe7bae3 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs @@ -107,5 +107,24 @@ namespace ICSharpCode.Decompiler.IL falseInst.WriteTo(output, options); } } + + /// + /// Gets whether the input instruction occurs in a context where it is being compared with 0. + /// + internal static bool IsInConditionSlot(ILInstruction inst) + { + var slot = inst.SlotInfo; + if (slot == IfInstruction.ConditionSlot) + return true; + if (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot) + return IsInConditionSlot(inst.Parent); + if (inst.Parent is Comp comp) { + if (comp.Left == inst && comp.Right.MatchLdcI4(0)) + return true; + if (comp.Right == inst && comp.Left.MatchLdcI4(0)) + return true; + } + return false; + } } } diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index f0011a9cf..7471059e3 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -54,18 +54,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms // we know those were already handled previously. } - static bool IsInConditionSlot(ILInstruction inst) - { - var slot = inst.SlotInfo; - if (slot == IfInstruction.ConditionSlot) - return true; - if (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot) - return IsInConditionSlot(inst.Parent); - if (inst.Parent.MatchLogicNot(out _)) - return true; - return false; - } - protected internal override void VisitComp(Comp inst) { // "logic.not(arg)" is sugar for "comp(arg != ldc.i4 0)" @@ -73,7 +61,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms VisitLogicNot(inst, arg); return; } else if (inst.Kind == ComparisonKind.Inequality && inst.LiftingKind == ComparisonLiftingKind.None - && inst.Right.MatchLdcI4(0) && (IsInConditionSlot(inst) || inst.Left is Comp) + && inst.Right.MatchLdcI4(0) && (IfInstruction.IsInConditionSlot(inst) || inst.Left is Comp) ) { // if (comp(x != 0)) ==> if (x) // comp(comp(...) != 0) => comp(...) From 9e2f98cb8d75253fe9dd480fa88359618a89b2fc Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 Oct 2017 18:28:03 +0200 Subject: [PATCH 69/84] Improve RemoveDeadVariableInit and CopyPropagation --- .../IL/Transforms/CopyPropagation.cs | 2 +- .../IL/Transforms/RemoveDeadVariableInit.cs | 28 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs index 1ef40d116..071f59d63 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs @@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) { if (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot) { // dead store to stack - if (copiedExpr.Flags == InstructionFlags.None) { + if (SemanticHelper.IsPure(copiedExpr.Flags)) { // no-op -> delete context.Step("remove dead store to stack: no-op -> delete", block.Instructions[i]); block.Instructions.RemoveAt(i--); diff --git a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs index b8dc74578..b12f102a7 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Collections.Generic; +using System.Linq; using ICSharpCode.Decompiler.FlowAnalysis; namespace ICSharpCode.Decompiler.IL.Transforms @@ -37,13 +39,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms v.HasInitialValue = false; } } - if (function.IsIterator || function.IsAsync) { - // In yield return + async, the C# compiler tends to store null/default(T) to variables - // when the variable goes out of scope. Remove such useless stores. - foreach (var v in function.Variables) { - if (v.Kind == VariableKind.Local && v.StoreCount == 1 && v.LoadCount == 0 && v.AddressCount == 0) { - if (v.StoreInstructions[0] is StLoc stloc && (stloc.Value.MatchLdNull() || stloc.Value is DefaultValue) && stloc.Parent is Block block) { + // Remove dead stores to variables that are never read from. + // If the stored value has some side-effect, the value is unwrapped. + // This is necessary to remove useless stores generated by some compilers, e.g., the F# compiler. + // In yield return + async, the C# compiler tends to store null/default(T) to variables + // when the variable goes out of scope. + var variableQueue = new Queue(function.Variables.Where(v => v.Kind == VariableKind.Local || v.Kind == VariableKind.StackSlot)); + while (variableQueue.Count > 0) { + var v = variableQueue.Dequeue(); + if (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot) + continue; + if (v.LoadCount != 0 || v.AddressCount != 0) + continue; + foreach (var stloc in v.StoreInstructions.OfType().ToArray()) { + if (stloc.Parent is Block block) { + if (SemanticHelper.IsPure(stloc.Value.Flags)) { block.Instructions.Remove(stloc); + } else { + stloc.ReplaceWith(stloc.Value); + } + if (stloc.Value is LdLoc ldloc && (ldloc.Variable.Kind == VariableKind.Local || ldloc.Variable.Kind == VariableKind.StackSlot)) { + variableQueue.Enqueue(ldloc.Variable); } } } From 97eac21021cab2923e1d6abe2f7a753acee241b2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 Oct 2017 18:28:30 +0200 Subject: [PATCH 70/84] Update F# using pretty tests --- .../TestCases/ILPretty/FSharpUsing_Debug.cs | 18 +++++++-------- .../TestCases/ILPretty/FSharpUsing_Release.cs | 22 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs index d9ca8bff4..972149116 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs @@ -31,28 +31,28 @@ public static class FSharpUsingPatterns public static void sample4() { Console.WriteLine("some text"); - int num; + int num = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { num = fileStream.ReadByte(); } - int firstByte = num; - Console.WriteLine("read:" + firstByte.ToString()); + int num2 = num; + Console.WriteLine("read:" + num2.ToString()); } public static void sample5() { Console.WriteLine("some text"); - int num; + int num = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { num = fileStream.ReadByte(); } - int firstByte = num; - int num3; + int num2 = num; + int num3 = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { - int num2 = fileStream.ReadByte(); + fileStream.ReadByte(); num3 = fileStream.ReadByte(); } - int secondByte = num3; - Console.WriteLine("read: {0}, {1}", firstByte, secondByte); + int num4 = num3; + Console.WriteLine("read: {0}, {1}", num2, num4); } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs index 6396bc6d5..9585b51a1 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs @@ -31,28 +31,28 @@ public static class FSharpUsingPatterns public static void sample4() { Console.WriteLine("some text"); - int num; + int num = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { num = fileStream.ReadByte(); } - int firstByte = num; - Console.WriteLine("read:" + firstByte.ToString()); + int num2 = num; + Console.WriteLine("read:" + num2.ToString()); } public static void sample5() { Console.WriteLine("some text"); - int secondByte; + int num = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { - secondByte = fileStream.ReadByte(); + num = fileStream.ReadByte(); } - int firstByte = secondByte; - int num2; + int num2 = num; + int num3 = default(int); using (FileStream fileStream = File.OpenRead("x.txt")) { - int num = fileStream.ReadByte(); - num2 = fileStream.ReadByte(); + fileStream.ReadByte(); + num3 = fileStream.ReadByte(); } - secondByte = num2; - Console.WriteLine("read: {0}, {1}", firstByte, secondByte); + num = num3; + Console.WriteLine("read: {0}, {1}", num2, num); } } From aa87169331ce21892f3a33c9c23e44a4ab655583 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 Oct 2017 18:50:18 +0200 Subject: [PATCH 71/84] Clean up RemoveDeadVariableInit --- .../IL/Transforms/RemoveDeadVariableInit.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs index b12f102a7..e5d1831bf 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs @@ -44,7 +44,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms // This is necessary to remove useless stores generated by some compilers, e.g., the F# compiler. // In yield return + async, the C# compiler tends to store null/default(T) to variables // when the variable goes out of scope. - var variableQueue = new Queue(function.Variables.Where(v => v.Kind == VariableKind.Local || v.Kind == VariableKind.StackSlot)); + var variableQueue = new Queue(function.Variables); while (variableQueue.Count > 0) { var v = variableQueue.Dequeue(); if (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot) @@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms } else { stloc.ReplaceWith(stloc.Value); } - if (stloc.Value is LdLoc ldloc && (ldloc.Variable.Kind == VariableKind.Local || ldloc.Variable.Kind == VariableKind.StackSlot)) { + if (stloc.Value is LdLoc ldloc) { variableQueue.Enqueue(ldloc.Variable); } } From f8b27066a182837a1bdc17298d85a61c48e4a9bb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 Oct 2017 02:32:58 +0200 Subject: [PATCH 72/84] Remove ILInstructionExtensions.cs --- .../ICSharpCode.Decompiler.csproj | 1 - .../IL/ControlFlow/ConditionDetection.cs | 2 +- .../Instructions/ILInstructionExtensions.cs | 20 ------------------- 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 1e02da7aa..d94c974fc 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -275,7 +275,6 @@ - diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index 97f763426..657a5f7a0 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -174,7 +174,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow // -> if (...) { ... } else { ... } goto exitPoint; // the else block is not empty or nop-only: - if (!targetBlock.IsNopBlock(ignoreExitPoint: falseExitInst)) { + if (targetBlock.Children.Any(inst => !(inst is Nop) && inst != falseExitInst)) { context.Step("Inline block as else-branch", ifInst); targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); targetBlock.Remove(); diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs deleted file mode 100644 index c363dd1de..000000000 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; - -namespace ICSharpCode.Decompiler.IL -{ - public static class ILInstructionExtensions - { - /// - /// Determines whether a block only consists of nop instructions or is empty. - /// - public static bool IsNopBlock(this Block block, ILInstruction ignoreExitPoint = null) - { - if (block == null) - throw new ArgumentNullException(nameof(block)); - return block.Children.Count(i => !(i is Nop) && i != ignoreExitPoint) == 0; - } - } -} From 8fe53a27582463c5a78484c8576e0d0b3175ceca Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 Oct 2017 11:42:41 +0100 Subject: [PATCH 73/84] Fix #267: Improve formatting for long sequences of method calls --- .../OutputVisitor/CSharpOutputVisitor.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index cc3708c81..5dfe66d38 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -278,6 +278,30 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor isAtStartOfLine = true; isAfterSpace = false; } + + int GetCallChainLengthLimited(MemberReferenceExpression expr) + { + int callChainLength = 0; + var node = expr; + + while (node.Target is InvocationExpression invocation && invocation.Target is MemberReferenceExpression mre && callChainLength < 4) { + node = mre; + callChainLength++; + } + return callChainLength; + } + + protected virtual void InsertNewLineWhenInMethodCallChain(MemberReferenceExpression expr) + { + int callChainLength = GetCallChainLengthLimited(expr); + if (callChainLength < 3) return; + if (callChainLength == 3) + writer.Indent(); + writer.NewLine(); + + isAtStartOfLine = true; + isAfterSpace = false; + } protected virtual void OpenBrace(BraceStyle style) { @@ -810,6 +834,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor invocationExpression.Target.AcceptVisitor(this); Space(policy.SpaceBeforeMethodCallParentheses); WriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, policy.SpaceWithinMethodCallParentheses); + if (!(invocationExpression.Parent is MemberReferenceExpression)) { + if (invocationExpression.Target is MemberReferenceExpression mre) { + if (GetCallChainLengthLimited(mre) > 3) + writer.Unindent(); + } + } EndNode(invocationExpression); } @@ -859,6 +889,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(memberReferenceExpression); memberReferenceExpression.Target.AcceptVisitor(this); + InsertNewLineWhenInMethodCallChain(memberReferenceExpression); WriteToken(Roles.Dot); WriteIdentifier(memberReferenceExpression.MemberNameToken); WriteTypeArguments(memberReferenceExpression.TypeArguments); From 9df0e920b36c55ddda949b671715b0ce97b79a8f Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 Oct 2017 19:41:02 +0100 Subject: [PATCH 74/84] Fix #933: Add line break before call to chained ctor --- .../CSharp/OutputVisitor/CSharpOutputVisitor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index 5dfe66d38..0d46092d5 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -1890,8 +1890,10 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor Space(policy.SpaceBeforeConstructorDeclarationParentheses); WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses); if (!constructorDeclaration.Initializer.IsNull) { - Space(); + NewLine(); + writer.Indent(); constructorDeclaration.Initializer.AcceptVisitor(this); + writer.Unindent(); } WriteMethodBody(constructorDeclaration.Body, policy.ConstructorBraceStyle); EndNode(constructorDeclaration); From c683567a8c5b2e8f4a1642a360b1c8cc37e99963 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 Oct 2017 22:45:40 +0100 Subject: [PATCH 75/84] Add BinaryOperatorType.IsBitwise extension. --- ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs | 3 +-- ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index d9ac60f1a..cf81abcc6 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -694,8 +694,7 @@ namespace ICSharpCode.Decompiler.CSharp } } - if ((op == BinaryOperatorType.BitwiseAnd || op == BinaryOperatorType.BitwiseOr || op == BinaryOperatorType.ExclusiveOr) - && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum)) { + if (op.IsBitwise() && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum)) { left = AdjustConstantExpressionToType(left, right.Type); right = AdjustConstantExpressionToType(right, left.Type); } diff --git a/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs b/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs index a1f3bb3d2..4104ac02b 100644 --- a/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs +++ b/ICSharpCode.Decompiler/CSharp/NRefactoryExtensions.cs @@ -99,5 +99,15 @@ namespace ICSharpCode.Decompiler.CSharp var simpleType = type as SimpleType; return simpleType != null && simpleType.Identifier == "__arglist"; } + + /// + /// Returns true if is bitwise and, bitwise or, or exclusive or. + /// + public static bool IsBitwise(this BinaryOperatorType operatorType) + { + return operatorType == BinaryOperatorType.BitwiseAnd + || operatorType == BinaryOperatorType.BitwiseOr + || operatorType == BinaryOperatorType.ExclusiveOr; + } } } From 079109bc85830fa4d8d49c7b50c704950fe2bce1 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 29 Oct 2017 22:46:06 +0100 Subject: [PATCH 76/84] Rename TextWriterOutputFormatter.cs to TextWriterTokenWriter.cs --- .../{TextWriterOutputFormatter.cs => TextWriterTokenWriter.cs} | 0 ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename ICSharpCode.Decompiler/CSharp/OutputVisitor/{TextWriterOutputFormatter.cs => TextWriterTokenWriter.cs} (100%) diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs similarity index 100% rename from ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterOutputFormatter.cs rename to ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index d94c974fc..a804aa488 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -205,7 +205,7 @@ - + From bec8c61a41abde34ac4ea7e1f9dc3bd5e6cf420a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 10:49:34 +0100 Subject: [PATCH 77/84] WIP on #945: Add options LoadInMemory and ThrowOnAssemblyResolveErrors --- ICSharpCode.Decompiler/DecompilerSettings.cs | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index 6d6e16d21..9e29709ef 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -375,6 +375,34 @@ namespace ICSharpCode.Decompiler #endregion + #region Assembly Load and Resolve options + + bool loadInMemory = false; + + public bool LoadInMemory { + get { return loadInMemory; } + set { + if (loadInMemory != value) { + loadInMemory = value; + OnPropertyChanged(); + } + } + } + + bool throwOnAssemblyResolveErrors = false; + + public bool ThrowOnAssemblyResolveErrors { + get { return throwOnAssemblyResolveErrors; } + set { + if (throwOnAssemblyResolveErrors != value) { + throwOnAssemblyResolveErrors = value; + OnPropertyChanged(); + } + } + } + + #endregion + CSharpFormattingOptions csharpFormattingOptions; public CSharpFormattingOptions CSharpFormattingOptions { From fa650c8e68573501cd72bf8433a039b7cf713d25 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 10:50:19 +0100 Subject: [PATCH 78/84] WIP on #945: Add first implementation of UniversalAssemblyResolver --- .../DotNetCore/UniversalAssemblyResolver.cs | 350 ++++++++++++++++++ .../ICSharpCode.Decompiler.csproj | 1 + ICSharpCode.Decompiler/Util/EmptyList.cs | 5 + 3 files changed, 356 insertions(+) create mode 100644 ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs diff --git a/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs b/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs new file mode 100644 index 000000000..a52bbb2e5 --- /dev/null +++ b/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs @@ -0,0 +1,350 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using ICSharpCode.Decompiler.Util; +using Mono.Cecil; + +namespace ICSharpCode.Decompiler +{ + public class UniversalAssemblyResolver : IAssemblyResolver + { + DotNetCorePathFinder dotNetCorePathFinder; + readonly bool throwOnError; + readonly string mainAssemblyFileName; + readonly string baseDirectory; + readonly Dictionary loadedAssemblyReferences; + readonly List directories; + readonly List gac_paths = GetGacPaths(); + + public static readonly bool OnMono = Type.GetType("Mono.Runtime") != null; + + public event AssemblyResolveEventHandler ResolveFailed; + + public void AddSearchDirectory(string directory) + { + directories.Add(directory); + } + + public void RemoveSearchDirectory(string directory) + { + directories.Remove(directory); + } + + public string[] GetSearchDirectories() + { + return directories.ToArray(); + } + + public string TargetFramework { get; set; } + + private UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError) + { + this.mainAssemblyFileName = mainAssemblyFileName; + this.baseDirectory = Path.GetDirectoryName(mainAssemblyFileName); + + AddSearchDirectory(baseDirectory); + } + + public static ModuleDefinition LoadMainModule(string mainAssemblyFileName, bool throwOnError = true, bool inMemory = false) + { + var resolver = new UniversalAssemblyResolver(mainAssemblyFileName, throwOnError); + + var module = ModuleDefinition.ReadModule(mainAssemblyFileName, new ReaderParameters { + AssemblyResolver = resolver, + InMemory = inMemory + }); + + resolver.TargetFramework = module.Assembly.DetectTargetFrameworkId(); + + return module; + } + + public AssemblyDefinition Resolve(AssemblyNameReference name) + { + return Resolve(name, new ReaderParameters()); + } + + public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) + { + var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None); + string file = null; + switch (targetFramework[0]) { + case ".NETCoreApp": + case ".NETStandard": + if (targetFramework.Length != 2) goto default; + if (dotNetCorePathFinder == null) { + var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1]; + dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, TargetFramework, version, this.loadedAssemblyReferences); + } + file = dotNetCorePathFinder.TryResolveDotNetCore(name); + if (file == null) + goto default; + else { + var asm = ModuleDefinition.ReadModule(file, parameters).Assembly; + if (throwOnError && asm == null) + throw new AssemblyResolutionException(name); + return asm; + } + default: + return ResolveInternal(name, parameters); + } + } + + AssemblyDefinition ResolveInternal(AssemblyNameReference name, ReaderParameters parameters) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + + if (parameters == null) + throw new ArgumentNullException(nameof(parameters)); + + var assembly = SearchDirectory(name, directories, parameters); + if (assembly != null) + return assembly; + + if (name.IsRetargetable) { + // if the reference is retargetable, zero it + name = new AssemblyNameReference(name.Name, ZeroVersion) { + PublicKeyToken = Empty.Array, + }; + } + + var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName); + var framework_dirs = OnMono + ? new[] { framework_dir, Path.Combine(framework_dir, "Facades") } + : new[] { framework_dir }; + + if (IsZero(name.Version)) { + assembly = SearchDirectory(name, framework_dirs, parameters); + if (assembly != null) + return assembly; + } + + if (name.Name == "mscorlib") { + assembly = GetCorlib(name, parameters); + if (assembly != null) + return assembly; + } + + assembly = GetAssemblyInGac(name, parameters); + if (assembly != null) + return assembly; + + assembly = SearchDirectory(name, framework_dirs, parameters); + if (assembly != null) + return assembly; + + if (ResolveFailed != null) { + assembly = ResolveFailed(this, name); + if (assembly != null) + return assembly; + } + + if (throwOnError) + throw new AssemblyResolutionException(name); + return null; + } + + #region .NET / mono GAC handling + AssemblyDefinition SearchDirectory(AssemblyNameReference name, IEnumerable directories, ReaderParameters parameters) + { + var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" }; + foreach (var directory in directories) { + foreach (var extension in extensions) { + string file = Path.Combine(directory, name.Name + extension); + if (!File.Exists(file)) + continue; + try { + return GetAssembly(file, parameters); + } catch (System.BadImageFormatException) { + continue; + } + } + } + + return null; + } + + static bool IsZero(Version version) + { + return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; + } + + static Version ZeroVersion = new Version(0, 0, 0, 0); + + AssemblyDefinition GetCorlib(AssemblyNameReference reference, ReaderParameters parameters) + { + var version = reference.Version; + var corlib = typeof(object).Assembly.GetName(); + + if (corlib.Version == version || IsZero(version)) + return GetAssembly(typeof(object).Module.FullyQualifiedName, parameters); + + var path = Directory.GetParent( + Directory.GetParent( + typeof(object).Module.FullyQualifiedName).FullName + ).FullName; + + if (OnMono) { + if (version.Major == 1) + path = Path.Combine(path, "1.0"); + else if (version.Major == 2) { + if (version.MajorRevision == 5) + path = Path.Combine(path, "2.1"); + else + path = Path.Combine(path, "2.0"); + } else if (version.Major == 4) + path = Path.Combine(path, "4.0"); + else + throw new NotSupportedException("Version not supported: " + version); + } else { + switch (version.Major) { + case 1: + if (version.MajorRevision == 3300) + path = Path.Combine(path, "v1.0.3705"); + else + path = Path.Combine(path, "v1.0.5000.0"); + break; + case 2: + path = Path.Combine(path, "v2.0.50727"); + break; + case 4: + path = Path.Combine(path, "v4.0.30319"); + break; + default: + throw new NotSupportedException("Version not supported: " + version); + } + } + + var file = Path.Combine(path, "mscorlib.dll"); + if (File.Exists(file)) + return GetAssembly(file, parameters); + + return null; + } + + static List GetGacPaths() + { + if (OnMono) + return GetDefaultMonoGacPaths(); + + var paths = new List(2); + var windir = Environment.GetEnvironmentVariable("WINDIR"); + if (windir == null) + return paths; + + paths.Add(Path.Combine(windir, "assembly")); + paths.Add(Path.Combine(windir, Path.Combine("Microsoft.NET", "assembly"))); + return paths; + } + + static List GetDefaultMonoGacPaths() + { + var paths = new List(1); + var gac = GetCurrentMonoGac(); + if (gac != null) + paths.Add(gac); + + var gac_paths_env = Environment.GetEnvironmentVariable("MONO_GAC_PREFIX"); + if (string.IsNullOrEmpty(gac_paths_env)) + return paths; + + var prefixes = gac_paths_env.Split(Path.PathSeparator); + foreach (var prefix in prefixes) { + if (string.IsNullOrEmpty(prefix)) + continue; + + var gac_path = Path.Combine(Path.Combine(Path.Combine(prefix, "lib"), "mono"), "gac"); + if (Directory.Exists(gac_path) && !paths.Contains(gac)) + paths.Add(gac_path); + } + + return paths; + } + + static string GetCurrentMonoGac() + { + return Path.Combine( + Directory.GetParent( + Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)).FullName, + "gac"); + } + + AssemblyDefinition GetAssembly(string file, ReaderParameters parameters) + { + if (parameters.AssemblyResolver == null) + parameters.AssemblyResolver = this; + + return ModuleDefinition.ReadModule(file, parameters).Assembly; + } + + AssemblyDefinition GetAssemblyInGac(AssemblyNameReference reference, ReaderParameters parameters) + { + if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0) + return null; + + if (OnMono) + return GetAssemblyInMonoGac(reference, parameters); + + return GetAssemblyInNetGac(reference, parameters); + } + + AssemblyDefinition GetAssemblyInMonoGac(AssemblyNameReference reference, ReaderParameters parameters) + { + for (int i = 0; i < gac_paths.Count; i++) { + var gac_path = gac_paths[i]; + var file = GetAssemblyFile(reference, string.Empty, gac_path); + if (File.Exists(file)) + return GetAssembly(file, parameters); + } + + return null; + } + + AssemblyDefinition GetAssemblyInNetGac(AssemblyNameReference reference, ReaderParameters parameters) + { + var gacs = new[] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" }; + var prefixes = new[] { string.Empty, "v4.0_" }; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < gacs.Length; j++) { + var gac = Path.Combine(gac_paths[i], gacs[j]); + var file = GetAssemblyFile(reference, prefixes[i], gac); + if (Directory.Exists(gac) && File.Exists(file)) + return GetAssembly(file, parameters); + } + } + + return null; + } + + static string GetAssemblyFile(AssemblyNameReference reference, string prefix, string gac) + { + var gac_folder = new StringBuilder() + .Append(prefix) + .Append(reference.Version) + .Append("__"); + + for (int i = 0; i < reference.PublicKeyToken.Length; i++) + gac_folder.Append(reference.PublicKeyToken[i].ToString("x2")); + + return Path.Combine( + Path.Combine( + Path.Combine(gac, reference.Name), gac_folder.ToString()), + reference.Name + ".dll"); + } + + #endregion + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + } + } +} diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index a804aa488..764707c72 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -274,6 +274,7 @@ + diff --git a/ICSharpCode.Decompiler/Util/EmptyList.cs b/ICSharpCode.Decompiler/Util/EmptyList.cs index a9014be59..d98a1f309 100644 --- a/ICSharpCode.Decompiler/Util/EmptyList.cs +++ b/ICSharpCode.Decompiler/Util/EmptyList.cs @@ -111,4 +111,9 @@ namespace ICSharpCode.Decompiler.Util { } } + + public static class Empty + { + public static readonly T[] Array = new T[0]; + } } From 22b9e4877ab023208247fc56fe5371c2486f3875 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 10:50:45 +0100 Subject: [PATCH 79/84] WIP on #945: Add CSharpDecompiler ctor taking a file name. --- ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 1bba92164..a290c03c5 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -168,6 +168,11 @@ namespace ICSharpCode.Decompiler.CSharp get { return astTransforms; } } + public CSharpDecompiler(string fileName, DecompilerSettings settings) + : this(UniversalAssemblyResolver.LoadMainModule(fileName, settings.ThrowOnAssemblyResolveErrors, settings.LoadInMemory), settings) + { + } + public CSharpDecompiler(ModuleDefinition module, DecompilerSettings settings) : this(new DecompilerTypeSystem(module), settings) { From 484567b47247e9387b2e201753b4fbd6709f7f6d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 11:31:01 +0100 Subject: [PATCH 80/84] WIP on #945: Add Decompile*AsString overloads and DecompileType(FullTypeName). --- .../CSharp/CSharpDecompiler.cs | 115 +++++++++++++++--- 1 file changed, 98 insertions(+), 17 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index a290c03c5..bbba077c3 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -31,6 +31,7 @@ using ICSharpCode.Decompiler.IL.ControlFlow; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; +using System.IO; namespace ICSharpCode.Decompiler.CSharp { @@ -185,7 +186,7 @@ namespace ICSharpCode.Decompiler.CSharp this.typeSystem = typeSystem; this.settings = settings; } - + #region MemberIsHidden public static bool MemberIsHidden(MemberReference member, DecompilerSettings settings) { @@ -213,7 +214,7 @@ namespace ICSharpCode.Decompiler.CSharp return true; } } - + FieldDefinition field = member as FieldDefinition; if (field != null) { if (field.IsCompilerGenerated()) { @@ -235,10 +236,10 @@ namespace ICSharpCode.Decompiler.CSharp return true; } } - + return false; } - + static bool IsSwitchOnStringCache(FieldDefinition field) { return field.Name.StartsWith("<>f__switch", StringComparison.Ordinal); @@ -263,7 +264,7 @@ namespace ICSharpCode.Decompiler.CSharp return type.BaseType.FullName == "System.Object" && !type.HasInterfaces; } #endregion - + TypeSystemAstBuilder CreateAstBuilder(ITypeResolveContext decompilationContext) { var typeSystemAstBuilder = new TypeSystemAstBuilder(); @@ -272,7 +273,7 @@ namespace ICSharpCode.Decompiler.CSharp typeSystemAstBuilder.AddResolveResultAnnotations = true; return typeSystemAstBuilder; } - + void RunTransforms(AstNode rootNode, ITypeResolveContext decompilationContext) { var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); @@ -283,7 +284,14 @@ namespace ICSharpCode.Decompiler.CSharp } rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); } - + + string SyntaxTreeToString(SyntaxTree syntaxTree) + { + StringWriter w = new StringWriter(); + syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions)); + return w.ToString(); + } + /// /// Decompile assembly and module attributes. /// @@ -297,6 +305,14 @@ namespace ICSharpCode.Decompiler.CSharp return syntaxTree; } + /// + /// Decompile assembly and module attributes. + /// + public string DecompileModuleAndAssemblyAttributesToString() + { + return SyntaxTreeToString(DecompileModuleAndAssemblyAttributes()); + } + void DoDecompileModuleAndAssemblyAttributes(ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) { foreach (var a in typeSystem.Compilation.MainAssembly.AssemblyAttributes) { @@ -330,7 +346,7 @@ namespace ICSharpCode.Decompiler.CSharp groupNode.AddChild(typeDecl, SyntaxTree.MemberRole); } } - + /// /// Decompiles the whole module into a single syntax tree. /// @@ -344,7 +360,15 @@ namespace ICSharpCode.Decompiler.CSharp RunTransforms(syntaxTree, decompilationContext); return syntaxTree; } - + + /// + /// Decompiles the whole module into a single string. + /// + public string DecompileWholeModuleAsString() + { + return SyntaxTreeToString(DecompileWholeModuleAsSingleFile()); + } + /// /// Decompile the given types. /// @@ -363,6 +387,47 @@ namespace ICSharpCode.Decompiler.CSharp return syntaxTree; } + /// + /// Decompile the given types. + /// + /// + /// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definitions. + /// + public string DecompileTypesAsString(IEnumerable types) + { + return SyntaxTreeToString(DecompileTypes(types)); + } + + /// + /// Decompile the given type. + /// + /// + /// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition. + /// + public SyntaxTree DecompileType(FullTypeName fullTypeName) + { + var type = typeSystem.Compilation.FindType(fullTypeName).GetDefinition(); + if (type == null) + throw new InvalidOperationException($"Could not find type definition {fullTypeName} in type system."); + var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly); + syntaxTree = new SyntaxTree(); + definedSymbols = new HashSet(); + DoDecompileTypes(new[] { typeSystem.GetCecil(type) }, decompilationContext, syntaxTree); + RunTransforms(syntaxTree, decompilationContext); + return syntaxTree; + } + + /// + /// Decompile the given type. + /// + /// + /// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition. + /// + public string DecompileTypeAsString(FullTypeName fullTypeName) + { + return SyntaxTreeToString(DecompileType(fullTypeName)); + } + /// /// Decompile the specified types and/or members. /// @@ -427,6 +492,22 @@ namespace ICSharpCode.Decompiler.CSharp return syntaxTree; } + /// + /// Decompile the specified types and/or members. + /// + public string DecompileAsString(params IMemberDefinition[] definitions) + { + return SyntaxTreeToString(Decompile(definitions)); + } + + /// + /// Decompile the specified types and/or members. + /// + public string DecompileAsString(IList definitions) + { + return SyntaxTreeToString(Decompile(definitions)); + } + IEnumerable AddInterfaceImplHelpers(EntityDeclaration memberDecl, MethodDefinition methodDef, TypeSystemAstBuilder astBuilder) { @@ -446,7 +527,7 @@ namespace ICSharpCode.Decompiler.CSharp methodDecl.Parameters.AddRange(memberDecl.GetChildrenByRole(Roles.Parameter).Select(n => n.Clone())); methodDecl.Constraints.AddRange(memberDecl.GetChildrenByRole(Roles.Constraint) .Select(n => (Constraint)n.Clone())); - + methodDecl.Body = new BlockStatement(); methodDecl.Body.AddChild(new Comment( "ILSpy generated this explicit interface implementation from .override directive in " + memberDecl.Name), @@ -463,7 +544,7 @@ namespace ICSharpCode.Decompiler.CSharp yield return methodDecl; } } - + Expression ForwardParameter(ParameterDeclaration p) { switch (p.ParameterModifier) { @@ -475,7 +556,7 @@ namespace ICSharpCode.Decompiler.CSharp return new IdentifierExpression(p.Name); } } - + /// /// Sets new modifier if the member hides some other member from a base type. /// @@ -485,7 +566,7 @@ namespace ICSharpCode.Decompiler.CSharp bool addNewModifier = false; var entity = (IEntity)member.GetSymbol(); var lookup = new MemberLookup(entity.DeclaringTypeDefinition, entity.ParentAssembly); - + var baseTypes = entity.DeclaringType.GetNonInterfaceBaseTypes().Where(t => entity.DeclaringType != t); if (entity is ITypeDefinition) { addNewModifier = baseTypes.SelectMany(b => b.GetNestedTypes(t => t.Name == entity.Name && lookup.IsAccessible(t, true))).Any(); @@ -523,7 +604,7 @@ namespace ICSharpCode.Decompiler.CSharp i++; } } - + EntityDeclaration DoDecompile(ITypeDefinition typeDef, ITypeResolveContext decompilationContext) { Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef); @@ -622,7 +703,7 @@ namespace ICSharpCode.Decompiler.CSharp }; return method; } - + EntityDeclaration DoDecompile(MethodDefinition methodDefinition, IMethod method, ITypeResolveContext decompilationContext) { Debug.Assert(decompilationContext.CurrentMember == method); @@ -661,7 +742,7 @@ namespace ICSharpCode.Decompiler.CSharp i++; } } - + var context = new ILTransformContext(function, specializingTypeSystem, settings) { CancellationToken = CancellationToken }; @@ -773,7 +854,7 @@ namespace ICSharpCode.Decompiler.CSharp SetNewModifier(propertyDecl); return propertyDecl; } - + EntityDeclaration DoDecompile(EventDefinition eventDefinition, IEvent ev, ITypeResolveContext decompilationContext) { Debug.Assert(decompilationContext.CurrentMember == ev); From 1d227eaf6ea347d4aa6010415d80844b6fadd5e0 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 12:36:49 +0100 Subject: [PATCH 81/84] Fix bug in UniversalAssemblyResolver: use current directory as baseDirectory when loading paths without a directory name. --- .../DotNetCore/UniversalAssemblyResolver.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs b/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs index a52bbb2e5..d8f62d5ff 100644 --- a/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs +++ b/ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs @@ -42,7 +42,9 @@ namespace ICSharpCode.Decompiler { this.mainAssemblyFileName = mainAssemblyFileName; this.baseDirectory = Path.GetDirectoryName(mainAssemblyFileName); - + this.throwOnError = throwOnError; + if (string.IsNullOrWhiteSpace(this.baseDirectory)) + this.baseDirectory = Environment.CurrentDirectory; AddSearchDirectory(baseDirectory); } From 4b1488685f6ecbeb553bbc538a7d5076224270ee Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 13:39:06 +0100 Subject: [PATCH 82/84] Add test cases for #888 --- .../ICSharpCode.Decompiler.Tests.csproj | 5 + .../ILPrettyTestRunner.cs | 14 +- .../TestCases/ILPretty/FSharpLoops.fs | 30 + .../TestCases/ILPretty/FSharpLoops_Debug.cs | 209 +++++++ .../TestCases/ILPretty/FSharpLoops_Debug.il | 586 ++++++++++++++++++ .../TestCases/ILPretty/FSharpLoops_Release.cs | 210 +++++++ .../TestCases/ILPretty/FSharpLoops_Release.il | 561 +++++++++++++++++ 7 files changed, 1614 insertions(+), 1 deletion(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops.fs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index cd71918fa..e3c10b410 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -45,6 +45,9 @@ + + + @@ -55,6 +58,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 799ea3924..4afafa3b4 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.Tests { Run(); } - + [Test] public void FSharpUsing_Debug() { @@ -54,6 +54,18 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test, Ignore] + public void FSharpLoops_Debug() + { + Run(); + } + + [Test, Ignore] + public void FSharpLoops_Release() + { + Run(); + } + void Run([CallerMemberName] string testName = null) { var ilFile = Path.Combine(TestCasePath, testName + ".il"); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops.fs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops.fs new file mode 100644 index 000000000..ddb285561 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops.fs @@ -0,0 +1,30 @@ +open System + +let disposable() = { new IDisposable with member x.Dispose() = () } + +let getSeq() = seq { yield 1; } +let getList() = [ 1 ] +let getArray() = [| 1 |] + +[] +let main argv = + + // nested using scopes? + use disp1 = + use disp2 = disposable() + Console.WriteLine "Hello 1" + disposable() + + // for loop over seq + for i in getSeq() do + Console.WriteLine i + + // for loop over list + for i in getList() do + Console.WriteLine i + + // for loop over array + for i in getArray() do + Console.WriteLine i + + 0 // return an integer exit code \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.cs new file mode 100644 index 000000000..72393a233 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.cs @@ -0,0 +1,209 @@ + +// C:\Users\Siegfried\Documents\Visual Studio 2017\Projects\ConsoleApp13\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe +// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null +// Global type: +// Entry point: Program.main +// Architecture: AnyCPU (32-bit preferred) +// Runtime: .NET 4.0 + +using Microsoft.FSharp.Collections; +using Microsoft.FSharp.Core; +using Microsoft.FSharp.Core.CompilerServices; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +[assembly: FSharpInterfaceDataVersion(2, 0, 0)] +[assembly: TargetFramework(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")] +[assembly: AssemblyTitle("ConsoleApplication1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleApplication1")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("e0674ff5-5e8f-4d4e-a88f-e447192454c7")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations)] +[assembly: AssemblyVersion("1.0.0.0")] +[CompilationMapping(SourceConstructFlags.Module)] +public static class Program +{ + [Serializable] + [StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] + [CompilationMapping(SourceConstructFlags.Closure)] + internal sealed class disposable@3 : IDisposable + { + public disposable@3() + { + ((object)this)..ctor(); + } + + private void System-IDisposable-Dispose() + { + } + + void IDisposable.Dispose() + { + //ILSpy generated this explicit interface implementation from .override directive in System-IDisposable-Dispose + this.System-IDisposable-Dispose(); + } + } + + [Serializable] + [StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] + [CompilationMapping(SourceConstructFlags.Closure)] + internal sealed class getSeq@5 : GeneratedSequenceBase + { + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + [CompilerGenerated] + [DebuggerNonUserCode] + public int pc = pc; + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + [CompilerGenerated] + [DebuggerNonUserCode] + public int current = current; + + public getSeq@5(int pc, int current) + { + } + + public override int GenerateNext(ref IEnumerable next) + { + switch (this.pc) + { + default: + this.pc = 1; + this.current = 1; + return 1; + case 1: + this.pc = 2; + break; + case 2: + break; + } + this.current = 0; + return 0; + } + + public override void Close() + { + this.pc = 2; + } + + public override bool get_CheckClose() + { + switch (this.pc) + { + default: + return false; + case 0: + case 2: + return false; + } + } + + [CompilerGenerated] + [DebuggerNonUserCode] + public override int get_LastGenerated() + { + return this.current; + } + + [CompilerGenerated] + [DebuggerNonUserCode] + public override IEnumerator GetFreshEnumerator() + { + return new getSeq@5(0, 0); + } + } + + public static IDisposable disposable() + { + return new disposable@3(); + } + + public static IEnumerable getSeq() + { + return new getSeq@5(0, 0); + } + + public static FSharpList getList() + { + return FSharpList.Cons(1, FSharpList.Empty); + } + + public static int[] getArray() + { + return new int[1] + { + 1 + }; + } + + [EntryPoint] + public static int main(string[] argv) + { + IDisposable disposable = default(IDisposable); + using (Program.disposable()) + { + Console.WriteLine("Hello 1"); + disposable = Program.disposable(); + } + using (disposable) + { + IEnumerable seq = Program.getSeq(); + using (IEnumerator enumerator = seq.GetEnumerator()) + { + while (true) + { + if (!enumerator.MoveNext()) + break; + int k = enumerator.Current; + Console.WriteLine(k); + } + } + FSharpList fSharpList = Program.getList(); + FSharpList tailOrNull = fSharpList.TailOrNull; + while (true) + { + if (tailOrNull == null) + break; + int j = fSharpList.HeadOrDefault; + Console.WriteLine(j); + fSharpList = tailOrNull; + tailOrNull = fSharpList.TailOrNull; + } + int[] array = Program.getArray(); + for (int l = 0; l < array.Length; l++) + { + int i = array[l]; + Console.WriteLine(i); + } + return 0; + } + } +} +namespace +{ + internal static class $Program + { + } + internal static class $AssemblyInfo + { + } +} +namespace .$.NETFramework,Version=v4.6.1 +{ + internal static class AssemblyAttributes + { + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.il new file mode 100644 index 000000000..a3980aa4f --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.il @@ -0,0 +1,586 @@ +// C:\Users\Siegfried\Documents\Visual Studio 2017\Projects\ConsoleApp13\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe + +.assembly extern mscorlib +{ + .publickeytoken = ( + b7 7a 5c 56 19 34 e0 89 + ) + .ver 4:0:0:0 +} +.assembly extern FSharp.Core +{ + .publickeytoken = ( + b0 3f 5f 7f 11 d5 0a 3a + ) + .ver 4:4:1:0 +} +.assembly ConsoleApplication1 +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = ( + 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( + 01 00 1c 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b + 2c 56 65 72 73 69 6f 6e 3d 76 34 2e 36 2e 31 01 + 00 54 0e 14 46 72 61 6d 65 77 6f 72 6b 44 69 73 + 70 6c 61 79 4e 61 6d 65 14 2e 4e 45 54 20 46 72 + 61 6d 65 77 6f 72 6b 20 34 2e 36 2e 31 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( + 01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63 + 61 74 69 6f 6e 31 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( + 01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63 + 61 74 69 6f 6e 31 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( + 01 00 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20 + 20 32 30 31 37 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCultureAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( + 01 00 24 65 30 36 37 34 66 66 35 2d 35 65 38 66 + 2d 34 64 34 65 2d 61 38 38 66 2d 65 34 34 37 31 + 39 32 34 35 34 63 37 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyVersionAttribute::.ctor(string) = ( + 01 00 07 31 2e 30 2e 30 2e 30 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( + 01 00 07 31 2e 30 2e 30 2e 30 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( + 01 00 01 01 00 00 00 00 + ) + .hash algorithm 0x00008004 // SHA1 + .ver 1:0:0:0 +} + +.module ConsoleApplication1.exe +// MVID: {59F64D20-6A1F-D4CE-A745-0383204DF659} +.corflags 0x00020003 // ILOnly, Required32Bit, Preferred32Bit + + +.class private auto ansi '' + extends [mscorlib]System.Object +{ +} // end of class + +.class public auto ansi abstract sealed Program + extends [mscorlib]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 07 00 00 00 00 00 + ) + // Nested Types + .class nested assembly auto auto sealed specialname serializable beforefieldinit disposable@3 + extends [mscorlib]System.Object + implements [mscorlib]System.IDisposable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 06 00 00 00 00 00 + ) + // Methods + .method public specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x21c8 + // Code size 9 (0x9) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } // end of method disposable@3::.ctor + + .method private final hidebysig newslot virtual + instance void 'System-IDisposable-Dispose' () cil managed + { + .override method instance void [mscorlib]System.IDisposable::Dispose() + // Method begins at RVA 0x21d4 + // Code size 1 (0x1) + .maxstack 8 + + IL_0000: ret + } // end of method disposable@3::'System-IDisposable-Dispose' + + } // end of class disposable@3 + + .class nested assembly auto auto sealed specialname serializable beforefieldinit getSeq@5 + extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 06 00 00 00 00 00 + ) + // Fields + .field public int32 pc + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( + 01 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + .field public int32 current + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( + 01 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + + // Methods + .method public specialname rtspecialname + instance void .ctor ( + int32 pc, + int32 current + ) cil managed + { + // Method begins at RVA 0x21d8 + // Code size 21 (0x15) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Program/getSeq@5::pc + IL_0007: ldarg.0 + IL_0008: ldarg.2 + IL_0009: stfld int32 Program/getSeq@5::current + IL_000e: ldarg.0 + IL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() + IL_0014: ret + } // end of method getSeq@5::.ctor + + .method public strict virtual + instance int32 GenerateNext ( + class [mscorlib]System.Collections.Generic.IEnumerable`1& next + ) cil managed + { + // Method begins at RVA 0x21f0 + // Code size 66 (0x42) + .maxstack 6 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::pc + IL_0006: ldc.i4.1 + IL_0007: sub + IL_0008: switch (IL_0017, IL_0019) + + IL_0015: br.s IL_0021 + + IL_0017: br.s IL_001b + + IL_0019: br.s IL_001e + + IL_001b: nop + IL_001c: br.s IL_0032 + + IL_001e: nop + IL_001f: br.s IL_0039 + + IL_0021: nop + IL_0022: ldarg.0 + IL_0023: ldc.i4.1 + IL_0024: stfld int32 Program/getSeq@5::pc + IL_0029: ldarg.0 + IL_002a: ldc.i4.1 + IL_002b: stfld int32 Program/getSeq@5::current + IL_0030: ldc.i4.1 + IL_0031: ret + + IL_0032: ldarg.0 + IL_0033: ldc.i4.2 + IL_0034: stfld int32 Program/getSeq@5::pc + + IL_0039: ldarg.0 + IL_003a: ldc.i4.0 + IL_003b: stfld int32 Program/getSeq@5::current + IL_0040: ldc.i4.0 + IL_0041: ret + } // end of method getSeq@5::GenerateNext + + .method public strict virtual + instance void Close () cil managed + { + // Method begins at RVA 0x2240 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldc.i4.2 + IL_0002: stfld int32 Program/getSeq@5::pc + IL_0007: ret + } // end of method getSeq@5::Close + + .method public strict virtual + instance bool get_CheckClose () cil managed + { + // Method begins at RVA 0x224c + // Code size 45 (0x2d) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::pc + IL_0006: switch (IL_0019, IL_001b, IL_001d) + + IL_0017: br.s IL_0028 + + IL_0019: br.s IL_001f + + IL_001b: br.s IL_0022 + + IL_001d: br.s IL_0025 + + IL_001f: nop + IL_0020: br.s IL_002b + + IL_0022: nop + IL_0023: br.s IL_0029 + + IL_0025: nop + IL_0026: br.s IL_002b + + IL_0028: nop + + IL_0029: ldc.i4.0 + IL_002a: ret + + IL_002b: ldc.i4.0 + IL_002c: ret + } // end of method getSeq@5::get_CheckClose + + .method public strict virtual + instance int32 get_LastGenerated () cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x227c + // Code size 7 (0x7) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::current + IL_0006: ret + } // end of method getSeq@5::get_LastGenerated + + .method public strict virtual + instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator () cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2284 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32) + IL_0007: ret + } // end of method getSeq@5::GetFreshEnumerator + + } // end of class getSeq@5 + + + // Methods + .method public static + class [mscorlib]System.IDisposable disposable () cil managed + { + // Method begins at RVA 0x2050 + // Code size 6 (0x6) + .maxstack 8 + + IL_0000: newobj instance void Program/disposable@3::.ctor() + IL_0005: ret + } // end of method Program::disposable + + .method public static + class [mscorlib]System.Collections.Generic.IEnumerable`1 getSeq () cil managed + { + // Method begins at RVA 0x2058 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32) + IL_0007: ret + } // end of method Program::getSeq + + .method public static + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 getList () cil managed + { + // Method begins at RVA 0x2064 + // Code size 12 (0xc) + .maxstack 8 + + IL_0000: ldc.i4.1 + IL_0001: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0006: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_000b: ret + } // end of method Program::getList + + .method public static + int32[] getArray () cil managed + { + // Method begins at RVA 0x2074 + // Code size 15 (0xf) + .maxstack 8 + + IL_0000: ldc.i4.1 + IL_0001: newarr [mscorlib]System.Int32 + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: stelem.any [mscorlib]System.Int32 + IL_000e: ret + } // end of method Program::getArray + + .method public static + int32 main ( + string[] argv + ) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2084 + // Code size 270 (0x10e) + .maxstack 4 + .entrypoint + .locals init ( + [0] class [mscorlib]System.IDisposable, + [1] class [mscorlib]System.IDisposable, + [2] class [mscorlib]System.IDisposable, + [3] class [mscorlib]System.IDisposable, + [4] int32, + [5] class [mscorlib]System.Collections.Generic.IEnumerable`1, + [6] class [mscorlib]System.Collections.Generic.IEnumerator`1, + [7] class [FSharp.Core]Microsoft.FSharp.Core.Unit, + [8] int32, + [9] class [mscorlib]System.IDisposable, + [10] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + [11] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + [12] int32, + [13] int32[], + [14] int32, + [15] int32, + [16] class [mscorlib]System.IDisposable + ) + + IL_0000: call class [mscorlib]System.IDisposable Program::disposable() + IL_0005: stloc.1 + .try + { + IL_0006: ldstr "Hello 1" + IL_000b: call void [mscorlib]System.Console::WriteLine(string) + IL_0010: call class [mscorlib]System.IDisposable Program::disposable() + IL_0015: stloc.2 + IL_0016: leave.s IL_0032 + } // end .try + finally + { + IL_0018: ldloc.1 + IL_0019: isinst [mscorlib]System.IDisposable + IL_001e: stloc.3 + IL_001f: ldloc.3 + IL_0020: brfalse.s IL_0024 + + IL_0022: br.s IL_0026 + + IL_0024: br.s IL_002f + + IL_0026: ldloc.3 + IL_0027: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002c: ldnull + IL_002d: pop + IL_002e: endfinally + + IL_002f: ldnull + IL_0030: pop + IL_0031: endfinally + } // end handler + + IL_0032: ldloc.2 + IL_0033: stloc.0 + .try + { + IL_0034: call class [mscorlib]System.Collections.Generic.IEnumerable`1 Program::getSeq() + IL_0039: stloc.s 5 + IL_003b: ldloc.s 5 + IL_003d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0042: stloc.s 6 + .try + { + // loop start (head: IL_0044) + IL_0044: ldloc.s 6 + IL_0046: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_004b: brfalse.s IL_0060 + + IL_004d: ldloc.s 6 + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.s 8 + IL_0056: ldloc.s 8 + IL_0058: call void [mscorlib]System.Console::WriteLine(int32) + IL_005d: nop + IL_005e: br.s IL_0044 + // end loop + + IL_0060: ldnull + IL_0061: stloc.s 7 + IL_0063: leave.s IL_0083 + } // end .try + finally + { + IL_0065: ldloc.s 6 + IL_0067: isinst [mscorlib]System.IDisposable + IL_006c: stloc.s 9 + IL_006e: ldloc.s 9 + IL_0070: brfalse.s IL_0074 + + IL_0072: br.s IL_0076 + + IL_0074: br.s IL_0080 + + IL_0076: ldloc.s 9 + IL_0078: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_007d: ldnull + IL_007e: pop + IL_007f: endfinally + + IL_0080: ldnull + IL_0081: pop + IL_0082: endfinally + } // end handler + + IL_0083: ldloc.s 7 + IL_0085: pop + IL_0086: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Program::getList() + IL_008b: stloc.s 10 + IL_008d: ldloc.s 10 + IL_008f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0094: stloc.s 11 + // loop start (head: IL_0096) + IL_0096: ldloc.s 11 + IL_0098: ldnull + IL_0099: cgt.un + IL_009b: brfalse.s IL_00bd + + IL_009d: ldloc.s 10 + IL_009f: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_00a4: stloc.s 12 + IL_00a6: ldloc.s 12 + IL_00a8: call void [mscorlib]System.Console::WriteLine(int32) + IL_00ad: ldloc.s 11 + IL_00af: stloc.s 10 + IL_00b1: ldloc.s 10 + IL_00b3: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00b8: stloc.s 11 + IL_00ba: nop + IL_00bb: br.s IL_0096 + // end loop + + IL_00bd: call int32[] Program::getArray() + IL_00c2: stloc.s 13 + IL_00c4: ldc.i4.0 + IL_00c5: stloc.s 14 + IL_00c7: br.s IL_00e1 + // loop start (head: IL_00e1) + IL_00c9: ldloc.s 13 + IL_00cb: ldloc.s 14 + IL_00cd: ldelem.any [mscorlib]System.Int32 + IL_00d2: stloc.s 15 + IL_00d4: ldloc.s 15 + IL_00d6: call void [mscorlib]System.Console::WriteLine(int32) + IL_00db: ldloc.s 14 + IL_00dd: ldc.i4.1 + IL_00de: add + IL_00df: stloc.s 14 + + IL_00e1: ldloc.s 14 + IL_00e3: ldloc.s 13 + IL_00e5: ldlen + IL_00e6: conv.i4 + IL_00e7: blt.s IL_00c9 + // end loop + + IL_00e9: ldc.i4.0 + IL_00ea: stloc.s 4 + IL_00ec: leave.s IL_010b + } // end .try + finally + { + IL_00ee: ldloc.0 + IL_00ef: isinst [mscorlib]System.IDisposable + IL_00f4: stloc.s 16 + IL_00f6: ldloc.s 16 + IL_00f8: brfalse.s IL_00fc + + IL_00fa: br.s IL_00fe + + IL_00fc: br.s IL_0108 + + IL_00fe: ldloc.s 16 + IL_0100: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0105: ldnull + IL_0106: pop + IL_0107: endfinally + + IL_0108: ldnull + IL_0109: pop + IL_010a: endfinally + } // end handler + + IL_010b: ldloc.s 4 + IL_010d: ret + } // end of method Program::main + +} // end of class Program + +.class private auto ansi abstract sealed '.$Program' + extends [mscorlib]System.Object +{ +} // end of class .$Program + +.class private auto ansi abstract sealed '.$AssemblyInfo' + extends [mscorlib]System.Object +{ +} // end of class .$AssemblyInfo + +.class private auto ansi abstract sealed '.$.NETFramework,Version=v4.6.1.AssemblyAttributes' + extends [mscorlib]System.Object +{ +} // end of class .$.NETFramework,Version=v4.6.1.AssemblyAttributes + diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.cs new file mode 100644 index 000000000..d64bda08b --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.cs @@ -0,0 +1,210 @@ + +// C:\Users\Siegfried\Documents\Visual Studio 2017\Projects\ConsoleApp13\ConsoleApplication1\bin\Release\ConsoleApplication1.exe +// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null +// Global type: +// Entry point: Program.main +// Architecture: AnyCPU (32-bit preferred) +// Runtime: .NET 4.0 + +using Microsoft.FSharp.Collections; +using Microsoft.FSharp.Core; +using Microsoft.FSharp.Core.CompilerServices; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +[assembly: FSharpInterfaceDataVersion(2, 0, 0)] +[assembly: TargetFramework(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")] +[assembly: AssemblyTitle("ConsoleApplication1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleApplication1")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("e0674ff5-5e8f-4d4e-a88f-e447192454c7")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.None)] +[assembly: AssemblyVersion("1.0.0.0")] +[CompilationMapping(SourceConstructFlags.Module)] +public static class Program +{ + [Serializable] + [StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] + [CompilationMapping(SourceConstructFlags.Closure)] + internal sealed class disposable@3 : IDisposable + { + public disposable@3() + { + ((object)this)..ctor(); + } + + private void System-IDisposable-Dispose() + { + } + + void IDisposable.Dispose() + { + //ILSpy generated this explicit interface implementation from .override directive in System-IDisposable-Dispose + this.System-IDisposable-Dispose(); + } + } + + [Serializable] + [StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] + [CompilationMapping(SourceConstructFlags.Closure)] + internal sealed class getSeq@5 : GeneratedSequenceBase + { + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + [CompilerGenerated] + [DebuggerNonUserCode] + public int pc = pc; + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + [CompilerGenerated] + [DebuggerNonUserCode] + public int current = current; + + public getSeq@5(int pc, int current) + { + } + + public override int GenerateNext(ref IEnumerable next) + { + switch (this.pc) + { + default: + this.pc = 1; + this.current = 1; + return 1; + case 1: + this.pc = 2; + break; + case 2: + break; + } + this.current = 0; + return 0; + } + + public override void Close() + { + this.pc = 2; + } + + public override bool get_CheckClose() + { + switch (this.pc) + { + default: + return false; + case 0: + case 2: + return false; + } + } + + [CompilerGenerated] + [DebuggerNonUserCode] + public override int get_LastGenerated() + { + return this.current; + } + + [CompilerGenerated] + [DebuggerNonUserCode] + public override IEnumerator GetFreshEnumerator() + { + return new getSeq@5(0, 0); + } + } + + public static IDisposable disposable() + { + return new disposable@3(); + } + + public static IEnumerable getSeq() + { + return new getSeq@5(0, 0); + } + + public static FSharpList getList() + { + return FSharpList.Cons(1, FSharpList.Empty); + } + + public static int[] getArray() + { + return new int[1] + { + 1 + }; + } + + [EntryPoint] + public static int main(string[] argv) + { + IDisposable disposable = default(IDisposable); + using (Program.disposable()) + { + Console.WriteLine("Hello 1"); + disposable = Program.disposable(); + } + using (disposable) + { + IEnumerable seq = Program.getSeq(); + using (IEnumerator enumerator = seq.GetEnumerator()) + { + while (true) + { + if (!enumerator.MoveNext()) + break; + Console.WriteLine(enumerator.Current); + } + } + FSharpList fSharpList = FSharpList.Cons(1, FSharpList.Empty); + FSharpList tailOrNull = fSharpList.TailOrNull; + while (true) + { + if (tailOrNull == null) + break; + int j = fSharpList.HeadOrDefault; + Console.WriteLine(j); + fSharpList = tailOrNull; + tailOrNull = fSharpList.TailOrNull; + } + int[] array = new int[1] + { + 1 + }; + for (int j = 0; j < array.Length; j++) + { + Console.WriteLine(array[j]); + } + return 0; + } + } +} +namespace +{ + internal static class $Program + { + } + internal static class $AssemblyInfo + { + } +} +namespace .$.NETFramework,Version=v4.6.1 +{ + internal static class AssemblyAttributes + { + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.il new file mode 100644 index 000000000..5df4fe852 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.il @@ -0,0 +1,561 @@ +// C:\Users\Siegfried\Documents\Visual Studio 2017\Projects\ConsoleApp13\ConsoleApplication1\bin\Release\ConsoleApplication1.exe + +.assembly extern mscorlib +{ + .publickeytoken = ( + b7 7a 5c 56 19 34 e0 89 + ) + .ver 4:0:0:0 +} +.assembly extern FSharp.Core +{ + .publickeytoken = ( + b0 3f 5f 7f 11 d5 0a 3a + ) + .ver 4:4:1:0 +} +.assembly ConsoleApplication1 +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = ( + 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( + 01 00 1c 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b + 2c 56 65 72 73 69 6f 6e 3d 76 34 2e 36 2e 31 01 + 00 54 0e 14 46 72 61 6d 65 77 6f 72 6b 44 69 73 + 70 6c 61 79 4e 61 6d 65 14 2e 4e 45 54 20 46 72 + 61 6d 65 77 6f 72 6b 20 34 2e 36 2e 31 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( + 01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63 + 61 74 69 6f 6e 31 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( + 01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63 + 61 74 69 6f 6e 31 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( + 01 00 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20 + 20 32 30 31 37 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyCultureAttribute::.ctor(string) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( + 01 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( + 01 00 24 65 30 36 37 34 66 66 35 2d 35 65 38 66 + 2d 34 64 34 65 2d 61 38 38 66 2d 65 34 34 37 31 + 39 32 34 35 34 63 37 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyVersionAttribute::.ctor(string) = ( + 01 00 07 31 2e 30 2e 30 2e 30 00 00 + ) + .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( + 01 00 07 31 2e 30 2e 30 2e 30 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( + 01 00 00 00 00 00 00 00 + ) + .hash algorithm 0x00008004 // SHA1 + .ver 1:0:0:0 +} + +.module ConsoleApplication1.exe +// MVID: {59F64D28-6A1F-D4CE-A745-0383284DF659} +.corflags 0x00020003 // ILOnly, Required32Bit, Preferred32Bit + + +.class private auto ansi '' + extends [mscorlib]System.Object +{ +} // end of class + +.class public auto ansi abstract sealed Program + extends [mscorlib]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 07 00 00 00 00 00 + ) + // Nested Types + .class nested assembly auto auto sealed specialname serializable beforefieldinit disposable@3 + extends [mscorlib]System.Object + implements [mscorlib]System.IDisposable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 06 00 00 00 00 00 + ) + // Methods + .method public specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x21bc + // Code size 9 (0x9) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } // end of method disposable@3::.ctor + + .method private final hidebysig newslot virtual + instance void 'System-IDisposable-Dispose' () cil managed + { + .override method instance void [mscorlib]System.IDisposable::Dispose() + // Method begins at RVA 0x21c8 + // Code size 1 (0x1) + .maxstack 8 + + IL_0000: ret + } // end of method disposable@3::'System-IDisposable-Dispose' + + } // end of class disposable@3 + + .class nested assembly auto auto sealed specialname serializable beforefieldinit getSeq@5 + extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( + 01 00 06 00 00 00 00 00 + ) + // Fields + .field public int32 pc + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( + 01 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + .field public int32 current + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( + 01 00 00 00 00 00 00 00 + ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + + // Methods + .method public specialname rtspecialname + instance void .ctor ( + int32 pc, + int32 current + ) cil managed + { + // Method begins at RVA 0x21cc + // Code size 21 (0x15) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 Program/getSeq@5::pc + IL_0007: ldarg.0 + IL_0008: ldarg.2 + IL_0009: stfld int32 Program/getSeq@5::current + IL_000e: ldarg.0 + IL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() + IL_0014: ret + } // end of method getSeq@5::.ctor + + .method public strict virtual + instance int32 GenerateNext ( + class [mscorlib]System.Collections.Generic.IEnumerable`1& next + ) cil managed + { + // Method begins at RVA 0x21e4 + // Code size 62 (0x3e) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::pc + IL_0006: ldc.i4.1 + IL_0007: sub + IL_0008: switch (IL_0018, IL_001b) + + IL_0015: nop + IL_0016: br.s IL_001e + + IL_0018: nop + IL_0019: br.s IL_002e + + IL_001b: nop + IL_001c: br.s IL_0035 + + IL_001e: ldarg.0 + IL_001f: ldc.i4.1 + IL_0020: stfld int32 Program/getSeq@5::pc + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 Program/getSeq@5::current + IL_002c: ldc.i4.1 + IL_002d: ret + + IL_002e: ldarg.0 + IL_002f: ldc.i4.2 + IL_0030: stfld int32 Program/getSeq@5::pc + + IL_0035: ldarg.0 + IL_0036: ldc.i4.0 + IL_0037: stfld int32 Program/getSeq@5::current + IL_003c: ldc.i4.0 + IL_003d: ret + } // end of method getSeq@5::GenerateNext + + .method public strict virtual + instance void Close () cil managed + { + // Method begins at RVA 0x2224 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldc.i4.2 + IL_0002: stfld int32 Program/getSeq@5::pc + IL_0007: ret + } // end of method getSeq@5::Close + + .method public strict virtual + instance bool get_CheckClose () cil managed + { + // Method begins at RVA 0x2230 + // Code size 39 (0x27) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::pc + IL_0006: switch (IL_001a, IL_001d, IL_0020) + + IL_0017: nop + IL_0018: br.s IL_0023 + + IL_001a: nop + IL_001b: br.s IL_0025 + + IL_001d: nop + IL_001e: br.s IL_0023 + + IL_0020: nop + IL_0021: br.s IL_0025 + + IL_0023: ldc.i4.0 + IL_0024: ret + + IL_0025: ldc.i4.0 + IL_0026: ret + } // end of method getSeq@5::get_CheckClose + + .method public strict virtual + instance int32 get_LastGenerated () cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2258 + // Code size 7 (0x7) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/getSeq@5::current + IL_0006: ret + } // end of method getSeq@5::get_LastGenerated + + .method public strict virtual + instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator () cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2260 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32) + IL_0007: ret + } // end of method getSeq@5::GetFreshEnumerator + + } // end of class getSeq@5 + + + // Methods + .method public static + class [mscorlib]System.IDisposable disposable () cil managed + { + // Method begins at RVA 0x2050 + // Code size 6 (0x6) + .maxstack 8 + + IL_0000: newobj instance void Program/disposable@3::.ctor() + IL_0005: ret + } // end of method Program::disposable + + .method public static + class [mscorlib]System.Collections.Generic.IEnumerable`1 getSeq () cil managed + { + // Method begins at RVA 0x2058 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32) + IL_0007: ret + } // end of method Program::getSeq + + .method public static + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 getList () cil managed + { + // Method begins at RVA 0x2064 + // Code size 12 (0xc) + .maxstack 8 + + IL_0000: ldc.i4.1 + IL_0001: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0006: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_000b: ret + } // end of method Program::getList + + .method public static + int32[] getArray () cil managed + { + // Method begins at RVA 0x2074 + // Code size 15 (0xf) + .maxstack 8 + + IL_0000: ldc.i4.1 + IL_0001: newarr [mscorlib]System.Int32 + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: stelem.any [mscorlib]System.Int32 + IL_000e: ret + } // end of method Program::getArray + + .method public static + int32 main ( + string[] argv + ) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( + 01 00 00 00 + ) + // Method begins at RVA 0x2084 + // Code size 259 (0x103) + .maxstack 6 + .entrypoint + .locals init ( + [0] class [mscorlib]System.IDisposable, + [1] class [mscorlib]System.IDisposable, + [2] class [mscorlib]System.IDisposable, + [3] class [mscorlib]System.IDisposable, + [4] int32, + [5] class [mscorlib]System.Collections.Generic.IEnumerable`1, + [6] class [mscorlib]System.Collections.Generic.IEnumerator`1, + [7] class [FSharp.Core]Microsoft.FSharp.Core.Unit, + [8] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + [9] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + [10] int32, + [11] int32[] + ) + + IL_0000: call class [mscorlib]System.IDisposable Program::disposable() + IL_0005: stloc.1 + .try + { + IL_0006: ldstr "Hello 1" + IL_000b: call void [mscorlib]System.Console::WriteLine(string) + IL_0010: call class [mscorlib]System.IDisposable Program::disposable() + IL_0015: stloc.2 + IL_0016: leave.s IL_002e + } // end .try + finally + { + IL_0018: ldloc.1 + IL_0019: isinst [mscorlib]System.IDisposable + IL_001e: stloc.3 + IL_001f: ldloc.3 + IL_0020: brfalse.s IL_002b + + IL_0022: ldloc.3 + IL_0023: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0028: ldnull + IL_0029: pop + IL_002a: endfinally + + IL_002b: ldnull + IL_002c: pop + IL_002d: endfinally + } // end handler + + IL_002e: ldloc.2 + IL_002f: stloc.0 + .try + { + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 Program::getSeq() + IL_0035: stloc.s 5 + IL_0037: ldloc.s 5 + IL_0039: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003e: stloc.s 6 + .try + { + // loop start (head: IL_0040) + IL_0040: ldloc.s 6 + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_0058 + + IL_0049: ldloc.s 6 + IL_004b: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0050: call void [mscorlib]System.Console::WriteLine(int32) + IL_0055: nop + IL_0056: br.s IL_0040 + // end loop + + IL_0058: ldnull + IL_0059: stloc.s 7 + IL_005b: leave.s IL_0074 + } // end .try + finally + { + IL_005d: ldloc.s 6 + IL_005f: isinst [mscorlib]System.IDisposable + IL_0064: stloc.1 + IL_0065: ldloc.1 + IL_0066: brfalse.s IL_0071 + + IL_0068: ldloc.1 + IL_0069: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_006e: ldnull + IL_006f: pop + IL_0070: endfinally + + IL_0071: ldnull + IL_0072: pop + IL_0073: endfinally + } // end handler + + IL_0074: ldloc.s 7 + IL_0076: pop + IL_0077: ldc.i4.1 + IL_0078: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_007d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0082: stloc.s 8 + IL_0084: ldloc.s 8 + IL_0086: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_008b: stloc.s 9 + // loop start (head: IL_008d) + IL_008d: ldloc.s 9 + IL_008f: ldnull + IL_0090: cgt.un + IL_0092: brfalse.s IL_00b4 + + IL_0094: ldloc.s 8 + IL_0096: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_009b: stloc.s 10 + IL_009d: ldloc.s 10 + IL_009f: call void [mscorlib]System.Console::WriteLine(int32) + IL_00a4: ldloc.s 9 + IL_00a6: stloc.s 8 + IL_00a8: ldloc.s 8 + IL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00af: stloc.s 9 + IL_00b1: nop + IL_00b2: br.s IL_008d + // end loop + + IL_00b4: ldc.i4.1 + IL_00b5: newarr [mscorlib]System.Int32 + IL_00ba: dup + IL_00bb: ldc.i4.0 + IL_00bc: ldc.i4.1 + IL_00bd: stelem.any [mscorlib]System.Int32 + IL_00c2: stloc.s 11 + IL_00c4: ldc.i4.0 + IL_00c5: stloc.s 10 + IL_00c7: br.s IL_00dd + // loop start (head: IL_00dd) + IL_00c9: ldloc.s 11 + IL_00cb: ldloc.s 10 + IL_00cd: ldelem.any [mscorlib]System.Int32 + IL_00d2: call void [mscorlib]System.Console::WriteLine(int32) + IL_00d7: ldloc.s 10 + IL_00d9: ldc.i4.1 + IL_00da: add + IL_00db: stloc.s 10 + + IL_00dd: ldloc.s 10 + IL_00df: ldloc.s 11 + IL_00e1: ldlen + IL_00e2: conv.i4 + IL_00e3: blt.s IL_00c9 + // end loop + + IL_00e5: ldc.i4.0 + IL_00e6: stloc.s 4 + IL_00e8: leave.s IL_0100 + } // end .try + finally + { + IL_00ea: ldloc.0 + IL_00eb: isinst [mscorlib]System.IDisposable + IL_00f0: stloc.1 + IL_00f1: ldloc.1 + IL_00f2: brfalse.s IL_00fd + + IL_00f4: ldloc.1 + IL_00f5: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_00fa: ldnull + IL_00fb: pop + IL_00fc: endfinally + + IL_00fd: ldnull + IL_00fe: pop + IL_00ff: endfinally + } // end handler + + IL_0100: ldloc.s 4 + IL_0102: ret + } // end of method Program::main + +} // end of class Program + +.class private auto ansi abstract sealed '.$Program' + extends [mscorlib]System.Object +{ +} // end of class .$Program + +.class private auto ansi abstract sealed '.$AssemblyInfo' + extends [mscorlib]System.Object +{ +} // end of class .$AssemblyInfo + +.class private auto ansi abstract sealed '.$.NETFramework,Version=v4.6.1.AssemblyAttributes' + extends [mscorlib]System.Object +{ +} // end of class .$.NETFramework,Version=v4.6.1.AssemblyAttributes + From 63b0a799707076adf91febf8a11589f3c64ce915 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 20:28:12 +0100 Subject: [PATCH 83/84] OpenListDialog: Add confirmation message on Delete --- ILSpy/OpenListDialog.xaml | 2 +- ILSpy/OpenListDialog.xaml.cs | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ILSpy/OpenListDialog.xaml b/ILSpy/OpenListDialog.xaml index 8428df3fa..a38f9c9d7 100644 --- a/ILSpy/OpenListDialog.xaml +++ b/ILSpy/OpenListDialog.xaml @@ -34,7 +34,7 @@ - + diff --git a/ILSpy/OpenListDialog.xaml.cs b/ILSpy/OpenListDialog.xaml.cs index 414b44adc..830db59d6 100644 --- a/ILSpy/OpenListDialog.xaml.cs +++ b/ILSpy/OpenListDialog.xaml.cs @@ -20,6 +20,7 @@ using System.Windows; using System.Windows.Controls; using Mono.Cecil; using System.Windows.Input; +using System; namespace ICSharpCode.ILSpy { @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { okButton.IsEnabled = listView.SelectedItem != null; - removeButton.IsEnabled = listView.SelectedItem != null; + deleteButton.IsEnabled = listView.SelectedItem != null; } void OKButton_Click(object sender, RoutedEventArgs e) @@ -174,10 +175,14 @@ namespace ICSharpCode.ILSpy } } - private void RemoveButton_Click(object sender, RoutedEventArgs e) + private void DeleteButton_Click(object sender, RoutedEventArgs e) { - if (listView.SelectedItem != null) - manager.DeleteList(listView.SelectedItem.ToString()); + if (listView.SelectedItem == null) + return; + if (MessageBox.Show(this, "Are you sure that you want to delete the selected assembly list?", +"ILSpy", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No, MessageBoxOptions.None) != MessageBoxResult.Yes) + return; + manager.DeleteList(listView.SelectedItem.ToString()); } private void ResetButton_Click(object sender, RoutedEventArgs e) From c3ff2ce63c7eed2dc185857cfa3ae99af70a5fb1 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 30 Oct 2017 21:01:54 +0100 Subject: [PATCH 84/84] Fix #577: Improve the display of namespaces and nested classes --- .../CSharp/CSharpDecompiler.cs | 45 +++++++++++++++---- ILSpy/TreeNodes/TypeTreeNode.cs | 4 -- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index bbba077c3..6fa460d11 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -934,13 +934,31 @@ namespace ICSharpCode.Decompiler.CSharp } else if (type is GenericParameter) { return new SimpleType(type.Name); } else if (type.IsNested) { - AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions); string namepart = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name); - MemberType memberType = new MemberType { Target = typeRef, MemberName = namepart }; - memberType.AddAnnotation(type); - if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { - AddTypeParameterDefininitionsTo(type, memberType); + AstType memberType; + if ((options & (ConvertTypeOptions.IncludeOuterTypeName | ConvertTypeOptions.IncludeNamespace)) != 0) { + AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions); + memberType = new MemberType { Target = typeRef, MemberName = namepart }; + if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { + AddTypeParameterDefininitionsTo(type, memberType); + } + } else { + memberType = new SimpleType(namepart); + if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { + if (type.HasGenericParameters) { + List typeArguments = new List(); + foreach (GenericParameter gp in type.GenericParameters) { + typeArguments.Add(new SimpleType(gp.Name)); + } + ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out int typeParameterCount); + if (typeParameterCount > typeArguments.Count) + typeParameterCount = typeArguments.Count; + ((SimpleType)memberType).TypeArguments.AddRange(typeArguments.GetRange(typeArguments.Count - typeParameterCount, typeParameterCount)); + typeArguments.RemoveRange(typeArguments.Count - typeParameterCount, typeParameterCount); + } + } } + memberType.AddAnnotation(type); return memberType; } else { string ns = type.Namespace ?? string.Empty; @@ -1029,14 +1047,22 @@ namespace ICSharpCode.Decompiler.CSharp { SimpleType st = baseType as SimpleType; if (st != null) { - st.TypeArguments.AddRange(typeArguments); + TypeReference type = st.Annotation(); + if (type != null) { + ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out int typeParameterCount); + if (typeParameterCount > typeArguments.Count) + typeParameterCount = typeArguments.Count; + st.TypeArguments.AddRange(typeArguments.GetRange(typeArguments.Count - typeParameterCount, typeParameterCount)); + } else { + st.TypeArguments.AddRange(typeArguments); + + } } MemberType mt = baseType as MemberType; if (mt != null) { TypeReference type = mt.Annotation(); if (type != null) { - int typeParameterCount; - ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount); + ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out int typeParameterCount); if (typeParameterCount > typeArguments.Count) typeParameterCount = typeArguments.Count; mt.TypeArguments.AddRange(typeArguments.GetRange(typeArguments.Count - typeParameterCount, typeParameterCount)); @@ -1090,6 +1116,7 @@ namespace ICSharpCode.Decompiler.CSharp None = 0, IncludeNamespace = 1, IncludeTypeParameterDefinitions = 2, - DoNotUsePrimitiveTypeNames = 4 + DoNotUsePrimitiveTypeNames = 4, + IncludeOuterTypeName = 8, } } diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index e57fd06be..5f51b0de4 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -44,10 +44,6 @@ namespace ICSharpCode.ILSpy.TreeNodes public AssemblyTreeNode ParentAssemblyNode { get; } - public string Name => TypeDefinition.Name; - - public string Namespace => TypeDefinition.Namespace; - public override object Text => HighlightSearchMatch(this.Language.FormatTypeName(TypeDefinition), TypeDefinition.MetadataToken.ToSuffixString()); public override bool IsPublicAPI {