Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy into fancy-tooltips

pull/1654/head
Siegfried Pammer 7 years ago
parent
commit
159ab51e80
  1. 6
      Frontends.sln
  2. 15
      ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj
  3. BIN
      ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png
  4. 9
      ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs
  5. 15
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs
  6. 2
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  7. 2
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 37
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  9. BIN
      ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png
  10. 8
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  11. 3
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template
  12. 8
      ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs
  13. 2
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  14. 5
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  15. 1
      ILSpy/ILSpy.csproj
  16. 2
      ILSpy/MainWindow.xaml.cs
  17. 63
      ILSpy/Search/NamespaceSearchStrategy.cs
  18. 9
      ILSpy/Search/SearchPane.cs
  19. 9
      ILSpy/Search/SearchResult.cs
  20. 5
      ILSpy/TextView/DecompilerTextView.cs
  21. 18
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  22. 25
      README.md
  23. 2
      global.json

6
Frontends.sln

@ -14,6 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.Cons
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.PowerShell", "ICSharpCode.Decompiler.PowerShell\ICSharpCode.Decompiler.PowerShell.csproj", "{FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.PowerShell", "ICSharpCode.Decompiler.PowerShell\ICSharpCode.Decompiler.PowerShell.csproj", "{FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler", "ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj", "{526B267D-1904-4E9E-80DB-BB2259ADCF6C}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{FF7D6041-3C52-47D1-A32A-0BFE8EE4EEEB}.Release|Any CPU.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

15
ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj

@ -12,7 +12,7 @@
<Copyright>Copyright 2011-2019 AlphaSierraPapa</Copyright> <Copyright>Copyright 2011-2019 AlphaSierraPapa</Copyright>
<PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl> <PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIconUrl>https://ilspy.net/images/icon32.png</PackageIconUrl> <PackageIcon>ILSpyCmdNuGetPackageIcon.png</PackageIcon>
<RepositoryUrl>https://github.com/icsharpcode/ILSpy/</RepositoryUrl> <RepositoryUrl>https://github.com/icsharpcode/ILSpy/</RepositoryUrl>
<Company /> <Company />
<AssemblyVersion>5.0.0.0</AssemblyVersion> <AssemblyVersion>5.0.0.0</AssemblyVersion>
@ -27,8 +27,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.3.2" /> <None Include="ILSpyCmdNuGetPackageIcon.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="ICSharpCode.Decompiler" Version="5.0.0.5124" /> <PackageReference Include="ICSharpCode.Decompiler" Version="5.0.0.5124" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.3.2" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" /> <PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" /> <PackageReference Include="System.Runtime.Handles" Version="4.3.0" />

BIN
ICSharpCode.Decompiler.Console/ILSpyCmdNuGetPackageIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

9
ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.Tests
[Test] [Test]
public void ICSharpCode_Decompiler() public void ICSharpCode_Decompiler()
{ {
RunWithTest("ICSharpCode.Decompiler", "ICSharpCode.Decompiler.dll", "ICSharpCode.Decompiler.Tests.exe"); RunOnly("ICSharpCode.Decompiler", "ICSharpCode.Decompiler.dll");
} }
[Test] [Test]
@ -113,7 +113,12 @@ namespace ICSharpCode.Decompiler.Tests
RunInternal(dir, fileToRoundtrip, RunInternal(dir, fileToRoundtrip,
outputDir => Tester.RunAndCompareOutput(fileToRoundtrip, Path.Combine(inputDir, fileToRoundtrip), Path.Combine(outputDir, 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<string> testAction, string snkFilePath = null) void RunInternal(string dir, string fileToRoundtrip, Action<string> testAction, string snkFilePath = null)
{ {
if (!Directory.Exists(TestDir)) { if (!Directory.Exists(TestDir)) {

15
ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs

@ -17,6 +17,8 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
@ -182,7 +184,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
Use(GetMyClass()?.Text ?? "Hello"); Use(GetMyClass()?.Text ?? "Hello");
} }
public void CallOnValueTypeField() public void CallOnValueTypeField()
{ {
Use(GetMyClass()?.IntVal.ToString()); Use(GetMyClass()?.IntVal.ToString());
@ -258,6 +260,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return t?.Int(); return t?.Int();
} }
public int? Issue1709(object obj)
{
return (obj as ICollection)?.Count + (obj as ICollection<int>)?.Count;
}
private static void Issue1689(List<byte[]> setsOfNumbers)
{
Console.WriteLine(setsOfNumbers?[0]?[1].ToString() == "2");
Console.WriteLine(setsOfNumbers?[1]?[1].ToString() == null);
}
private static dynamic DynamicNullProp(dynamic a) private static dynamic DynamicNullProp(dynamic a)
{ {
return a?.b.c(1)?.d[10]; return a?.b.c(1)?.d[10];

2
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -791,7 +791,7 @@ namespace ICSharpCode.Decompiler.CSharp
bool ParentIsCurrentGetter(ILInstruction inst) bool ParentIsCurrentGetter(ILInstruction inst)
{ {
return inst.Parent is CallInstruction cv && cv.Method.IsAccessor && 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 #endregion

2
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1522,7 +1522,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
Accessor decl = new Accessor(); Accessor decl = new Accessor();
if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility) if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility)
decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility); decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility);
if (accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false) if (accessor.HasReadonlyModifier())
decl.Modifiers |= Modifiers.Readonly; decl.Modifiers |= Modifiers.Readonly;
if (ShowAttributes) { if (ShowAttributes) {
decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes())); decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes()));

37
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override AstNode VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) public override AstNode VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{ {
if (context.Settings.AutomaticProperties) { if (context.Settings.AutomaticProperties) {
AstNode result = TransformAutomaticProperties(propertyDeclaration); AstNode result = TransformAutomaticProperty(propertyDeclaration);
if (result != null) if (result != null)
return result; 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; IProperty property = propertyDeclaration.GetSymbol() as IProperty;
if (!property.CanGet || (!property.Getter.IsCompilerGenerated() && (property.Setter?.IsCompilerGenerated() == false))) if (!CanTransformToAutomaticProperty(property))
return null; return null;
IField field = null; IField field = null;
Match m = automaticPropertyPattern.Match(propertyDeclaration); Match m = automaticPropertyPattern.Match(propertyDeclaration);
@ -652,14 +667,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var parent = identifier.Parent; var parent = identifier.Parent;
var mrr = parent.Annotation<MemberResolveResult>(); var mrr = parent.Annotation<MemberResolveResult>();
var field = mrr?.Member as IField; var field = mrr?.Member as IField;
if (field != null && field.IsCompilerGenerated()) { if (field != null && IsBackingFieldOfAutomaticProperty(field, out var property)
var propertyName = identifier.Name.Substring(1, identifier.Name.Length - 1 - ">k__BackingField".Length); && CanTransformToAutomaticProperty(property) && currentMethod.AccessorOwner != property)
var property = field.DeclaringTypeDefinition.GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); {
if (property != null) { parent.RemoveAnnotations<MemberResolveResult>();
parent.RemoveAnnotations<MemberResolveResult>(); parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property));
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property)); return Identifier.Create(property.Name);
return Identifier.Create(propertyName);
}
} }
} }
return null; return null;
@ -673,7 +686,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (field == null) if (field == null)
return null; return null;
var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault(); var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
if (@event != null) { if (@event != null && currentMethod.AccessorOwner != @event) {
parent.RemoveAnnotations<MemberResolveResult>(); parent.RemoveAnnotations<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event)); parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event));
return identifier; return identifier;

BIN
ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

8
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project> <Project Sdk="Microsoft.NET.Sdk">
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" />
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
@ -647,12 +646,11 @@
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" /> <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup> </ItemGroup>
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" /> <Target Name="ILSpyUpdateAssemblyInfo" BeforeTargets="BeforeBuild">
<Target Name="BeforeBuild">
<PropertyGroup> <PropertyGroup>
<UpdateAssemblyInfo>powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration)</UpdateAssemblyInfo> <UpdateAssemblyInfo>powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration)</UpdateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<Exec WorkingDirectory=".." Command="$(UpdateAssemblyInfo)" Timeout="60000" /> <Exec WorkingDirectory=".." Command="$(UpdateAssemblyInfo)" Timeout="60000" />
</Target> </Target>
</Project> </Project>

3
ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template

@ -8,7 +8,7 @@
<owners>Daniel Grunwald, SharpDevelop</owners> <owners>Daniel Grunwald, SharpDevelop</owners>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/icsharpcode/ILSpy/</projectUrl> <projectUrl>https://github.com/icsharpcode/ILSpy/</projectUrl>
<iconUrl>https://ilspy.net/images/icon32.png</iconUrl> <icon>images\DecompilerNuGetPackageIcon.png</icon>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ICSharpCode.Decompiler is the decompiler engine used in ILSpy.</description> <description>ICSharpCode.Decompiler is the decompiler engine used in ILSpy.</description>
<!--<releaseNotes></releaseNotes>--> <!--<releaseNotes></releaseNotes>-->
@ -22,6 +22,7 @@
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>
<file src="DecompilerNuGetPackageIcon.png" target="images\" />
<file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.dll" target="lib\netstandard2.0" /> <file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.dll" target="lib\netstandard2.0" />
<file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.pdb" target="lib\netstandard2.0" /> <file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.pdb" target="lib\netstandard2.0" />
<file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.xml" target="lib\netstandard2.0" /> <file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.xml" target="lib\netstandard2.0" />

8
ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs

@ -18,6 +18,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL.Transforms namespace ICSharpCode.Decompiler.IL.Transforms
@ -211,6 +212,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
} else if (inst is LdLen ldLen) { } else if (inst is LdLen ldLen) {
inst = ldLen.Array; 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) { } else if (inst is NullableUnwrap unwrap) {
inst = unwrap.Argument; inst = unwrap.Argument;
if (unwrap.RefInput && inst is AddressOf addressOf) { if (unwrap.RefInput && inst is AddressOf addressOf) {
@ -272,7 +278,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
static bool IsGetter(IMethod method) 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) private void IntroduceUnwrap(ILVariable testedVar, ILInstruction varLoad, Mode mode)

2
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; 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 /// system from multiple PEFiles. This allows the caches to be shared across multiple
/// decompiled type systems. /// decompiled type systems.
/// </remarks> /// </remarks>
[DebuggerDisplay("{FileName}")]
public class PEFile : IDisposable, TypeSystem.IModuleReference public class PEFile : IDisposable, TypeSystem.IModuleReference
{ {
public string FileName { get; } public string FileName { get; }

5
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -281,6 +281,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
return ty; return ty;
} }
public static bool HasReadonlyModifier(this IMethod accessor)
{
return accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false;
}
#region GetType/Member #region GetType/Member
/// <summary> /// <summary>
/// Gets all type definitions in the compilation. /// Gets all type definitions in the compilation.

1
ILSpy/ILSpy.csproj

@ -175,6 +175,7 @@
</Compile> </Compile>
<Compile Include="RichTextModelOutput.cs" /> <Compile Include="RichTextModelOutput.cs" />
<Compile Include="Search\AbstractEntitySearchStrategy.cs" /> <Compile Include="Search\AbstractEntitySearchStrategy.cs" />
<Compile Include="Search\NamespaceSearchStrategy.cs" />
<Compile Include="Search\AssemblySearchStrategy.cs" /> <Compile Include="Search\AssemblySearchStrategy.cs" />
<Compile Include="Search\LiteralSearchStrategy.cs" /> <Compile Include="Search\LiteralSearchStrategy.cs" />
<Compile Include="LoadedAssembly.cs" /> <Compile Include="LoadedAssembly.cs" />

2
ILSpy/MainWindow.xaml.cs

@ -722,6 +722,8 @@ namespace ICSharpCode.ILSpy
return assemblyListTreeNode.FindPropertyNode(pd); return assemblyListTreeNode.FindPropertyNode(pd);
case IEvent ed: case IEvent ed:
return assemblyListTreeNode.FindEventNode(ed); return assemblyListTreeNode.FindEventNode(ed);
case INamespace nd:
return AssemblyListTreeNode.FindNamespaceNode(nd);
default: default:
return null; return null;
} }

63
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<SearchResult> resultQueue)
: this(resultQueue, new[] { term })
{
}
public NamespaceSearchStrategy(IProducerConsumerCollection<SearchResult> 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);
}
}
}

9
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.Library, Name = "Metadata Token" });
searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" }); searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" });
searchModeComboBox.Items.Add(new { Image = Images.Assembly, Name = "Assembly" }); searchModeComboBox.Items.Add(new { Image = Images.Assembly, Name = "Assembly" });
searchModeComboBox.Items.Add(new { Image = Images.Namespace, Name = "Namespace" });
ContextMenuProvider.Add(listBox); ContextMenuProvider.Add(listBox);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged; MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
@ -355,6 +356,9 @@ namespace ICSharpCode.ILSpy
if (searchTerm[0].StartsWith("an:", StringComparison.Ordinal)) if (searchTerm[0].StartsWith("an:", StringComparison.Ordinal))
return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FullName); 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) switch (searchMode)
@ -381,6 +385,8 @@ namespace ICSharpCode.ILSpy
return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm); return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm);
case SearchMode.Assembly: case SearchMode.Assembly:
return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.NameOrFileName); return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.NameOrFileName);
case SearchMode.Namespace:
return new NamespaceSearchStrategy(resultQueue, searchTerm);
} }
return null; return null;
@ -413,6 +419,7 @@ namespace ICSharpCode.ILSpy
Literal, Literal,
Token, Token,
Resource, Resource,
Assembly Assembly,
Namespace
} }
} }

9
ILSpy/Search/SearchResult.cs

@ -103,4 +103,13 @@ namespace ICSharpCode.ILSpy
public override ImageSource Image => Images.Assembly; public override ImageSource Image => Images.Assembly;
public override ImageSource LocationImage => Images.Library; 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;
}
} }

5
ILSpy/TextView/DecompilerTextView.cs

@ -606,6 +606,11 @@ namespace ICSharpCode.ILSpy.TextView
foldingManager = FoldingManager.Install(textEditor.TextArea); foldingManager = FoldingManager.Install(textEditor.TextArea);
foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1); foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1);
Debug.WriteLine(" Updating folding: {0}", w.Elapsed); w.Restart(); 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 #endregion

18
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -318,6 +318,24 @@ namespace ICSharpCode.ILSpy.TreeNodes
typeNode.EnsureLazyChildren(); typeNode.EnsureLazyChildren();
return typeNode.Children.OfType<EventTreeNode>().FirstOrDefault(m => m.EventDefinition.MetadataToken == def.MetadataToken && !m.IsHidden); return typeNode.Children.OfType<EventTreeNode>().FirstOrDefault(m => m.EventDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);
} }
/// <summary>
/// Looks up the event node corresponding to the namespace definition.
/// Returns null if no matching node is found.
/// </summary>
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<NamespaceTreeNode>().FirstOrDefault(n => def.FullName.Length == 0 || def.FullName.Equals(n.Text));
}
#endregion #endregion
} }
} }

25
README.md

@ -48,13 +48,11 @@ How to build
------------ ------------
Windows: Windows:
- Install Visual Studio (minimum version: 2019.2) with the following components: - Install Visual Studio (documented version: 16.3) with the following components:
- Workload ".NET Desktop Development" - 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).
- .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) - 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. - 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. - Check out the ILSpy repository using git.
- Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases).
- Open ILSpy.sln in Visual Studio. - Open ILSpy.sln in Visual Studio.
@ -62,19 +60,12 @@ Windows:
- Run project "ILSpy" for the ILSpy UI - Run project "ILSpy" for the ILSpy UI
- Use the Visual Studio "Test Explorer" to see/run the tests - Use the Visual Studio "Test Explorer" to see/run the tests
Unix: Unix / Mac:
- 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. - Make sure [.NET Core 3 SDK](https://dotnet.microsoft.com/download/dotnet-core) is installed.
- Check out the repository using git. - Check out the repository using git.
- Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). - 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`
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 How to contribute
----------------- -----------------

2
global.json

@ -1,6 +1,6 @@
{ {
"msbuild-sdks": { "msbuild-sdks": {
"MSBuild.Sdk.Extras": "2.0.24" "MSBuild.Sdk.Extras": "2.0.54"
}, },
"sdk": { "sdk": {
"version": "3.0.100" "version": "3.0.100"

Loading…
Cancel
Save