From 5388a18c4622bec4936d17569027172cbd037488 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Sun, 29 Sep 2019 12:14:29 +0200 Subject: [PATCH 01/15] Remove old hacks for decompiler csproj --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 6 ++---- global.json | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 9f2c10d1b..fe8e13487 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -1,6 +1,5 @@  - - + netstandard2.0 @@ -620,12 +619,11 @@ - - powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration) + \ No newline at end of file diff --git a/global.json b/global.json index 6ba836210..6e5ed6274 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "msbuild-sdks": { - "MSBuild.Sdk.Extras": "2.0.24" + "MSBuild.Sdk.Extras": "2.0.54" }, "sdk": { "version": "3.0.100" From 7de25bc4b59c84f39ec17e7c848ed81ccbfe98e1 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Sun, 29 Sep 2019 12:22:22 +0200 Subject: [PATCH 02/15] Change target name to using BeforeTargets --- ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index fe8e13487..cd5bc932b 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -619,7 +619,7 @@ - + powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration) From 80cb24d1802c2acea0f308d66a68266ba9d33b6b Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 30 Sep 2019 21:34:03 +0200 Subject: [PATCH 03/15] Fix #1709: NullPropagationTransform.IsGetter on generic types --- .../TestCases/Pretty/NullPropagation.cs | 7 +++++++ ICSharpCode.Decompiler/CSharp/StatementBuilder.cs | 2 +- .../IL/Transforms/NullPropagationTransform.cs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs index 98b5df626..5886234e1 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs @@ -17,6 +17,8 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections; +using System.Collections.Generic; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { @@ -258,6 +260,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return t?.Int(); } + public int? Issue1709(object obj) + { + return (obj as ICollection)?.Count + (obj as ICollection)?.Count; + } + private static dynamic DynamicNullProp(dynamic a) { return a?.b.c(1)?.d[10]; diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 06ea73131..8cb202b61 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -791,7 +791,7 @@ namespace ICSharpCode.Decompiler.CSharp bool ParentIsCurrentGetter(ILInstruction inst) { return inst.Parent is CallInstruction cv && cv.Method.IsAccessor && - cv.Method.AccessorOwner is IProperty p && p.Getter.Equals(cv.Method); + cv.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter; } #endregion diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs index 90d41d06d..a30ebcab9 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs @@ -272,7 +272,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms static bool IsGetter(IMethod method) { - return method.AccessorOwner is IProperty p && p.Getter == method; + return method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter; } private void IntroduceUnwrap(ILVariable testedVar, ILInstruction varLoad, Mode mode) From d65b109fbcc311043f4c3183d86bc1a615843cc6 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 30 Sep 2019 21:48:16 +0200 Subject: [PATCH 04/15] Fix #1689: Add support for null propagation on array access: `arr?[i]` --- .../TestCases/Pretty/NullPropagation.cs | 8 +++++++- .../IL/Transforms/NullPropagationTransform.cs | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs index 5886234e1..6d2191833 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs @@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { Use(GetMyClass()?.Text ?? "Hello"); } - + public void CallOnValueTypeField() { Use(GetMyClass()?.IntVal.ToString()); @@ -265,6 +265,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return (obj as ICollection)?.Count + (obj as ICollection)?.Count; } + private static void Issue1689(List setsOfNumbers) + { + Console.WriteLine(setsOfNumbers?[0]?[1].ToString() == "2"); + Console.WriteLine(setsOfNumbers?[1]?[1].ToString() == null); + } + private static dynamic DynamicNullProp(dynamic a) { return a?.b.c(1)?.d[10]; diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs index a30ebcab9..b8da2c416 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs @@ -18,6 +18,7 @@ using System; using System.Diagnostics; +using System.Linq; using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL.Transforms @@ -211,6 +212,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms return false; } else if (inst is LdLen ldLen) { inst = ldLen.Array; + } else if (inst is LdElema ldElema) { + inst = ldElema.Array; + // ensure the access chain does not contain any 'nullable.unwrap' that aren't directly part of the chain + if (ldElema.Indices.Any(i => i.HasFlag(InstructionFlags.MayUnwrapNull))) + return false; } else if (inst is NullableUnwrap unwrap) { inst = unwrap.Argument; if (unwrap.RefInput && inst is AddressOf addressOf) { From 6bd12413ae4faad4066928e34dd99ac7435d41a7 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Tue, 27 Aug 2019 21:42:03 +0200 Subject: [PATCH 05/15] Apply DebuggerDisplayAttribute to PEFile for easier debugging. --- ICSharpCode.Decompiler/Metadata/PEFile.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ICSharpCode.Decompiler/Metadata/PEFile.cs b/ICSharpCode.Decompiler/Metadata/PEFile.cs index 0934962a3..84ca61409 100644 --- a/ICSharpCode.Decompiler/Metadata/PEFile.cs +++ b/ICSharpCode.Decompiler/Metadata/PEFile.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection.Metadata; @@ -41,6 +42,7 @@ namespace ICSharpCode.Decompiler.Metadata /// system from multiple PEFiles. This allows the caches to be shared across multiple /// decompiled type systems. /// + [DebuggerDisplay("{FileName}")] public class PEFile : IDisposable, TypeSystem.IModuleReference { public string FileName { get; } From 0e84a0353a1b803569ddba24af9f27786ebcd035 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Tue, 3 Sep 2019 18:59:39 +0200 Subject: [PATCH 06/15] support folding for xaml, fixes #1658 --- ILSpy/TextView/DecompilerTextView.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index 17a53d9dc..5751aedfc 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -428,6 +428,11 @@ namespace ICSharpCode.ILSpy.TextView foldingManager = FoldingManager.Install(textEditor.TextArea); foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1); Debug.WriteLine(" Updating folding: {0}", w.Elapsed); w.Restart(); + } else if (highlighting?.Name == "XML") { + foldingManager = FoldingManager.Install(textEditor.TextArea); + var foldingStrategy = new XmlFoldingStrategy(); + foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); + Debug.WriteLine(" Updating folding: {0}", w.Elapsed); w.Restart(); } } #endregion From e84c3ae04c5623f6cc4b6fe9f78ba3848301033c Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Tue, 1 Oct 2019 13:38:32 +0200 Subject: [PATCH 07/15] Work on issue #1729 --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 71d46c53e..62ed6d9e8 100644 --- a/README.md +++ b/README.md @@ -48,13 +48,11 @@ How to build ------------ Windows: -- Install Visual Studio (minimum version: 2019.2) with the following components: - - Workload ".NET Desktop Development" - - .NET Framework 4.6.2 Targeting Pack (if the VS installer does not offer this option, install the [.NET 4.6.2 developer pack](https://www.microsoft.com/en-us/download/details.aspx?id=53321) separately) +- Install Visual Studio (documented version: 16.3) with the following components: + - Workload ".NET Desktop Development". This includes by default .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the .NET Core 3 SDK (ILSpy.csproj targets .NET 4.7.2 and uses SDK-style project files across ILSpy.sln). + - Workload "Visual Studio extension development" (ILSpy.sln contains a VS extension project) - Individual Component "MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.22)" (or similar) - The VC++ toolset is optional; if present it is used for `editbin.exe` to modify the stack size used by ILSpy.exe from 1MB to 16MB, because the decompiler makes heavy use of recursion, where small stack sizes lead to problems in very complex methods. -- Install the [.NET Core SDK 2.2](https://dotnet.microsoft.com/download) -- Install the [.NET Core SDK 3](https://dotnet.microsoft.com/download/dotnet-core) - Check out the ILSpy repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). - Open ILSpy.sln in Visual Studio. @@ -63,11 +61,11 @@ Windows: - Use the Visual Studio "Test Explorer" to see/run the tests Unix: -- Make sure .NET Core 2.2 is installed (you can get it here: https://get.dot.net). +- Make sure .NET Core 2.1 LTS Runtime is installed (you can get it here: https://get.dot.net). - Make sure [.NET Core SDK 3](https://dotnet.microsoft.com/download/dotnet-core) is installed. - Check out the repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). -- Use `dotnet build Frontends.sln` to build the non-Windows flavors of ILSpy (cli and powershell core). +- Use `dotnet build Frontends.sln` to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core). (Visual Studio for Mac users only:) - Edit `\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj` From 5963f737bc6984c32bb8cfd883ef9a0f5a9e4a89 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Tue, 1 Oct 2019 13:39:36 +0200 Subject: [PATCH 08/15] Pull request #1728 obsoletes the note for Mac users --- README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.md b/README.md index 62ed6d9e8..17b8f787f 100644 --- a/README.md +++ b/README.md @@ -60,20 +60,13 @@ Windows: - Run project "ILSpy" for the ILSpy UI - Use the Visual Studio "Test Explorer" to see/run the tests -Unix: +Unix / Mac: - Make sure .NET Core 2.1 LTS Runtime is installed (you can get it here: https://get.dot.net). - Make sure [.NET Core SDK 3](https://dotnet.microsoft.com/download/dotnet-core) is installed. - Check out the repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). - Use `dotnet build Frontends.sln` to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core). -(Visual Studio for Mac users only:) -- Edit `\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj` - Add `Sdk="Microsoft.NET.Sdk"` to the `Project` element. - This is required due to a tooling issue. - Please do not commit this when contributing a pull request! -- Use Frontends.sln to work. - How to contribute ----------------- From b479d15c915eb01f089f55b8b8603c0121053090 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Tue, 1 Oct 2019 13:46:15 +0200 Subject: [PATCH 09/15] MSVC tooling version update, wording --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 17b8f787f..87283a0b0 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,9 @@ How to build Windows: - Install Visual Studio (documented version: 16.3) with the following components: - - Workload ".NET Desktop Development". This includes by default .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the .NET Core 3 SDK (ILSpy.csproj targets .NET 4.7.2 and uses SDK-style project files across ILSpy.sln). + - Workload ".NET Desktop Development". This includes by default .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the .NET Core 3 SDK (ILSpy.csproj targets .NET 4.7.2, and ILSpy.sln uses SDK-style projects). - Workload "Visual Studio extension development" (ILSpy.sln contains a VS extension project) - - Individual Component "MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.22)" (or similar) + - Individual Component "MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.23)" (or similar) - The VC++ toolset is optional; if present it is used for `editbin.exe` to modify the stack size used by ILSpy.exe from 1MB to 16MB, because the decompiler makes heavy use of recursion, where small stack sizes lead to problems in very complex methods. - Check out the ILSpy repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). @@ -62,7 +62,7 @@ Windows: Unix / Mac: - Make sure .NET Core 2.1 LTS Runtime is installed (you can get it here: https://get.dot.net). -- Make sure [.NET Core SDK 3](https://dotnet.microsoft.com/download/dotnet-core) is installed. +- Make sure [.NET Core 3 SDK](https://dotnet.microsoft.com/download/dotnet-core) is installed. - Check out the repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). - Use `dotnet build Frontends.sln` to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core). From 44acb103bc9d568bcfb09e3fbde9551f9af1cd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Tue, 1 Oct 2019 16:23:04 +0200 Subject: [PATCH 10/15] Add namespace search strategy --- ILSpy/ILSpy.csproj | 1 + ILSpy/MainWindow.xaml.cs | 2 + ILSpy/Search/NamespaceSearchStrategy.cs | 63 +++++++++++++++++++++++++ ILSpy/Search/SearchPane.cs | 9 +++- ILSpy/Search/SearchResult.cs | 9 ++++ ILSpy/TreeNodes/AssemblyListTreeNode.cs | 18 +++++++ 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 ILSpy/Search/NamespaceSearchStrategy.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 5c5f3b189..2caf98878 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -173,6 +173,7 @@ Resources.resx + diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index 16f35d510..7bff4aaae 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -722,6 +722,8 @@ namespace ICSharpCode.ILSpy return assemblyListTreeNode.FindPropertyNode(pd); case IEvent ed: return assemblyListTreeNode.FindEventNode(ed); + case INamespace nd: + return AssemblyListTreeNode.FindNamespaceNode(nd); default: return null; } diff --git a/ILSpy/Search/NamespaceSearchStrategy.cs b/ILSpy/Search/NamespaceSearchStrategy.cs new file mode 100644 index 000000000..6aca2973a --- /dev/null +++ b/ILSpy/Search/NamespaceSearchStrategy.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Metadata; +using System.Threading; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Util; + +namespace ICSharpCode.ILSpy.Search +{ + class NamespaceSearchStrategy : AbstractSearchStrategy + { + public NamespaceSearchStrategy(string term, IProducerConsumerCollection resultQueue) + : this(resultQueue, new[] { term }) + { + } + + public NamespaceSearchStrategy(IProducerConsumerCollection resultQueue, string[] terms) + : base(resultQueue, terms) + { + } + + public override void Search(PEFile module, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + var typeSystem = module.GetTypeSystemOrNull(); + if (typeSystem == null) return; + + var root = ((MetadataModule)typeSystem.MainModule).RootNamespace; + Search(module, root); + } + + private void Search(PEFile module, INamespace ns) + { + if (ns.Types.Any()) { + if (IsMatch(ns.FullName.Length == 0 ? "-" : ns.FullName)) + OnFoundResult(module, ns); + } + + foreach (var child in ns.ChildNamespaces) + Search(module, child); + } + + void OnFoundResult(PEFile module, INamespace ns) + { + var name = ns.FullName.Length == 0 ? "-" : ns.FullName; + var result = new NamespaceSearchResult { + Namespace = ns, + Name = name, + Fitness = 1.0f / name.Length, + Location = module.Name, + Assembly = module.FullName, + }; + OnFoundResult(result); + } + } +} \ No newline at end of file diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index f2bbf7760..2201273eb 100644 --- a/ILSpy/Search/SearchPane.cs +++ b/ILSpy/Search/SearchPane.cs @@ -77,6 +77,7 @@ namespace ICSharpCode.ILSpy searchModeComboBox.Items.Add(new { Image = Images.Library, Name = "Metadata Token" }); searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" }); searchModeComboBox.Items.Add(new { Image = Images.Assembly, Name = "Assembly" }); + searchModeComboBox.Items.Add(new { Image = Images.Namespace, Name = "Namespace" }); ContextMenuProvider.Add(listBox); MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged; @@ -355,6 +356,9 @@ namespace ICSharpCode.ILSpy if (searchTerm[0].StartsWith("an:", StringComparison.Ordinal)) return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FullName); + + if (searchTerm[0].StartsWith("n:", StringComparison.Ordinal)) + return new NamespaceSearchStrategy(searchTerm[0].Substring(2), resultQueue); } switch (searchMode) @@ -381,6 +385,8 @@ namespace ICSharpCode.ILSpy return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm); case SearchMode.Assembly: return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.NameOrFileName); + case SearchMode.Namespace: + return new NamespaceSearchStrategy(resultQueue, searchTerm); } return null; @@ -413,6 +419,7 @@ namespace ICSharpCode.ILSpy Literal, Token, Resource, - Assembly + Assembly, + Namespace } } \ No newline at end of file diff --git a/ILSpy/Search/SearchResult.cs b/ILSpy/Search/SearchResult.cs index d632129f2..9d71adf59 100644 --- a/ILSpy/Search/SearchResult.cs +++ b/ILSpy/Search/SearchResult.cs @@ -103,4 +103,13 @@ namespace ICSharpCode.ILSpy public override ImageSource Image => Images.Assembly; public override ImageSource LocationImage => Images.Library; } + + public class NamespaceSearchResult : SearchResult + { + public INamespace Namespace { get; set; } + public override object Reference => Namespace; + + public override ImageSource Image => Images.Namespace; + public override ImageSource LocationImage => Images.Assembly; + } } \ No newline at end of file diff --git a/ILSpy/TreeNodes/AssemblyListTreeNode.cs b/ILSpy/TreeNodes/AssemblyListTreeNode.cs index b579b2930..e0755ec23 100644 --- a/ILSpy/TreeNodes/AssemblyListTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyListTreeNode.cs @@ -318,6 +318,24 @@ namespace ICSharpCode.ILSpy.TreeNodes typeNode.EnsureLazyChildren(); return typeNode.Children.OfType().FirstOrDefault(m => m.EventDefinition.MetadataToken == def.MetadataToken && !m.IsHidden); } + + /// + /// Looks up the event node corresponding to the namespace definition. + /// Returns null if no matching node is found. + /// + public NamespaceTreeNode FindNamespaceNode(INamespace def) + { + var module = def.ContributingModules.FirstOrDefault(); + if (module == null) + return null; + + AssemblyTreeNode assemblyNode = FindAssemblyNode(module); + if (assemblyNode == null) + return null; + + assemblyNode.EnsureLazyChildren(); + return assemblyNode.Children.OfType().FirstOrDefault(n => def.FullName.Length == 0 || def.FullName.Equals(n.Text)); + } #endregion } } From 4bc7feadbf8b61cc207215dfd688c3b23dc39f13 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 1 Oct 2019 19:58:48 +0200 Subject: [PATCH 11/15] Fix #1734: Do not roundtrip ICSharpCode.Decompiler test-case. --- ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs b/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs index 210a45d13..fa58d103e 100644 --- a/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs +++ b/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs @@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.Tests [Test] public void ICSharpCode_Decompiler() { - RunWithTest("ICSharpCode.Decompiler", "ICSharpCode.Decompiler.dll", "ICSharpCode.Decompiler.Tests.exe"); + RunOnly("ICSharpCode.Decompiler", "ICSharpCode.Decompiler.dll"); } [Test] @@ -113,7 +113,12 @@ namespace ICSharpCode.Decompiler.Tests RunInternal(dir, fileToRoundtrip, outputDir => Tester.RunAndCompareOutput(fileToRoundtrip, Path.Combine(inputDir, fileToRoundtrip), Path.Combine(outputDir, fileToRoundtrip))); } - + + void RunOnly(string dir, string fileToRoundtrip) + { + RunInternal(dir, fileToRoundtrip, outputDir => { }); + } + void RunInternal(string dir, string fileToRoundtrip, Action testAction, string snkFilePath = null) { if (!Directory.Exists(TestDir)) { From 941906e8dbb57131417d8acafa0fb7fcd7225466 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 1 Oct 2019 21:58:40 +0200 Subject: [PATCH 12/15] Fix #1699: Auto properties without getter are not properly decompiled Also fixes wrong decompilation of auto properties modified by Fody. --- .../CSharp/Syntax/TypeSystemAstBuilder.cs | 2 +- .../Transforms/PatternStatementTransform.cs | 37 +++++++++++++------ .../TypeSystem/TypeSystemExtensions.cs | 5 +++ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 64d677fb4..f67d60321 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -1522,7 +1522,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax Accessor decl = new Accessor(); if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility) decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility); - if (accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false) + if (accessor.HasReadonlyModifier()) decl.Modifiers |= Modifiers.Readonly; if (ShowAttributes) { decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes())); diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs index 8692bf678..b4758059d 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs @@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms public override AstNode VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) { if (context.Settings.AutomaticProperties) { - AstNode result = TransformAutomaticProperties(propertyDeclaration); + AstNode result = TransformAutomaticProperty(propertyDeclaration); if (result != null) return result; } @@ -554,10 +554,25 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } }; - PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration propertyDeclaration) + bool CanTransformToAutomaticProperty(IProperty property) + { + if (!property.CanGet) + return false; + if (!property.Getter.IsCompilerGenerated()) + return false; + if (property.Setter is IMethod setter) { + if (!setter.IsCompilerGenerated()) + return false; + if (setter.HasReadonlyModifier()) + return false; + } + return true; + } + + PropertyDeclaration TransformAutomaticProperty(PropertyDeclaration propertyDeclaration) { IProperty property = propertyDeclaration.GetSymbol() as IProperty; - if (!property.CanGet || (!property.Getter.IsCompilerGenerated() && (property.Setter?.IsCompilerGenerated() == false))) + if (!CanTransformToAutomaticProperty(property)) return null; IField field = null; Match m = automaticPropertyPattern.Match(propertyDeclaration); @@ -652,14 +667,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms var parent = identifier.Parent; var mrr = parent.Annotation(); var field = mrr?.Member as IField; - if (field != null && field.IsCompilerGenerated()) { - var propertyName = identifier.Name.Substring(1, identifier.Name.Length - 1 - ">k__BackingField".Length); - var property = field.DeclaringTypeDefinition.GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); - if (property != null) { - parent.RemoveAnnotations(); - parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property)); - return Identifier.Create(propertyName); - } + if (field != null && IsBackingFieldOfAutomaticProperty(field, out var property) + && CanTransformToAutomaticProperty(property) && currentMethod.AccessorOwner != property) + { + parent.RemoveAnnotations(); + parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property)); + return Identifier.Create(property.Name); } } return null; @@ -673,7 +686,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (field == null) return null; var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault(); - if (@event != null) { + if (@event != null && currentMethod.AccessorOwner != @event) { parent.RemoveAnnotations(); parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event)); return identifier; diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs index 78c5a1892..1b6e6cdbe 100644 --- a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs +++ b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs @@ -281,6 +281,11 @@ namespace ICSharpCode.Decompiler.TypeSystem return ty; } + public static bool HasReadonlyModifier(this IMethod accessor) + { + return accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false; + } + #region GetType/Member /// /// Gets all type definitions in the compilation. From 1010d3658cf81bb62544636ea80cee18e44588aa Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Wed, 2 Oct 2019 12:06:42 +0200 Subject: [PATCH 13/15] Try switching .Decompiler.Console on Release(NuGet)/Debug(ProjectRef). Tested on VS Mac 8.3 --- Frontends.sln | 6 ++++++ .../ICSharpCode.Decompiler.Console.csproj | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Frontends.sln b/Frontends.sln index bd714df16..e25304c21 100644 --- a/Frontends.sln +++ b/Frontends.sln @@ -14,6 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.Cons EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.PowerShell", "ICSharpCode.Decompiler.PowerShell\ICSharpCode.Decompiler.PowerShell.csproj", "{FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler", "ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj", "{526B267D-1904-4E9E-80DB-BB2259ADCF6C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -28,6 +30,10 @@ Global {FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}.Debug|Any CPU.Build.0 = Debug|Any CPU {FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}.Release|Any CPU.ActiveCfg = Release|Any CPU {FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}.Release|Any CPU.Build.0 = Release|Any CPU + {526B267D-1904-4E9E-80DB-BB2259ADCF6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {526B267D-1904-4E9E-80DB-BB2259ADCF6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {526B267D-1904-4E9E-80DB-BB2259ADCF6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {526B267D-1904-4E9E-80DB-BB2259ADCF6C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj index 5f3e7a298..f5478c1b9 100644 --- a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj +++ b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj @@ -26,9 +26,17 @@ NU1605 + + + + + + + + + - From 935e63f21a6d8e3c3ed616754e551dafdca58af3 Mon Sep 17 00:00:00 2001 From: Christoph Wille Date: Mon, 7 Oct 2019 09:33:52 +0200 Subject: [PATCH 14/15] iconUrl -> icon for ilspycmd https://aka.ms/deprecateIconUrl --- .../ICSharpCode.Decompiler.Console.csproj | 5 ++++- .../ILSpyCmdNuGetPackageIcon.png | Bin 0 -> 2454 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png diff --git a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj index f5478c1b9..6d337805c 100644 --- a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj +++ b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj @@ -12,7 +12,7 @@ Copyright 2011-2019 AlphaSierraPapa https://github.com/icsharpcode/ILSpy/ MIT - https://ilspy.net/images/icon32.png + ILSpyCmdNuGetPackageIcon.png https://github.com/icsharpcode/ILSpy/ 5.0.0.0 @@ -26,6 +26,9 @@ NU1605 + + + diff --git a/ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png b/ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..48841d7c7a169be011e054427cea93a396790879 GIT binary patch literal 2454 zcmd^9`9IT-A0IVWQ6GIjd`gE(pB!DNzI?(rMQ#0hmX(S@qIlW&)4(ueE#-&K3=a^oE5}aTIz%p2n3QgH8HZ; z=iC26;=q2-t3}T5lSrVAu>pwKbCSO=4nEPh&p!6489kd?XJoqb==#@E2! z|E}Zndk_2!9iVp{1I!);S-6JSJq&}m1w-6It=(VRJ`Qtu8t(W6@xc4lBNya-Z=|zt zl(Tn+3pCa|pypvfiH}dBr+?Pp0kMyR;(cMUK4D3|&@?{;IslOn7>I@=vOQtN9D>lQcXJD1vuWD8hpSHuP+wa{@HTp@` zzmTm*C?ov?vS0c3rs;AEZq20~TFE{%nSE~lh4D43 zDB5x=bp}nF&uZeQHVUxi3<8l}Qq}yC#3--sB2t(Iq#+!YTSn%T)eaNuIAxUK8WNLC zZm+6qBhfmj^_}EKPEzw)JVTg6=VKVcv`%3TYyBM)$Yl$1dVt)1A(qZAYaJvvcTt;J zR0f;eJWA>rY-IM;_i+lDvjuHGaUC;d^vTlB*^fPZ9D4^lC@dZZ2m`z2T!7p$Q~!C1 zIy_zVWuua_Q#1UllDA14TBUM#t0#b_aY5Y-(7*>;i(>j|rQdr=yYr>Mat*z$zoqj_ zYv*V?o734dLg$Qje;(~0{5mkqYZ>J;2A7#5tDgtQ2S+DHzJ70++G$+?+GmCAIYIXV z(7i0|o0|JNF~ghuF|f2dumX&(1A72{;yZul$2|Y%;?ITU$qis?YiDtJbxyE34+vM+ zer;@QZftD>fN+2L%~VEj?B59}$OdA&_y1iWTY>n6{YWICCJzEZAeokbA;NlI`WOTP zA2T)5w{tXJNQc{DJWsNsd}|DYu38($$S(Wc`JP4NeriWMaaHVLpn0D4Uc2lNXGb?!1)Anja)dV;u;IrB)+Dnyd<+CGp-N)Epf+EgwDzccISE_a*_pSX%TZr#5VoU`38Es_J&bWc~MN^Yd9XKO7jYXkHgyT213uSMjcvN>uZP5@{duD*SA3G^Q8S;mTo_<7#bV&9}${ob34*m>^GfF z_&Gr@n;Hl`t^4Se4`IOz4?L$<&94Man-j5Cz-ZtWmc~d%Mv9 zZIu!`Iexh~C+1nI$o`ZSV38SnRR}0yQ~Q!ui^!%HmWUmB2{+wh*&jbXrs&KIxe(a#VV&fyhAYX)jFH#c z;5t=f=eiP^V+to!Rmpy#rw*@`TvQ$ZUZd4Gr!G@VyRMfQ0c!*cC!~M6a)aGm4Vh!_ zG&SYFUQ>e<_Ct$Ach45tsJI9oyL>6jRQ+mmSlEByU3@}({7phrC_VDa&kA#z(oHYb zGmNQ~4_NG7#(U9rNB!n1{2U%j@cYIYK zLieC*!YqhzmC0*($z&?XxnPd|SA0YH!UgX|uC@o-;BA1Ylkw8?9enSS;K6*UgQO#99@cEbH<-(7r#=P2pkVuNO@(%O?a Date: Mon, 7 Oct 2019 09:39:35 +0200 Subject: [PATCH 15/15] iconUrl -> icon for ics.d nuspec https://aka.ms/deprecateIconUrl --- .../DecompilerNuGetPackageIcon.png | Bin 0 -> 2454 bytes .../ICSharpCode.Decompiler.nuspec.template | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png diff --git a/ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png b/ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..48841d7c7a169be011e054427cea93a396790879 GIT binary patch literal 2454 zcmd^9`9IT-A0IVWQ6GIjd`gE(pB!DNzI?(rMQ#0hmX(S@qIlW&)4(ueE#-&K3=a^oE5}aTIz%p2n3QgH8HZ; z=iC26;=q2-t3}T5lSrVAu>pwKbCSO=4nEPh&p!6489kd?XJoqb==#@E2! z|E}Zndk_2!9iVp{1I!);S-6JSJq&}m1w-6It=(VRJ`Qtu8t(W6@xc4lBNya-Z=|zt zl(Tn+3pCa|pypvfiH}dBr+?Pp0kMyR;(cMUK4D3|&@?{;IslOn7>I@=vOQtN9D>lQcXJD1vuWD8hpSHuP+wa{@HTp@` zzmTm*C?ov?vS0c3rs;AEZq20~TFE{%nSE~lh4D43 zDB5x=bp}nF&uZeQHVUxi3<8l}Qq}yC#3--sB2t(Iq#+!YTSn%T)eaNuIAxUK8WNLC zZm+6qBhfmj^_}EKPEzw)JVTg6=VKVcv`%3TYyBM)$Yl$1dVt)1A(qZAYaJvvcTt;J zR0f;eJWA>rY-IM;_i+lDvjuHGaUC;d^vTlB*^fPZ9D4^lC@dZZ2m`z2T!7p$Q~!C1 zIy_zVWuua_Q#1UllDA14TBUM#t0#b_aY5Y-(7*>;i(>j|rQdr=yYr>Mat*z$zoqj_ zYv*V?o734dLg$Qje;(~0{5mkqYZ>J;2A7#5tDgtQ2S+DHzJ70++G$+?+GmCAIYIXV z(7i0|o0|JNF~ghuF|f2dumX&(1A72{;yZul$2|Y%;?ITU$qis?YiDtJbxyE34+vM+ zer;@QZftD>fN+2L%~VEj?B59}$OdA&_y1iWTY>n6{YWICCJzEZAeokbA;NlI`WOTP zA2T)5w{tXJNQc{DJWsNsd}|DYu38($$S(Wc`JP4NeriWMaaHVLpn0D4Uc2lNXGb?!1)Anja)dV;u;IrB)+Dnyd<+CGp-N)Epf+EgwDzccISE_a*_pSX%TZr#5VoU`38Es_J&bWc~MN^Yd9XKO7jYXkHgyT213uSMjcvN>uZP5@{duD*SA3G^Q8S;mTo_<7#bV&9}${ob34*m>^GfF z_&Gr@n;Hl`t^4Se4`IOz4?L$<&94Man-j5Cz-ZtWmc~d%Mv9 zZIu!`Iexh~C+1nI$o`ZSV38SnRR}0yQ~Q!ui^!%HmWUmB2{+wh*&jbXrs&KIxe(a#VV&fyhAYX)jFH#c z;5t=f=eiP^V+to!Rmpy#rw*@`TvQ$ZUZd4Gr!G@VyRMfQ0c!*cC!~M6a)aGm4Vh!_ zG&SYFUQ>e<_Ct$Ach45tsJI9oyL>6jRQ+mmSlEByU3@}({7phrC_VDa&kA#z(oHYb zGmNQ~4_NG7#(U9rNB!n1{2U%j@cYIYK zLieC*!YqhzmC0*($z&?XxnPd|SA0YH!UgX|uC@o-;BA1Ylkw8?9enSS;K6*UgQO#99@cEbH<-(7r#=P2pkVuNO@(%O?aDaniel Grunwald, SharpDevelop MIT https://github.com/icsharpcode/ILSpy/ - https://ilspy.net/images/icon32.png + images\DecompilerNuGetPackageIcon.png false ICSharpCode.Decompiler is the decompiler engine used in ILSpy. @@ -22,6 +22,7 @@ +