diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 07a789a4a..072b2c3ea 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -167,10 +167,7 @@
True
Resources.resx
-
- Code
- MSBuild:Compile
-
+
@@ -208,15 +205,13 @@
-
- Code
- MSBuild:Compile
-
+
SearchPane.xaml
+
diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs
index 059d9ec14..d388d2887 100644
--- a/ILSpy/MainWindow.xaml.cs
+++ b/ILSpy/MainWindow.xaml.cs
@@ -713,6 +713,8 @@ namespace ICSharpCode.ILSpy
return assemblyListTreeNode.FindAssemblyNode(asm);
case Resource res:
return assemblyListTreeNode.FindResourceNode(res);
+ case ValueTuple resName:
+ return assemblyListTreeNode.FindResourceNode(resName.Item1, resName.Item2);
case ITypeDefinition type:
return assemblyListTreeNode.FindTypeNode(type);
case IField fd:
diff --git a/ILSpy/Search/AbstractEntitySearchStrategy.cs b/ILSpy/Search/AbstractEntitySearchStrategy.cs
index 57382846b..e969c69c3 100644
--- a/ILSpy/Search/AbstractEntitySearchStrategy.cs
+++ b/ILSpy/Search/AbstractEntitySearchStrategy.cs
@@ -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
}
}
- ImageSource GetIcon(IEntity member)
+ static internal ImageSource GetIcon(IEntity member)
{
switch (member) {
case ITypeDefinition t:
diff --git a/ILSpy/Search/AbstractSearchStrategy.cs b/ILSpy/Search/AbstractSearchStrategy.cs
index b87bc3aed..7af565262 100644
--- a/ILSpy/Search/AbstractSearchStrategy.cs
+++ b/ILSpy/Search/AbstractSearchStrategy.cs
@@ -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);
diff --git a/ILSpy/Search/ResourceSearchStrategy.cs b/ILSpy/Search/ResourceSearchStrategy.cs
index 5faea4ba4..5824afd96 100644
--- a/ILSpy/Search/ResourceSearchStrategy.cs
+++ b/ILSpy/Search/ResourceSearchStrategy.cs
@@ -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);
diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs
index 5901b47ca..f911fd3a6 100644
--- a/ILSpy/Search/SearchPane.cs
+++ b/ILSpy/Search/SearchPane.cs
@@ -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
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
}
}
- public sealed class SearchResult // : IMemberTreeNode
- {
- public static readonly System.Collections.Generic.IComparer Comparer = new SearchResultComparer();
-
- ImageSource image;
- ImageSource locationImage;
-
- public static readonly IComparer 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
- {
- 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
diff --git a/ILSpy/Search/SearchResult.cs b/ILSpy/Search/SearchResult.cs
new file mode 100644
index 000000000..eb78c0bef
--- /dev/null
+++ b/ILSpy/Search/SearchResult.cs
@@ -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 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
+ {
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/ILSpy/TreeNodes/AssemblyListTreeNode.cs b/ILSpy/TreeNodes/AssemblyListTreeNode.cs
index e53a3a883..b579b2930 100644
--- a/ILSpy/TreeNodes/AssemblyListTreeNode.cs
+++ b/ILSpy/TreeNodes/AssemblyListTreeNode.cs
@@ -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
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().Where(x => name.Equals(x.Text)).FirstOrDefault() ?? resourceNode;
+ }
+
public AssemblyTreeNode FindAssemblyNode(IModule module)
{
return FindAssemblyNode(module.PEFile);