diff --git a/ICSharpCode.ILSpyX/Abstractions/ILanguage.cs b/ICSharpCode.ILSpyX/Abstractions/ILanguage.cs new file mode 100644 index 000000000..1947b0cc3 --- /dev/null +++ b/ICSharpCode.ILSpyX/Abstractions/ILanguage.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2022 Siegfried Pammer +// +// 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 ICSharpCode.Decompiler.Metadata; +using ICSharpCode.Decompiler.TypeSystem; + +namespace ICSharpCode.ILSpyX.Abstractions +{ + public interface ILanguage + { + bool ShowMember(IEntity member); + string GetEntityName(PEFile module, System.Reflection.Metadata.EntityHandle handle, bool fullName, bool omitGenerics); + string GetTooltip(IEntity entity); + + string TypeToString(IType type, bool includeNamespace); + string MethodToString(IMethod method, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName); + string FieldToString(IField field, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName); + string PropertyToString(IProperty property, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName); + string EventToString(IEvent @event, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName); + } +} diff --git a/ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs b/ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs new file mode 100644 index 000000000..836e43e22 --- /dev/null +++ b/ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2022 Siegfried Pammer +// +// 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.Collections.Generic; + +using ICSharpCode.Decompiler.Metadata; + +namespace ICSharpCode.ILSpyX.Abstractions +{ + public interface ITreeNode + { + object Text { get; } + object Icon { get; } + IEnumerable Children { get; } + + void EnsureLazyChildren(); + } + + public interface IResourcesFileTreeNode : ITreeNode + { + Resource Resource { get; } + } + + public interface ITreeNodeFactory + { + ITreeNode CreateResourcesList(PEFile module); + ITreeNode Create(Resource resource); + } +} diff --git a/ICSharpCode.ILSpyX/ApiVisibility.cs b/ICSharpCode.ILSpyX/ApiVisibility.cs new file mode 100644 index 000000000..7ee9956c6 --- /dev/null +++ b/ICSharpCode.ILSpyX/ApiVisibility.cs @@ -0,0 +1,27 @@ +// 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. + +namespace ICSharpCode.ILSpyX +{ + public enum ApiVisibility + { + PublicOnly, + PublicAndInternal, + All + } +} diff --git a/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs index a8c46f3ea..8fe549b28 100644 --- a/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs +++ b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs @@ -1,6 +1,7 @@ using System; using System.IO; +using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; @@ -46,6 +47,11 @@ namespace ICSharpCode.ILSpyX return GetLoadedAssembly(file).GetTypeSystemOrNull(); } + public static ICompilation? GetTypeSystemWithDecompilerSettingsOrNull(this PEFile file, DecompilerSettings settings) + { + return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings)); + } + public static LoadedAssembly GetLoadedAssembly(this PEFile file) { if (file == null) diff --git a/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs new file mode 100644 index 000000000..1161a86c8 --- /dev/null +++ b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs @@ -0,0 +1,96 @@ +// 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.Concurrent; + +namespace ICSharpCode.ILSpyX.Search +{ + using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX.Abstractions; + + abstract class AbstractEntitySearchStrategy : AbstractSearchStrategy + { + protected readonly ILanguage language; + protected readonly ApiVisibility apiVisibility; + + protected AbstractEntitySearchStrategy(ILanguage language, ApiVisibility apiVisibility, + SearchRequest searchRequest, IProducerConsumerCollection resultQueue) + : base(searchRequest, resultQueue) + { + this.language = language; + this.apiVisibility = apiVisibility; + } + + protected bool CheckVisibility(IEntity entity) + { + if (apiVisibility == ApiVisibility.All) + return true; + + do + { + if (apiVisibility == ApiVisibility.PublicOnly) + { + if (!(entity.Accessibility == Accessibility.Public || + entity.Accessibility == Accessibility.Protected || + entity.Accessibility == Accessibility.ProtectedOrInternal)) + return false; + } + else if (apiVisibility == ApiVisibility.PublicAndInternal) + { + if (!language.ShowMember(entity)) + return false; + } + entity = entity.DeclaringTypeDefinition; + } + while (entity != null); + + return true; + } + + protected bool IsInNamespaceOrAssembly(IEntity entity) + { + if (searchRequest.InAssembly != null) + { + if (!entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly)) + { + return false; + } + } + + if (searchRequest.InNamespace != null) + { + if (searchRequest.InNamespace.Length == 0) + { + return entity.Namespace.Length == 0; + } + else if (!entity.Namespace.Contains(searchRequest.InNamespace)) + { + return false; + } + } + + return true; + } + + protected void OnFoundResult(IEntity entity) + { + OnFoundResult(searchRequest.SearchResultFactory.Create(entity)); + } + } +} diff --git a/ILSpy/Search/AbstractSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs similarity index 91% rename from ILSpy/Search/AbstractSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs index 987f6fe45..b56c787da 100644 --- a/ILSpy/Search/AbstractSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs @@ -21,12 +21,33 @@ using System.Collections.Concurrent; using System.Text.RegularExpressions; using System.Threading; +using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpyX.Abstractions; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { + public enum SearchMode + { + TypeAndMember, + Type, + Member, + Method, + Field, + Property, + Event, + Literal, + Token, + Resource, + Assembly, + Namespace + } + struct SearchRequest { + public DecompilerSettings DecompilerSettings; + public ITreeNodeFactory TreeNodeFactory; + public ISearchResultFactory SearchResultFactory; public SearchMode Mode; public AssemblySearchKind AssemblySearchKind; public MemberSearchKind MemberSearchKind; diff --git a/ILSpy/Search/AssemblySearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs similarity index 91% rename from ILSpy/Search/AssemblySearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs index c15a48a6c..0c9a4353c 100644 --- a/ILSpy/Search/AssemblySearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs @@ -22,7 +22,7 @@ using System.Threading; using ICSharpCode.Decompiler.Metadata; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class AssemblySearchStrategy : AbstractSearchStrategy { @@ -92,15 +92,7 @@ namespace ICSharpCode.ILSpy.Search void OnFoundResult(PEFile module) { - var result = new AssemblySearchResult { - Module = module, - Fitness = 1.0f / module.Name.Length, - Name = module.Name, - Location = module.FileName, - Assembly = module.FullName, - ToolTip = module.FileName, - }; - OnFoundResult(result); + OnFoundResult(searchRequest.SearchResultFactory.Create(module)); } } diff --git a/ILSpy/Languages/CSharpLexer.cs b/ICSharpCode.ILSpyX/Search/CSharpLexer.cs similarity index 99% rename from ILSpy/Languages/CSharpLexer.cs rename to ICSharpCode.ILSpyX/Search/CSharpLexer.cs index 9e5685ac8..ab689b95a 100644 --- a/ILSpy/Languages/CSharpLexer.cs +++ b/ICSharpCode.ILSpyX/Search/CSharpLexer.cs @@ -22,7 +22,7 @@ using System.Globalization; using System.IO; using System.Text; -namespace ICSharpCode.ILSpy +namespace ICSharpCode.ILSpyX.Search { class LATextReader : TextReader { @@ -76,8 +76,7 @@ namespace ICSharpCode.ILSpy OctalNumber, StringLiteral, VerbatimStringLiteral, - CharLiteral, - DateTimeLiteral + CharLiteral } class Literal diff --git a/ILSpy/Search/LiteralSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs similarity index 95% rename from ILSpy/Search/LiteralSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs index 57f0a3f28..a4c23a634 100644 --- a/ILSpy/Search/LiteralSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs @@ -25,19 +25,20 @@ using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; +using ICSharpCode.ILSpyX.Abstractions; using static System.Reflection.Metadata.PEReaderExtensions; using ILOpCode = System.Reflection.Metadata.ILOpCode; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class LiteralSearchStrategy : AbstractEntitySearchStrategy { readonly TypeCode searchTermLiteralType; readonly object searchTermLiteralValue; - public LiteralSearchStrategy(Language language, ApiVisibility apiVisibility, SearchRequest request, + public LiteralSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest request, IProducerConsumerCollection resultQueue) : base(language, apiVisibility, request, resultQueue) { @@ -78,7 +79,7 @@ namespace ICSharpCode.ILSpy.Search { cancellationToken.ThrowIfCancellationRequested(); var metadata = module.Metadata; - var typeSystem = module.GetTypeSystemWithCurrentOptionsOrNull(); + var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings); if (typeSystem == null) return; @@ -114,7 +115,7 @@ namespace ICSharpCode.ILSpy.Search } } - bool IsLiteralMatch(MetadataReader metadata, object val) + bool IsLiteralMatch(MetadataReader metadata, object? val) { if (val == null) return false; diff --git a/ILSpy/Search/MemberSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs similarity index 94% rename from ILSpy/Search/MemberSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs index 1ff3d5c3a..880362c01 100644 --- a/ILSpy/Search/MemberSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs @@ -21,14 +21,15 @@ using System.Threading; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpyX.Abstractions; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class MemberSearchStrategy : AbstractEntitySearchStrategy { readonly MemberSearchKind searchKind; - public MemberSearchStrategy(Language language, ApiVisibility apiVisibility, SearchRequest searchRequest, + public MemberSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest searchRequest, IProducerConsumerCollection resultQueue, MemberSearchKind searchKind = MemberSearchKind.All) : base(language, apiVisibility, searchRequest, resultQueue) { @@ -39,7 +40,7 @@ namespace ICSharpCode.ILSpy.Search { cancellationToken.ThrowIfCancellationRequested(); var metadata = module.Metadata; - var typeSystem = module.GetTypeSystemWithCurrentOptionsOrNull(); + var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings); if (typeSystem == null) return; diff --git a/ILSpy/Search/MetadataTokenSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs similarity index 93% rename from ILSpy/Search/MetadataTokenSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs index 278e26a40..865874dd7 100644 --- a/ILSpy/Search/MetadataTokenSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs @@ -24,14 +24,15 @@ using System.Threading; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpyX.Abstractions; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class MetadataTokenSearchStrategy : AbstractEntitySearchStrategy { readonly EntityHandle searchTermToken; - public MetadataTokenSearchStrategy(Language language, ApiVisibility apiVisibility, SearchRequest request, + public MetadataTokenSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest request, IProducerConsumerCollection resultQueue) : base(language, apiVisibility, request, resultQueue) { @@ -48,7 +49,7 @@ namespace ICSharpCode.ILSpy.Search cancellationToken.ThrowIfCancellationRequested(); if (searchTermToken.IsNil) return; - var typeSystem = module.GetTypeSystemWithCurrentOptionsOrNull(); + var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings); if (typeSystem == null) return; var metadataModule = (MetadataModule)typeSystem.MainModule; diff --git a/ILSpy/Search/NamespaceSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs similarity index 85% rename from ILSpy/Search/NamespaceSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs index 8da1ce3cc..21a3fa040 100644 --- a/ILSpy/Search/NamespaceSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs @@ -24,7 +24,7 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class NamespaceSearchStrategy : AbstractSearchStrategy { @@ -36,7 +36,7 @@ namespace ICSharpCode.ILSpy.Search public override void Search(PEFile module, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var typeSystem = module.GetTypeSystemWithCurrentOptionsOrNull(); + var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings); if (typeSystem == null) return; @@ -58,15 +58,7 @@ namespace ICSharpCode.ILSpy.Search 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); + OnFoundResult(searchRequest.SearchResultFactory.Create(module, ns)); } } } \ No newline at end of file diff --git a/ILSpy/Search/ResourceSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs similarity index 72% rename from ILSpy/Search/ResourceSearchStrategy.cs rename to ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs index 39967538d..b7359eb8c 100644 --- a/ILSpy/Search/ResourceSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs @@ -19,22 +19,22 @@ using System; using System.Collections.Concurrent; using System.Reflection; using System.Threading; -using System.Windows.Media; using ICSharpCode.Decompiler.Metadata; -using ICSharpCode.ILSpy.TreeNodes; -using ICSharpCode.TreeView; +using ICSharpCode.ILSpyX.Abstractions; -namespace ICSharpCode.ILSpy.Search +namespace ICSharpCode.ILSpyX.Search { class ResourceSearchStrategy : AbstractSearchStrategy { protected readonly bool searchInside; protected readonly ApiVisibility apiVisibility; + protected readonly ITreeNodeFactory treeNodeFactory; public ResourceSearchStrategy(ApiVisibility apiVisibility, SearchRequest request, IProducerConsumerCollection resultQueue) : base(request, resultQueue) { + this.treeNodeFactory = request.TreeNodeFactory; this.apiVisibility = apiVisibility; this.searchInside = true; } @@ -53,24 +53,24 @@ namespace ICSharpCode.ILSpy.Search public override void Search(PEFile module, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var resourcesNode = new ResourceListTreeNode(module); + var resourcesNode = treeNodeFactory.CreateResourcesList(module); foreach (Resource resource in module.Resources) - Search(module, resource, resourcesNode, ResourceTreeNode.Create(resource), cancellationToken); + Search(module, resource, resourcesNode, treeNodeFactory.Create(resource), cancellationToken); } - void Search(PEFile module, Resource resource, SharpTreeNode parent, SharpTreeNode node, CancellationToken cancellationToken) + void Search(PEFile module, Resource resource, ITreeNode parent, ITreeNode node, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - if (node is ResourceTreeNode treeNode) + if (node is IResourcesFileTreeNode treeNode) { if (!CheckVisibility(treeNode.Resource)) return; resource = treeNode.Resource; } - if (node.Text != null && IsMatch((string)node.Text)) + if (node.Text is string s && IsMatch(s)) OnFoundResult(module, resource, node, parent); if (!searchInside) @@ -81,20 +81,9 @@ namespace ICSharpCode.ILSpy.Search Search(module, resource, node, child, cancellationToken); } - void OnFoundResult(PEFile module, Resource resource, SharpTreeNode node, SharpTreeNode parent) + void OnFoundResult(PEFile module, Resource resource, ITreeNode node, ITreeNode parent) { - var name = (string)node.Text; - 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, - Assembly = module.FullName, - ToolTip = module.FileName, - }; - OnFoundResult(result); + OnFoundResult(searchRequest.SearchResultFactory.Create(module, resource, node, parent)); } } } diff --git a/ILSpy/Search/SearchResult.cs b/ICSharpCode.ILSpyX/Search/SearchResult.cs similarity index 68% rename from ILSpy/Search/SearchResult.cs rename to ICSharpCode.ILSpyX/Search/SearchResult.cs index 124a2fe7d..d0e94bf40 100644 --- a/ILSpy/Search/SearchResult.cs +++ b/ICSharpCode.ILSpyX/Search/SearchResult.cs @@ -18,40 +18,38 @@ 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; +using ICSharpCode.ILSpyX.Abstractions; -namespace ICSharpCode.ILSpy +namespace ICSharpCode.ILSpyX.Search { + public interface ISearchResultFactory + { + MemberSearchResult Create(IEntity entity); + ResourceSearchResult Create(PEFile module, Resource resource, ITreeNode node, ITreeNode parent); + AssemblySearchResult Create(PEFile module); + NamespaceSearchResult Create(PEFile module, INamespace @namespace); + } + public class SearchResult { public static readonly IComparer ComparerByName = new SearchResultNameComparer(); public static readonly IComparer ComparerByFitness = new SearchResultFitnessComparer(); - public virtual object Reference { - get { - return null; - } - } + public virtual object? Reference => 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 object? ToolTip { get; set; } + public object Image { get; set; } + public object LocationImage { get; set; } - public ImageSource AssemblyImage { - get { - return Images.Assembly; - } - } + public object AssemblyImage { get; set; } public override string ToString() { @@ -60,7 +58,7 @@ namespace ICSharpCode.ILSpy class SearchResultNameComparer : IComparer { - public int Compare(SearchResult x, SearchResult y) + public int Compare(SearchResult? x, SearchResult? y) { return StringComparer.Ordinal.Compare(x?.Name ?? "", y?.Name ?? ""); } @@ -68,7 +66,7 @@ namespace ICSharpCode.ILSpy class SearchResultFitnessComparer : IComparer { - public int Compare(SearchResult x, SearchResult y) + public int Compare(SearchResult? x, SearchResult? y) { //elements with higher Fitness come first return Comparer.Default.Compare(y?.Fitness ?? 0, x?.Fitness ?? 0); @@ -80,26 +78,6 @@ namespace ICSharpCode.ILSpy { 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 @@ -112,17 +90,11 @@ namespace ICSharpCode.ILSpy { public PEFile Module { get; set; } public override object Reference => Module; - - 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.BamlDecompiler/BamlResourceNodeFactory.cs b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs index c5f086342..8a12280d2 100644 --- a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs +++ b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs @@ -24,13 +24,14 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpyX; +using ICSharpCode.ILSpyX.Abstractions; namespace ILSpy.BamlDecompiler { [Export(typeof(IResourceNodeFactory))] public sealed class BamlResourceNodeFactory : IResourceNodeFactory { - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { if (resource.Name.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) return new BamlResourceEntryNode(resource.Name, resource.TryOpenStream); diff --git a/ILSpy/ContextMenuEntry.cs b/ILSpy/ContextMenuEntry.cs index f13d6749c..73aa3ba73 100644 --- a/ILSpy/ContextMenuEntry.cs +++ b/ILSpy/ContextMenuEntry.cs @@ -27,6 +27,7 @@ using System.Windows.Media; using ICSharpCode.AvalonEdit; using ICSharpCode.ILSpy.TextView; +using ICSharpCode.ILSpyX.Search; using ICSharpCode.TreeView; namespace ICSharpCode.ILSpy diff --git a/ILSpy/FilterSettings.cs b/ILSpy/FilterSettings.cs index cc0aa4b05..6adb3200d 100644 --- a/ILSpy/FilterSettings.cs +++ b/ILSpy/FilterSettings.cs @@ -23,6 +23,8 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Xml.Linq; +using ICSharpCode.ILSpyX; + namespace ICSharpCode.ILSpy { /// @@ -220,11 +222,4 @@ namespace ICSharpCode.ILSpy return f; } } - - public enum ApiVisibility - { - PublicOnly, - PublicAndInternal, - All - } } diff --git a/ILSpy/Languages/Language.cs b/ILSpy/Languages/Language.cs index 0b7cc48e8..ecf626dbd 100644 --- a/ILSpy/Languages/Language.cs +++ b/ILSpy/Languages/Language.cs @@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem.Implementation; using ICSharpCode.Decompiler.Util; using ICSharpCode.ILSpyX; +using ICSharpCode.ILSpyX.Abstractions; using SRM = System.Reflection.Metadata; @@ -58,7 +59,7 @@ namespace ICSharpCode.ILSpy /// /// Implementations of this class must be thread-safe. /// - public abstract class Language + public abstract class Language : ILanguage { /// /// Gets the name of the language (as shown in the UI) diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml index 13708177d..bf9860abe 100644 --- a/ILSpy/MainWindow.xaml +++ b/ILSpy/MainWindow.xaml @@ -4,6 +4,7 @@ x:ClassModifier="public" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tv="clr-namespace:ICSharpCode.TreeView;assembly=ICSharpCode.TreeView" xmlns:local="clr-namespace:ICSharpCode.ILSpy" + xmlns:search="clr-namespace:ICSharpCode.ILSpy.Search" xmlns:avalondock="https://github.com/Dirkster99/AvalonDock" xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls" xmlns:docking="clr-namespace:ICSharpCode.ILSpy.Docking" @@ -75,7 +76,7 @@ - + diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index 69920b960..89bcbf5a0 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -45,6 +45,7 @@ using ICSharpCode.Decompiler.TypeSystem.Implementation; using ICSharpCode.ILSpy.Analyzers; using ICSharpCode.ILSpy.Commands; using ICSharpCode.ILSpy.Docking; +using ICSharpCode.ILSpy.Search; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.Themes; using ICSharpCode.ILSpy.TreeNodes; diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index 7f81b1972..61b81a1b4 100644 --- a/ILSpy/Search/SearchPane.cs +++ b/ILSpy/Search/SearchPane.cs @@ -35,12 +35,12 @@ using System.Windows.Threading; using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Options; -using ICSharpCode.ILSpy.Search; using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX.Extensions; +using ICSharpCode.ILSpyX.Search; -namespace ICSharpCode.ILSpy +namespace ICSharpCode.ILSpy.Search { /// /// Search pane @@ -447,6 +447,9 @@ namespace ICSharpCode.ILSpy request.Keywords = keywords.ToArray(); request.RegEx = regex; + request.SearchResultFactory = new SearchResultFactory(language); + request.TreeNodeFactory = new TreeNodeFactory(); + request.DecompilerSettings = new DecompilationOptions().DecompilerSettings; return request; } @@ -536,20 +539,4 @@ namespace ICSharpCode.ILSpy NavigationCommands.Search.InputGestures.Add(new KeyGesture(Key.E, ModifierKeys.Control)); } } - - public enum SearchMode - { - TypeAndMember, - Type, - Member, - Method, - Field, - Property, - Event, - Literal, - Token, - Resource, - Assembly, - Namespace - } } \ No newline at end of file diff --git a/ILSpy/Search/SearchPane.xaml b/ILSpy/Search/SearchPane.xaml index c8d9bf116..a77da7334 100644 --- a/ILSpy/Search/SearchPane.xaml +++ b/ILSpy/Search/SearchPane.xaml @@ -1,4 +1,4 @@ - resultQueue) - : base(searchRequest, resultQueue) + public SearchResultFactory(Language language) { this.language = language; - this.apiVisibility = apiVisibility; - } - - protected bool CheckVisibility(IEntity entity) - { - if (apiVisibility == ApiVisibility.All) - return true; - - do - { - if (apiVisibility == ApiVisibility.PublicOnly) - { - if (!(entity.Accessibility == Accessibility.Public || - entity.Accessibility == Accessibility.Protected || - entity.Accessibility == Accessibility.ProtectedOrInternal)) - return false; - } - else if (apiVisibility == ApiVisibility.PublicAndInternal) - { - if (!language.ShowMember(entity)) - return false; - } - entity = entity.DeclaringTypeDefinition; - } - while (entity != null); - - return true; - } - - protected bool IsInNamespaceOrAssembly(IEntity entity) - { - if (searchRequest.InAssembly != null) - { - if (!entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly)) - { - return false; - } - } - - if (searchRequest.InNamespace != null) - { - if (searchRequest.InNamespace.Length == 0) - { - return entity.Namespace.Length == 0; - } - else if (!entity.Namespace.Contains(searchRequest.InNamespace)) - { - return false; - } - } - - return true; - } - - protected void OnFoundResult(IEntity entity) - { - var result = ResultFromEntity(entity); - OnFoundResult(result); - } - - SearchResult ResultFromEntity(IEntity item) - { - var declaringType = item.DeclaringTypeDefinition; - return new MemberSearchResult { - Member = item, - Fitness = CalculateFitness(item), - Name = GetLanguageSpecificName(item), - Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : item.Namespace, - Assembly = item.ParentModule.FullAssemblyName, - ToolTip = item.ParentModule.PEFile?.FileName - }; } float CalculateFitness(IEntity member) @@ -151,7 +77,7 @@ namespace ICSharpCode.ILSpy.Search } } - static internal ImageSource GetIcon(IEntity member) + static ImageSource GetIcon(IEntity member) { switch (member) { @@ -169,5 +95,79 @@ namespace ICSharpCode.ILSpy.Search throw new NotSupportedException(member?.GetType() + " not supported!"); } } + + public MemberSearchResult Create(IEntity entity) + { + var declaringType = entity.DeclaringTypeDefinition; + return new MemberSearchResult { + Member = entity, + Fitness = CalculateFitness(entity), + Name = GetLanguageSpecificName(entity), + Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : entity.Namespace, + Assembly = entity.ParentModule.FullAssemblyName, + ToolTip = entity.ParentModule.PEFile?.FileName, + Image = Images.Assembly, + LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace, + AssemblyImage = Images.Assembly, + }; + } + + public ResourceSearchResult Create(PEFile module, Resource resource, ITreeNode node, ITreeNode parent) + { + return new ResourceSearchResult { + Resource = resource, + Fitness = 1.0f / resource.Name.Length, + Image = node.Icon, + Name = resource.Name, + LocationImage = parent.Icon, + Location = (string)parent.Text, + Assembly = module.FullName, + ToolTip = module.FileName, + AssemblyImage = Images.Assembly, + }; + } + + public AssemblySearchResult Create(PEFile module) + { + return new AssemblySearchResult { + Module = module, + Fitness = 1.0f / module.Name.Length, + Name = module.Name, + Location = module.FileName, + Assembly = module.FullName, + ToolTip = module.FileName, + Image = Images.Assembly, + LocationImage = Images.Library, + AssemblyImage = Images.Assembly, + }; + } + + public NamespaceSearchResult Create(PEFile module, INamespace ns) + { + var name = ns.FullName.Length == 0 ? "-" : ns.FullName; + return new NamespaceSearchResult { + Namespace = ns, + Name = name, + Fitness = 1.0f / name.Length, + Location = module.Name, + Assembly = module.FullName, + Image = Images.Namespace, + LocationImage = Images.Assembly, + AssemblyImage = Images.Assembly, + }; + } + } + + internal class TreeNodeFactory : ITreeNodeFactory + { + public ITreeNode Create(Resource resource) + { + return ResourceTreeNode.Create(resource); + } + + public ITreeNode CreateResourcesList(PEFile module) + { + return new ResourceListTreeNode(module); + } } } diff --git a/ILSpy/SessionSettings.cs b/ILSpy/SessionSettings.cs index 6fa003ff3..f02e56ee9 100644 --- a/ILSpy/SessionSettings.cs +++ b/ILSpy/SessionSettings.cs @@ -28,6 +28,7 @@ using System.Xml.Linq; using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Themes; +using ICSharpCode.ILSpyX.Search; namespace ICSharpCode.ILSpy { diff --git a/ILSpy/TreeNodes/EventTreeNode.cs b/ILSpy/TreeNodes/EventTreeNode.cs index 9362fac6e..9f73940f9 100644 --- a/ILSpy/TreeNodes/EventTreeNode.cs +++ b/ILSpy/TreeNodes/EventTreeNode.cs @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler; namespace ICSharpCode.ILSpy.TreeNodes { using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX; /// /// Represents an event in the TreeView. diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs index 3a11cbefb..3219abcd5 100644 --- a/ILSpy/TreeNodes/FieldTreeNode.cs +++ b/ILSpy/TreeNodes/FieldTreeNode.cs @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler; namespace ICSharpCode.ILSpy.TreeNodes { using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX; /// /// Represents a field in the TreeView. diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs index d4672fd6b..8bc68dabe 100644 --- a/ILSpy/TreeNodes/ILSpyTreeNode.cs +++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; @@ -28,6 +29,7 @@ using System.Windows.Threading; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.Options; +using ICSharpCode.ILSpyX.Abstractions; using ICSharpCode.TreeView; namespace ICSharpCode.ILSpy.TreeNodes @@ -35,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes /// /// Base class of all ILSpy tree nodes. /// - public abstract class ILSpyTreeNode : SharpTreeNode + public abstract class ILSpyTreeNode : SharpTreeNode, ITreeNode { FilterSettings filterSettings; bool childrenNeedFiltering; @@ -202,5 +204,7 @@ namespace ICSharpCode.ILSpy.TreeNodes public virtual bool IsAutoLoaded { get { return false; } } + + IEnumerable ITreeNode.Children => this.Children.OfType(); } } \ No newline at end of file diff --git a/ILSpy/TreeNodes/MethodTreeNode.cs b/ILSpy/TreeNodes/MethodTreeNode.cs index 28e4cfa30..03bd8bd1e 100644 --- a/ILSpy/TreeNodes/MethodTreeNode.cs +++ b/ILSpy/TreeNodes/MethodTreeNode.cs @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler; namespace ICSharpCode.ILSpy.TreeNodes { using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX; /// /// Tree Node representing a field, method, property, or event. diff --git a/ILSpy/TreeNodes/PropertyTreeNode.cs b/ILSpy/TreeNodes/PropertyTreeNode.cs index 694a31c4c..a495c6e79 100644 --- a/ILSpy/TreeNodes/PropertyTreeNode.cs +++ b/ILSpy/TreeNodes/PropertyTreeNode.cs @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler; namespace ICSharpCode.ILSpy.TreeNodes { using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX; /// /// Represents a property in the TreeView. diff --git a/ILSpy/TreeNodes/ResourceListTreeNode.cs b/ILSpy/TreeNodes/ResourceListTreeNode.cs index c753b14dd..5b5b80b33 100644 --- a/ILSpy/TreeNodes/ResourceListTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceListTreeNode.cs @@ -23,6 +23,7 @@ using System.Windows.Threading; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.Properties; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { diff --git a/ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs index dfe12d2af..b1e86026e 100644 --- a/ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { @@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { static readonly string[] imageFileExtensions = { ".cur" }; - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { string key = resource.Name; foreach (string fileExt in imageFileExtensions) diff --git a/ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs b/ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs index 94a3ce3cd..a9dba6c6f 100644 --- a/ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs +++ b/ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { @@ -25,6 +26,6 @@ namespace ICSharpCode.ILSpy.TreeNodes /// public interface IResourceNodeFactory { - ILSpyTreeNode CreateNode(Resource resource); + ITreeNode CreateNode(Resource resource); } } diff --git a/ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs index f886cf2b3..52716233d 100644 --- a/ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs @@ -26,13 +26,14 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { [Export(typeof(IResourceNodeFactory))] sealed class IconResourceNodeFactory : IResourceNodeFactory { - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { if (resource.Name.EndsWith(".ico", StringComparison.OrdinalIgnoreCase)) { diff --git a/ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs index 4a8a6f395..e3646c807 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs @@ -23,13 +23,14 @@ using System.Windows.Forms; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { [Export(typeof(IResourceNodeFactory))] sealed class ImageListResourceEntryNodeFactory : IResourceNodeFactory { - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { return null; } diff --git a/ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs index e03f56df3..719653af1 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.TreeNodes { @@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { static readonly string[] imageFileExtensions = { ".png", ".gif", ".bmp", ".jpg" }; - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { string key = resource.Name; foreach (string fileExt in imageFileExtensions) diff --git a/ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs index 52271e845..a130b2027 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs @@ -22,6 +22,7 @@ using System.IO; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpyX.Abstractions; using Microsoft.Win32; @@ -59,7 +60,7 @@ namespace ICSharpCode.ILSpy.TreeNodes ILSpyTreeNode result = null; foreach (var factory in App.ExportProvider.GetExportedValues()) { - result = factory.CreateNode(resource); + result = factory.CreateNode(resource) as ILSpyTreeNode; if (result != null) break; } diff --git a/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs b/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs index ce862a523..c0a797a86 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs @@ -29,6 +29,8 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX; +using ICSharpCode.ILSpyX.Abstractions; using Microsoft.Win32; @@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.TreeNodes /// This is the default resource entry tree node, which is used if no specific /// exists for the given resource type. /// - public class ResourceTreeNode : ILSpyTreeNode + public class ResourceTreeNode : ILSpyTreeNode, IResourcesFileTreeNode { public ResourceTreeNode(Resource r) { diff --git a/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs b/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs index bdef592c7..5c0548f73 100644 --- a/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs @@ -31,6 +31,7 @@ using ICSharpCode.ILSpy.Controls; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; using Microsoft.Win32; @@ -39,7 +40,7 @@ namespace ICSharpCode.ILSpy.TreeNodes [Export(typeof(IResourceNodeFactory))] sealed class ResourcesFileTreeNodeFactory : IResourceNodeFactory { - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { if (resource.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase)) { @@ -54,7 +55,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } } - sealed class ResourcesFileTreeNode : ResourceTreeNode + sealed class ResourcesFileTreeNode : ResourceTreeNode, IResourcesFileTreeNode { readonly ICollection> stringTableEntries = new ObservableCollection>(); readonly ICollection otherEntries = new ObservableCollection(); diff --git a/ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs b/ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs index a673ea074..5faa3e186 100644 --- a/ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs @@ -26,13 +26,14 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.Xaml { [Export(typeof(IResourceNodeFactory))] sealed class XamlResourceNodeFactory : IResourceNodeFactory { - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { if (resource.Name.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)) return new XamlResourceEntryNode(resource.Name, resource.TryOpenStream); diff --git a/ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs b/ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs index 3d544e13b..cdc154b90 100644 --- a/ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs +++ b/ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.ILSpyX.Abstractions; namespace ICSharpCode.ILSpy.Xaml { @@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.Xaml { private readonly static string[] xmlFileExtensions = { ".xml", ".xsd", ".xslt" }; - public ILSpyTreeNode CreateNode(Resource resource) + public ITreeNode CreateNode(Resource resource) { string key = resource.Name; foreach (string fileExt in xmlFileExtensions) diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index c0edd649e..83126d88c 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -27,6 +27,7 @@ using SRM = System.Reflection.Metadata; namespace ICSharpCode.ILSpy.TreeNodes { using ICSharpCode.Decompiler.TypeSystem; + using ICSharpCode.ILSpyX; public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode {