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..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 @@ -27,8 +27,19 @@ - + + + + + + + + + + + + diff --git a/ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png b/ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png new file mode 100644 index 000000000..48841d7c7 Binary files /dev/null and b/ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png differ 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)) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs index 98b5df626..6d2191833 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 { @@ -182,7 +184,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { Use(GetMyClass()?.Text ?? "Hello"); } - + public void CallOnValueTypeField() { Use(GetMyClass()?.IntVal.ToString()); @@ -258,6 +260,17 @@ 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 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/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/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/DecompilerNuGetPackageIcon.png b/ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png new file mode 100644 index 000000000..48841d7c7 Binary files /dev/null and b/ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png differ diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 7480923ab..a7becbd57 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -1,6 +1,5 @@  - - + netstandard2.0 @@ -647,12 +646,11 @@ - - - + powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration) + \ No newline at end of file diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template index 314edbd73..f8dec329e 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template @@ -8,7 +8,7 @@ Daniel 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 @@ + diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs index 90d41d06d..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) { @@ -272,7 +278,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) 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; } 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. diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 442bd19b4..05de6133a 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -175,6 +175,7 @@ + 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/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index 136ab67f3..84e646752 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -606,6 +606,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 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 } } diff --git a/README.md b/README.md index 71d46c53e..87283a0b0 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) - - Individual Component "MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.22)" (or similar) +- 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 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.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. -- 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. @@ -62,19 +60,12 @@ Windows: - Run project "ILSpy" for the ILSpy UI - 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 SDK 3](https://dotnet.microsoft.com/download/dotnet-core) is installed. +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 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 (cli 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. +- Use `dotnet build Frontends.sln` to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core). How to contribute ----------------- 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"