Browse Source

Accomodate result image caching, split search result, jump to resource children, clean-up

pull/1707/head
Jan Kučera 6 years ago
parent
commit
146b3e7f4b
  1. 11
      ILSpy/ILSpy.csproj
  2. 2
      ILSpy/MainWindow.xaml.cs
  3. 9
      ILSpy/Search/AbstractEntitySearchStrategy.cs
  4. 6
      ILSpy/Search/AbstractSearchStrategy.cs
  5. 25
      ILSpy/Search/ResourceSearchStrategy.cs
  6. 58
      ILSpy/Search/SearchPane.cs
  7. 97
      ILSpy/Search/SearchResult.cs
  8. 12
      ILSpy/TreeNodes/AssemblyListTreeNode.cs

11
ILSpy/ILSpy.csproj

@ -167,10 +167,7 @@ @@ -167,10 +167,7 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Search\AbstractEntitySearchStrategy.cs">
<SubType>Code</SubType>
<Generator>MSBuild:Compile</Generator>
</Compile>
<Compile Include="Search\AbstractEntitySearchStrategy.cs" />
<Compile Include="Search\LiteralSearchStrategy.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="LoadedAssemblyExtensions.cs" />
@ -208,15 +205,13 @@ @@ -208,15 +205,13 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Commands\RefreshCommand.cs" />
<Compile Include="Commands\SaveCommand.cs" />
<Compile Include="Search\ResourceSearchStrategy.cs">
<SubType>Code</SubType>
<Generator>MSBuild:Compile</Generator>
</Compile>
<Compile Include="Search\ResourceSearchStrategy.cs" />
<Compile Include="Search\SearchPane.cs">
<DependentUpon>SearchPane.xaml</DependentUpon>
</Compile>
<Compile Include="Commands\SimpleCommand.cs" />
<Compile Include="Search\AbstractSearchStrategy.cs" />
<Compile Include="Search\SearchResult.cs" />
<Compile Include="SolutionWriter.cs" />
<Compile Include="TaskHelper.cs" />
<Compile Include="TextView\BracketHighlightRenderer.cs" />

2
ILSpy/MainWindow.xaml.cs

@ -713,6 +713,8 @@ namespace ICSharpCode.ILSpy @@ -713,6 +713,8 @@ namespace ICSharpCode.ILSpy
return assemblyListTreeNode.FindAssemblyNode(asm);
case Resource res:
return assemblyListTreeNode.FindResourceNode(res);
case ValueTuple<Resource, string> resName:
return assemblyListTreeNode.FindResourceNode(resName.Item1, resName.Item2);
case ITypeDefinition type:
return assemblyListTreeNode.FindTypeNode(type);
case IField fd:

9
ILSpy/Search/AbstractEntitySearchStrategy.cs

@ -52,14 +52,11 @@ namespace ICSharpCode.ILSpy.Search @@ -52,14 +52,11 @@ namespace ICSharpCode.ILSpy.Search
SearchResult ResultFromEntity(IEntity item)
{
var declaringType = item.DeclaringTypeDefinition;
return new SearchResult {
Reference = item,
return new MemberSearchResult {
Member = item,
Fitness = CalculateFitness(item),
Image = GetIcon(item),
Name = GetLanguageSpecificName(item),
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : item.Namespace,
AssemblyImage = Images.Assembly,
Assembly = item.ParentModule.FullAssemblyName,
ToolTip = item.ParentModule.PEFile?.FileName
};
@ -104,7 +101,7 @@ namespace ICSharpCode.ILSpy.Search @@ -104,7 +101,7 @@ namespace ICSharpCode.ILSpy.Search
}
}
ImageSource GetIcon(IEntity member)
static internal ImageSource GetIcon(IEntity member)
{
switch (member) {
case ITypeDefinition t:

6
ILSpy/Search/AbstractSearchStrategy.cs

@ -40,17 +40,17 @@ namespace ICSharpCode.ILSpy.Search @@ -40,17 +40,17 @@ namespace ICSharpCode.ILSpy.Search
public abstract void Search(PEFile module, CancellationToken cancellationToken);
protected virtual bool IsMatch(string entityName)
protected virtual bool IsMatch(string name)
{
if (regex != null) {
return regex.IsMatch(entityName);
return regex.IsMatch(name);
}
for (int i = 0; i < searchTerm.Length; ++i) {
// How to handle overlapping matches?
var term = searchTerm[i];
if (string.IsNullOrEmpty(term)) continue;
string text = entityName;
string text = name;
switch (term[0]) {
case '+': // must contain
term = term.Substring(1);

25
ILSpy/Search/ResourceSearchStrategy.cs

@ -46,46 +46,43 @@ namespace ICSharpCode.ILSpy.Search @@ -46,46 +46,43 @@ namespace ICSharpCode.ILSpy.Search
{
cancellationToken.ThrowIfCancellationRequested();
var resourcesNode = new ResourceListTreeNode(module);
resourcesNode.EnsureLazyChildren();
foreach (var node in resourcesNode.Children)
Search(module, null, resourcesNode, node, cancellationToken);
return;
foreach (Resource resource in module.Resources)
Search(module, resource, resourcesNode, ResourceTreeNode.Create(resource), cancellationToken);
}
void Search(PEFile module, object reference, SharpTreeNode parent, SharpTreeNode node, CancellationToken cancellationToken)
void Search(PEFile module, Resource resource, SharpTreeNode parent, SharpTreeNode node, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (node is ResourceTreeNode treeNode) {
if (!CheckVisibility(treeNode.Resource))
return;
reference = treeNode.Resource;
resource = treeNode.Resource;
}
if (node.Text != null && IsMatch((string)node.Text))
OnFoundResult(module, reference, node, parent);
OnFoundResult(module, resource, node, parent);
if (!searchInside)
return;
node.EnsureLazyChildren();
foreach (var child in node.Children)
Search(module, reference, node, child, cancellationToken);
Search(module, resource, node, child, cancellationToken);
}
void OnFoundResult(PEFile module, object reference, SharpTreeNode node, SharpTreeNode parent)
void OnFoundResult(PEFile module, Resource resource, SharpTreeNode node, SharpTreeNode parent)
{
var name = (string)node.Text;
var result = new SearchResult {
Reference = reference,
var result = new ResourceSearchResult {
Resource = resource,
Fitness = 1.0f / name.Length,
Image = (ImageSource)node.Icon,
Name = name,
LocationImage = (ImageSource)parent.Icon,
Location = (string)parent.Text,
AssemblyImage = Images.Assembly,
Assembly = module.Name,
Assembly = module.FullName,
ToolTip = module.FileName,
};
OnFoundResult(result);

58
ILSpy/Search/SearchPane.cs

@ -32,7 +32,6 @@ using System.Windows.Media; @@ -32,7 +32,6 @@ using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy
{
@ -76,7 +75,7 @@ namespace ICSharpCode.ILSpy @@ -76,7 +75,7 @@ namespace ICSharpCode.ILSpy
searchModeComboBox.Items.Add(new { Image = Images.Event, Name = "Event" });
searchModeComboBox.Items.Add(new { Image = Images.Literal, Name = "Constant" });
searchModeComboBox.Items.Add(new { Image = Images.Library, Name = "Metadata Token" });
searchModeComboBox.Items.Add(new { Image = Images.ResourceResourcesFile, Name = "Resource" });
searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" });
ContextMenuProvider.Add(listBox);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
@ -377,61 +376,6 @@ namespace ICSharpCode.ILSpy @@ -377,61 +376,6 @@ namespace ICSharpCode.ILSpy
}
}
public sealed class SearchResult // : IMemberTreeNode
{
public static readonly System.Collections.Generic.IComparer<SearchResult> Comparer = new SearchResultComparer();
ImageSource image;
ImageSource locationImage;
public static readonly IComparer<SearchResult> Comparer = new SearchResultComparer();
public object Reference { get; set; }
public float Fitness { get; set; }
public string Assembly { get; set; }
public string Location { get; set; }
public string Name { get; set; }
public object ToolTip { get; set; }
public ImageSource Image {
get {
if (image == null) {
image = AbstractSearchStrategy.GetIcon(Member);
}
return image;
}
}
public ImageSource LocationImage {
get {
if (locationImage == null) {
locationImage = Member.DeclaringTypeDefinition != null ? TypeTreeNode.GetIcon(Member.DeclaringTypeDefinition) : Images.Namespace;
}
return locationImage;
}
}
public ImageSource AssemblyImage {
get {
return Images.Assembly;
}
}
public override string ToString()
{
return Name;
}
class SearchResultComparer : System.Collections.Generic.IComparer<SearchResult>
{
public int Compare(SearchResult x, SearchResult y)
{
return StringComparer.Ordinal.Compare(x?.Name ?? "", y?.Name ?? "");
}
}
}
[ExportMainMenuCommand(Menu = nameof(Properties.Resources._View), Header =nameof(Properties.Resources.Search), MenuIcon = "Images/Search", MenuCategory = nameof(Properties.Resources.View), MenuOrder = 100)]
[ExportToolbarCommand(ToolTip = nameof(Properties.Resources.SearchCtrlShiftFOrCtrlE), ToolbarIcon = "Images/Search", ToolbarCategory = nameof(Properties.Resources.View), ToolbarOrder = 100)]
sealed class ShowSearchCommand : CommandWrapper

97
ILSpy/Search/SearchResult.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy
{
public class SearchResult
{
public static readonly IComparer<SearchResult> Comparer = new SearchResultComparer();
public virtual object Reference {
get {
return null;
}
}
public float Fitness { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string Assembly { get; set; }
public object ToolTip { get; set; }
public virtual ImageSource Image { get; set; }
public virtual ImageSource LocationImage { get; set; }
public ImageSource AssemblyImage {
get {
return Images.Assembly;
}
}
public override string ToString()
{
return Name;
}
class SearchResultComparer : IComparer<SearchResult>
{
public int Compare(SearchResult x, SearchResult y)
{
return StringComparer.Ordinal.Compare(x?.Name ?? "", y?.Name ?? "");
}
}
}
public class MemberSearchResult : SearchResult
{
public IEntity Member { get; set; }
public override object Reference => Member;
public override ImageSource Image {
get {
if (base.Image == null) {
base.Image = AbstractEntitySearchStrategy.GetIcon(Member);
}
return base.Image;
}
}
public override ImageSource LocationImage {
get {
if (base.LocationImage == null) {
base.LocationImage = Member.DeclaringTypeDefinition != null ? TypeTreeNode.GetIcon(Member.DeclaringTypeDefinition) : Images.Namespace;
}
return base.LocationImage;
}
}
}
public class ResourceSearchResult : SearchResult
{
public Resource Resource { get; set; }
public override object Reference => ValueTuple.Create(Resource, Name);
}
}

12
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -155,7 +155,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -155,7 +155,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
#region Find*Node
public ILSpyTreeNode FindResourceNode(Resource resource)
{
if (resource == null)
if (resource == null || resource.IsNil)
return null;
foreach (AssemblyTreeNode node in this.Children)
{
@ -177,6 +177,16 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -177,6 +177,16 @@ namespace ICSharpCode.ILSpy.TreeNodes
return null;
}
public ILSpyTreeNode FindResourceNode(Resource resource, string name)
{
var resourceNode = FindResourceNode(resource);
if (resourceNode == null || name == null || name.Equals(resourceNode.Text))
return resourceNode;
resourceNode.EnsureLazyChildren();
return resourceNode.Children.OfType<ILSpyTreeNode>().Where(x => name.Equals(x.Text)).FirstOrDefault() ?? resourceNode;
}
public AssemblyTreeNode FindAssemblyNode(IModule module)
{
return FindAssemblyNode(module.PEFile);

Loading…
Cancel
Save