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"