Browse Source

Reimplement search strategies.

pull/1030/head
Siegfried Pammer 7 years ago
parent
commit
7ded12c5fb
  1. 6
      ICSharpCode.Decompiler/SRMExtensions.cs
  2. 2
      ICSharpCode.Decompiler/Util/CollectionExtensions.cs
  3. 4
      ILSpy/ILSpy.csproj
  4. 5
      ILSpy/Languages/CSharpLanguage.cs
  5. 5
      ILSpy/Languages/Language.cs
  6. 129
      ILSpy/Search/AbstractSearchStrategy.cs
  7. 64
      ILSpy/Search/LiteralSearchStrategy.cs
  8. 124
      ILSpy/Search/MemberSearchStrategy.cs
  9. 35
      ILSpy/Search/MetadataTokenSearchStrategy.cs
  10. 53
      ILSpy/Search/SearchPane.cs
  11. 53
      ILSpy/Search/TypeAndMemberSearchStrategy.cs
  12. 34
      ILSpy/Search/TypeSearchStrategy.cs

6
ICSharpCode.Decompiler/SRMExtensions.cs

@ -333,7 +333,7 @@ namespace ICSharpCode.Decompiler @@ -333,7 +333,7 @@ namespace ICSharpCode.Decompiler
}
#endregion
public static unsafe SRM.BlobReader GetInitialValue(this FieldDefinition field, PEReader pefile, IDecompilerTypeSystem typeSystem)
public static unsafe SRM.BlobReader GetInitialValue(this FieldDefinition field, PEReader pefile, ICompilation typeSystem)
{
if (!field.HasFlag(FieldAttributes.HasFieldRVA) || field.GetRelativeVirtualAddress() == 0)
return default;
@ -346,9 +346,9 @@ namespace ICSharpCode.Decompiler @@ -346,9 +346,9 @@ namespace ICSharpCode.Decompiler
{
MetadataModule module;
public FieldValueSizeDecoder(IDecompilerTypeSystem typeSystem)
public FieldValueSizeDecoder(ICompilation typeSystem)
{
this.module = typeSystem.MainModule;
this.module = (MetadataModule)typeSystem.MainModule;
}
public int GetArrayType(int elementType, ArrayShape shape) => GetPrimitiveType(PrimitiveTypeCode.Object);

2
ICSharpCode.Decompiler/Util/CollectionExtensions.cs

@ -4,7 +4,7 @@ using System.Linq; @@ -4,7 +4,7 @@ using System.Linq;
namespace ICSharpCode.Decompiler.Util
{
static class CollectionExtensions
public static class CollectionExtensions
{
public static void Deconstruct<K, V>(this KeyValuePair<K, V> pair, out K key, out V value)
{

4
ILSpy/ILSpy.csproj

@ -204,7 +204,7 @@ @@ -204,7 +204,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Commands\SimpleCommand.cs" />
<Compile Include="Search\SearchStrategies.cs" />
<Compile Include="Search\AbstractSearchStrategy.cs" />
<Compile Include="TaskHelper.cs" />
<Compile Include="TextView\EditorCommands.cs" />
<Compile Include="TextView\FoldingCommands.cs" />
@ -235,9 +235,7 @@ @@ -235,9 +235,7 @@
<Compile Include="TreeNodes\ResourceNodes\XamlResourceNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\XmlResourceNode.cs" />
<Compile Include="TreeNodes\SearchMsdnContextMenuEntry.cs" />
<Compile Include="Search\TypeAndMemberSearchStrategy.cs" />
<Compile Include="Analyzers\Builtin\TypeExtensionMethodsAnalyzer.cs" />
<Compile Include="Search\TypeSearchStrategy.cs" />
<EmbeddedResource Include="..\doc\LGPL.txt">
<Link>LGPL.txt</Link>
</EmbeddedResource>

5
ILSpy/Languages/CSharpLanguage.cs

@ -555,6 +555,11 @@ namespace ICSharpCode.ILSpy @@ -555,6 +555,11 @@ namespace ICSharpCode.ILSpy
return buffer.ToString();
}
public override bool SearchCanUseILNames(string text)
{
return !text.Contains("<");
}
public override bool ShowMember(IEntity member)
{
PEFile assembly = member.ParentModule.PEFile;

5
ILSpy/Languages/Language.cs

@ -266,6 +266,11 @@ namespace ICSharpCode.ILSpy @@ -266,6 +266,11 @@ namespace ICSharpCode.ILSpy
return true;
}
public virtual bool SearchCanUseILNames(string text)
{
return true;
}
public virtual CodeMappingInfo GetCodeMappingInfo(PEFile module, SRM.EntityHandle member)
{
var parts = new Dictionary<SRM.MethodDefinitionHandle, SRM.MethodDefinitionHandle[]>();

129
ILSpy/Search/SearchStrategies.cs → ILSpy/Search/AbstractSearchStrategy.cs

@ -7,33 +7,45 @@ using ICSharpCode.ILSpy.TreeNodes; @@ -7,33 +7,45 @@ using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection;
using ICSharpCode.Decompiler.TypeSystem;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.Search
{
abstract class AbstractSearchStrategy
{
protected string[] searchTerm;
protected Regex regex;
protected bool fullNameSearch;
protected AbstractSearchStrategy(params string[] terms)
protected readonly (string Term, bool CanUseILNames)[] searchTerm;
protected readonly Regex regex;
protected readonly bool fullNameSearch;
protected readonly bool needsLanguageSpecificNames;
protected readonly Language language;
protected readonly Action<SearchResult> addResult;
protected AbstractSearchStrategy(Language language, Action<SearchResult> addResult, params string[] terms)
{
this.language = language;
this.addResult = addResult;
if (terms.Length == 1 && terms[0].Length > 2) {
var search = terms[0];
string search = terms[0];
if (search.StartsWith("/", StringComparison.Ordinal) && search.Length > 4) {
var regexString = search.Substring(1, search.Length - 1);
fullNameSearch = search.Contains("\\.");
if (regexString.EndsWith("/", StringComparison.Ordinal))
regexString = regexString.Substring(0, regexString.Length - 1);
regex = SafeNewRegex(regexString);
needsLanguageSpecificNames = true;
searchTerm = new[] { (search, false) };
} else {
fullNameSearch = search.Contains(".");
needsLanguageSpecificNames = fullNameSearch || !language.SearchCanUseILNames(search);
searchTerm = new[] { (search, !needsLanguageSpecificNames) };
}
terms[0] = search;
} else {
searchTerm = terms.SelectArray(t => (t, language.SearchCanUseILNames(t)));
needsLanguageSpecificNames = searchTerm.Any(t => !t.CanUseILNames);
}
searchTerm = terms;
}
protected float CalculateFitness(IEntity member)
@ -57,42 +69,17 @@ namespace ICSharpCode.ILSpy @@ -57,42 +69,17 @@ namespace ICSharpCode.ILSpy
return 1.0f / text.Length;
}
protected virtual bool IsMatch(IField field, Language language)
{
return false;
}
protected virtual bool IsMatch(IProperty property, Language language)
{
return false;
}
protected virtual bool IsMatch(IEvent ev, Language language)
{
return false;
}
protected virtual bool IsMatch(IMethod m, Language language)
{
return false;
}
protected virtual bool MatchName(IEntity m, Language language)
{
return IsMatch(t => GetLanguageSpecificName(language, m, regex != null ? fullNameSearch : t.Contains(".")));
}
protected virtual bool IsMatch(Func<string, string> getText)
protected virtual bool IsMatch(MetadataReader metadata, StringHandle nameHandle, string languageSpecificName)
{
if (regex != null) {
return regex.IsMatch(getText(""));
return regex.IsMatch(languageSpecificName);
}
for (int i = 0; i < searchTerm.Length; ++i) {
// How to handle overlapping matches?
var term = searchTerm[i];
var term = searchTerm[i].Term;
if (string.IsNullOrEmpty(term)) continue;
string text = getText(term);
string text = nameHandle.IsNil || !searchTerm[i].CanUseILNames || term.Contains(".") ? languageSpecificName : metadata.GetString(nameHandle);
switch (term[0]) {
case '+': // must contain
term = term.Substring(1);
@ -107,7 +94,8 @@ namespace ICSharpCode.ILSpy @@ -107,7 +94,8 @@ namespace ICSharpCode.ILSpy
if (equalCompareLength == -1)
equalCompareLength = text.Length;
if (term.Length > 1 && String.Compare(term, 1, text, 0, Math.Max(term.Length, equalCompareLength), StringComparison.OrdinalIgnoreCase) != 0)
if (term.Length > 1 && String.Compare(term, 1, text, 0, Math.Max(term.Length, equalCompareLength),
StringComparison.OrdinalIgnoreCase) != 0)
return false;
}
break;
@ -151,7 +139,7 @@ namespace ICSharpCode.ILSpy @@ -151,7 +139,7 @@ namespace ICSharpCode.ILSpy
return false;
}
string GetLanguageSpecificName(Language language, IEntity member, bool fullName = false)
protected string GetLanguageSpecificName(IEntity member, bool fullName)
{
switch (member) {
case ITypeDefinition t:
@ -169,39 +157,25 @@ namespace ICSharpCode.ILSpy @@ -169,39 +157,25 @@ namespace ICSharpCode.ILSpy
}
}
void Add<T>(Func<IEnumerable<T>> itemsGetter, ITypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : IEntity
protected ImageSource GetIcon(IEntity member)
{
IEnumerable<T> items = Enumerable.Empty<T>();
try {
items = itemsGetter();
} catch (Exception ex) {
System.Diagnostics.Debug.Print(ex.ToString());
}
foreach (var item in items) {
if (matcher(item, language)) {
addResult(new SearchResult {
Member = item,
Fitness = CalculateFitness(item),
Image = image(item),
Name = GetLanguageSpecificName(language, item),
LocationImage = TypeTreeNode.GetIcon(type),
Location = language.TypeToString(type, includeNamespace: true)
});
}
switch (member) {
case ITypeDefinition t:
return TypeTreeNode.GetIcon(t);
case IField f:
return FieldTreeNode.GetIcon(f);
case IProperty p:
return PropertyTreeNode.GetIcon(p);
case IMethod m:
return MethodTreeNode.GetIcon(m);
case IEvent e:
return EventTreeNode.GetIcon(e);
default:
throw new NotSupportedException(member?.GetType() + " not supported!");
}
}
public virtual void Search(ITypeDefinition type, Language language, Action<SearchResult> addResult)
{
Add(() => type.Fields, type, language, addResult, IsMatch, FieldTreeNode.GetIcon);
Add(() => type.Properties, type, language, addResult, IsMatch, p => PropertyTreeNode.GetIcon(p));
Add(() => type.Events, type, language, addResult, IsMatch, EventTreeNode.GetIcon);
Add(() => type.Methods.Where(m => !m.IsAccessor), type, language, addResult, IsMatch, MethodTreeNode.GetIcon);
foreach (var nestedType in type.NestedTypes) {
Search(nestedType, language, addResult);
}
}
public abstract void Search(PEFile module);
Regex SafeNewRegex(string unsafePattern)
{
@ -211,5 +185,18 @@ namespace ICSharpCode.ILSpy @@ -211,5 +185,18 @@ namespace ICSharpCode.ILSpy
return null;
}
}
protected SearchResult ResultFromEntity(IEntity item)
{
var declaringType = item.DeclaringTypeDefinition;
return new SearchResult {
Member = item,
Fitness = CalculateFitness(item),
Image = GetIcon(item),
Name = GetLanguageSpecificName(item, fullName: false),
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : item.Namespace
};
}
}
}

64
ILSpy/Search/LiteralSearchStrategy.cs

@ -7,19 +7,22 @@ using ICSharpCode.Decompiler; @@ -7,19 +7,22 @@ using ICSharpCode.Decompiler;
using static System.Reflection.Metadata.PEReaderExtensions;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.Search
{
class LiteralSearchStrategy : AbstractSearchStrategy
{
readonly TypeCode searchTermLiteralType;
readonly object searchTermLiteralValue;
public LiteralSearchStrategy(params string[] terms)
: base(terms)
public LiteralSearchStrategy(Language language, Action<SearchResult> addResult, params string[] terms)
: base(language, addResult, terms)
{
if (searchTerm.Length == 1) {
var lexer = new Lexer(new LATextReader(new System.IO.StringReader(searchTerm[0])));
if (terms.Length == 1) {
var lexer = new Lexer(new LATextReader(new System.IO.StringReader(terms[0])));
var value = lexer.NextToken();
if (value != null && value.LiteralValue != null) {
@ -47,27 +50,31 @@ namespace ICSharpCode.ILSpy @@ -47,27 +50,31 @@ namespace ICSharpCode.ILSpy
}
}
protected override bool IsMatch(IField field, Language language)
public override void Search(PEFile module)
{
return IsLiteralMatch(field.ConstantValue);
}
protected override bool IsMatch(IProperty property, Language language)
{
return MethodIsLiteralMatch(property.Getter) || MethodIsLiteralMatch(property.Setter);
}
var metadata = module.Metadata;
var typeSystem = module.GetTypeSystemOrNull();
if (typeSystem == null) return;
protected override bool IsMatch(IEvent ev, Language language)
{
return MethodIsLiteralMatch(ev.AddAccessor) || MethodIsLiteralMatch(ev.RemoveAccessor) || MethodIsLiteralMatch(ev.InvokeAccessor);
}
foreach (var handle in metadata.MethodDefinitions) {
var md = metadata.GetMethodDefinition(handle);
if (!md.HasBody() || !MethodIsLiteralMatch(module, md)) continue;
var method = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
addResult(ResultFromEntity(method));
}
protected override bool IsMatch(IMethod m, Language language)
{
return MethodIsLiteralMatch(m);
foreach (var handle in metadata.FieldDefinitions) {
var fd = metadata.GetFieldDefinition(handle);
if (!fd.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA) || !fd.HasFlag(System.Reflection.FieldAttributes.Literal))
continue;
// TODO
//fd.GetInitialValue(module.Reader, typeSystem);
//IField field = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
//addResult(ResultFromEntity(field));
}
}
bool IsLiteralMatch(object val)
bool IsLiteralMatch(PEFile module, object val)
{
if (val == null)
return false;
@ -84,21 +91,12 @@ namespace ICSharpCode.ILSpy @@ -84,21 +91,12 @@ namespace ICSharpCode.ILSpy
return searchTermLiteralValue.Equals(val);
default:
// substring search with searchTerm
return IsMatch(t => val.ToString());
return IsMatch(module.Metadata, MetadataTokens.StringHandle(0), val.ToString());
}
}
bool MethodIsLiteralMatch(IMethod method)
bool MethodIsLiteralMatch(PEFile module, MethodDefinition methodDefinition)
{
if (method == null)
return false;
var module = ((MetadataModule)method.ParentModule).PEFile;
var m = (SRM.MethodDefinitionHandle)method.MetadataToken;
if (m.IsNil)
return false;
var methodDefinition = module.Metadata.GetMethodDefinition(m);
if (!methodDefinition.HasBody())
return false;
var blob = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress).GetILReader();
if (searchTermLiteralType == TypeCode.Int64) {
long val = (long)searchTermLiteralValue;
@ -205,7 +203,7 @@ namespace ICSharpCode.ILSpy @@ -205,7 +203,7 @@ namespace ICSharpCode.ILSpy
ILParser.SkipOperand(ref blob, code);
continue;
}
if (base.IsMatch(t => ILParser.DecodeUserString(ref blob, module.Metadata)))
if (IsMatch(module.Metadata, MetadataTokens.StringHandle(0), ILParser.DecodeUserString(ref blob, module.Metadata)))
return true;
}
}

124
ILSpy/Search/MemberSearchStrategy.cs

@ -1,46 +1,128 @@ @@ -1,46 +1,128 @@
using ICSharpCode.Decompiler.TypeSystem;
using System;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.Search
{
class MemberSearchStrategy : AbstractSearchStrategy
{
MemberSearchKind searchKind;
readonly MemberSearchKind searchKind;
public MemberSearchStrategy(string term, MemberSearchKind searchKind = MemberSearchKind.All)
: this(new[] { term }, searchKind)
public MemberSearchStrategy(Language language, Action<SearchResult> addResult, string term, MemberSearchKind searchKind = MemberSearchKind.All)
: this(language, addResult, new[] { term }, searchKind)
{
}
public MemberSearchStrategy(string[] terms, MemberSearchKind searchKind = MemberSearchKind.All)
: base(terms)
public MemberSearchStrategy(Language language, Action<SearchResult> addResult, string[] terms, MemberSearchKind searchKind = MemberSearchKind.All)
: base(language, addResult, terms)
{
this.searchKind = searchKind;
}
protected override bool IsMatch(IField field, Language language)
public override void Search(PEFile module)
{
return (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Field) && MatchName(field, language);
}
var metadata = module.Metadata;
var typeSystem = module.GetTypeSystemOrNull();
if (typeSystem == null) return;
protected override bool IsMatch(IProperty property, Language language)
{
return (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Property) && MatchName(property, language);
}
if (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Type) {
foreach (var handle in metadata.TypeDefinitions) {
var td = metadata.GetTypeDefinition(handle);
string languageSpecificName = null;
ITypeDefinition type = null;
if (needsLanguageSpecificNames) {
type = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
languageSpecificName = GetLanguageSpecificName(type, fullName: true);
}
if (!IsMatch(module.Metadata, td.Name, languageSpecificName))
continue;
if (type == null) {
type = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
}
addResult(ResultFromEntity(type));
}
}
protected override bool IsMatch(IEvent ev, Language language)
{
return (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Event) && MatchName(ev, language);
}
if (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Method) {
foreach (var handle in metadata.MethodDefinitions) {
// TODO use method semantics to skip accessors
var md = metadata.GetMethodDefinition(handle);
string languageSpecificName = null;
IMethod method = null;
if (needsLanguageSpecificNames) {
method = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
languageSpecificName = GetLanguageSpecificName(method, fullName: true);
}
if (!IsMatch(module.Metadata, md.Name, languageSpecificName))
continue;
if (method == null) {
method = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
}
addResult(ResultFromEntity(method));
}
}
protected override bool IsMatch(IMethod m, Language language)
{
return (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Method) && MatchName(m, language);
if (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Field) {
foreach (var handle in metadata.FieldDefinitions) {
var fd = metadata.GetFieldDefinition(handle);
string languageSpecificName = null;
IField field = null;
if (needsLanguageSpecificNames) {
field = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
languageSpecificName = GetLanguageSpecificName(field, fullName: true);
}
if (!IsMatch(module.Metadata, fd.Name, languageSpecificName))
continue;
if (field == null) {
field = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
}
addResult(ResultFromEntity(field));
}
}
if (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Property) {
foreach (var handle in metadata.PropertyDefinitions) {
var pd = metadata.GetPropertyDefinition(handle);
string languageSpecificName = null;
IProperty property = null;
if (needsLanguageSpecificNames) {
property = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
languageSpecificName = GetLanguageSpecificName(property, fullName: true);
}
if (!IsMatch(module.Metadata, pd.Name, languageSpecificName))
continue;
if (property == null) {
property = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
}
addResult(ResultFromEntity(property));
}
}
if (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Event) {
foreach (var handle in metadata.EventDefinitions) {
var ed = metadata.GetEventDefinition(handle);
string languageSpecificName = null;
IEvent @event = null;
if (needsLanguageSpecificNames) {
@event = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
languageSpecificName = GetLanguageSpecificName(@event, fullName: true);
}
if (!IsMatch(module.Metadata, ed.Name, languageSpecificName))
continue;
if (@event == null) {
@event = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);
}
addResult(ResultFromEntity(@event));
}
}
}
}
enum MemberSearchKind
{
All,
Type,
Member,
Field,
Property,
Event,

35
ILSpy/Search/MetadataTokenSearchStrategy.cs

@ -1,24 +1,37 @@ @@ -1,24 +1,37 @@
using System.Globalization;
using SRM = System.Reflection.Metadata;
using System;
using System.Globalization;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.Search
{
class MetadataTokenSearchStrategy : TypeAndMemberSearchStrategy
class MetadataTokenSearchStrategy : AbstractSearchStrategy
{
readonly int searchTermToken;
readonly EntityHandle searchTermToken;
public MetadataTokenSearchStrategy(params string[] terms)
: base(terms)
public MetadataTokenSearchStrategy(Language language, Action<SearchResult> addResult, params string[] terms)
: base(language, addResult, terms)
{
if (searchTerm.Length == 1) {
int.TryParse(searchTerm[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out searchTermToken);
if (terms.Length == 1) {
int.TryParse(terms[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var token);
searchTermToken = MetadataTokenHelpers.EntityHandleOrNil(token);
}
}
protected override bool MatchName(IEntity m, Language language)
public override void Search(PEFile module)
{
return SRM.Ecma335.MetadataTokens.GetToken(m.MetadataToken) == searchTermToken;
if (searchTermToken.IsNil) return;
var typeSystem = module.GetTypeSystemOrNull();
if (typeSystem == null) return;
switch (searchTermToken.Kind) {
case HandleKind.TypeDefinition:
var type = ((MetadataModule)typeSystem.MainModule).GetDefinition((TypeDefinitionHandle)searchTermToken);
addResult(ResultFromEntity(type));
break;
}
}
}
}

53
ILSpy/Search/SearchPane.cs

@ -19,15 +19,14 @@ @@ -19,15 +19,14 @@
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy
@ -128,7 +127,8 @@ namespace ICSharpCode.ILSpy @@ -128,7 +127,8 @@ namespace ICSharpCode.ILSpy
listBox.ItemsSource = null;
} else {
MainWindow mainWindow = MainWindow.Instance;
currentSearch = new RunningSearch(mainWindow.CurrentAssemblyList.GetAssemblies(), searchTerm, (SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage);
currentSearch = new RunningSearch(mainWindow.CurrentAssemblyList.GetAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage);
listBox.ItemsSource = currentSearch.Results;
new Thread(currentSearch.Run).Start();
}
@ -216,16 +216,13 @@ namespace ICSharpCode.ILSpy @@ -216,16 +216,13 @@ namespace ICSharpCode.ILSpy
{
try {
var searcher = GetSearchStrategy(searchMode, searchTerm);
// TODO : parallelize
foreach (var loadedAssembly in assemblies) {
var typeSystem = loadedAssembly.GetTypeSystemOrNull();
if (typeSystem == null)
var module = loadedAssembly.GetPEFileOrNull();
if (module == null)
continue;
CancellationToken cancellationToken = cts.Token;
foreach (var type in typeSystem.MainModule.TopLevelTypeDefinitions) {
cancellationToken.ThrowIfCancellationRequested();
searcher.Search(type, language, AddResult);
}
searcher.Search(module);
}
} catch (OperationCanceledException) {
// ignore cancellation
@ -276,53 +273,53 @@ namespace ICSharpCode.ILSpy @@ -276,53 +273,53 @@ namespace ICSharpCode.ILSpy
{
if (terms.Length == 1) {
if (terms[0].StartsWith("tm:", StringComparison.Ordinal))
return new TypeAndMemberSearchStrategy(terms[0].Substring(3));
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(3));
if (terms[0].StartsWith("t:", StringComparison.Ordinal))
return new TypeSearchStrategy(terms[0].Substring(2));
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(2), MemberSearchKind.Type);
if (terms[0].StartsWith("m:", StringComparison.Ordinal))
return new MemberSearchStrategy(terms[0].Substring(2));
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(2), MemberSearchKind.Member);
if (terms[0].StartsWith("md:", StringComparison.Ordinal))
return new MemberSearchStrategy(terms[0].Substring(3), MemberSearchKind.Method);
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(3), MemberSearchKind.Method);
if (terms[0].StartsWith("f:", StringComparison.Ordinal))
return new MemberSearchStrategy(terms[0].Substring(2), MemberSearchKind.Field);
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(2), MemberSearchKind.Field);
if (terms[0].StartsWith("p:", StringComparison.Ordinal))
return new MemberSearchStrategy(terms[0].Substring(2), MemberSearchKind.Property);
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(2), MemberSearchKind.Property);
if (terms[0].StartsWith("e:", StringComparison.Ordinal))
return new MemberSearchStrategy(terms[0].Substring(2), MemberSearchKind.Event);
return new MemberSearchStrategy(language, AddResult, terms[0].Substring(2), MemberSearchKind.Event);
if (terms[0].StartsWith("c:", StringComparison.Ordinal))
return new LiteralSearchStrategy(terms[0].Substring(2));
return new LiteralSearchStrategy(language, AddResult, terms[0].Substring(2));
if (terms[0].StartsWith("@", StringComparison.Ordinal))
return new MetadataTokenSearchStrategy(terms[0].Substring(1));
return new MetadataTokenSearchStrategy(language, AddResult, terms[0].Substring(1));
}
switch (mode)
{
case SearchMode.TypeAndMember:
return new TypeAndMemberSearchStrategy(terms);
return new MemberSearchStrategy(language, AddResult, terms);
case SearchMode.Type:
return new TypeSearchStrategy(terms);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Type);
case SearchMode.Member:
return new MemberSearchStrategy(terms);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Member);
case SearchMode.Literal:
return new LiteralSearchStrategy(terms);
return new LiteralSearchStrategy(language, AddResult, terms);
case SearchMode.Method:
return new MemberSearchStrategy(terms, MemberSearchKind.Method);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Method);
case SearchMode.Field:
return new MemberSearchStrategy(terms, MemberSearchKind.Field);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Field);
case SearchMode.Property:
return new MemberSearchStrategy(terms, MemberSearchKind.Property);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Property);
case SearchMode.Event:
return new MemberSearchStrategy(terms, MemberSearchKind.Event);
return new MemberSearchStrategy(language, AddResult, terms, MemberSearchKind.Event);
case SearchMode.Token:
return new MetadataTokenSearchStrategy(terms);
return new MetadataTokenSearchStrategy(language, AddResult, terms);
}
return null;

53
ILSpy/Search/TypeAndMemberSearchStrategy.cs

@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
using System;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy
{
class TypeAndMemberSearchStrategy : AbstractSearchStrategy
{
public TypeAndMemberSearchStrategy(params string[] terms)
: base(terms)
{
}
public override void Search(ITypeDefinition type, Language language, Action<SearchResult> addResult)
{
if (MatchName(type, language))
{
string name = language.TypeToString(type, includeNamespace: false);
var declaringType = type.DeclaringTypeDefinition;
addResult(new SearchResult {
Member = type,
Image = TypeTreeNode.GetIcon(type),
Fitness = CalculateFitness(type),
Name = name,
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : type.Namespace
});
}
base.Search(type, language, addResult);
}
protected override bool IsMatch(IField field, Language language)
{
return MatchName(field, language);
}
protected override bool IsMatch(IProperty property, Language language)
{
return MatchName(property, language);
}
protected override bool IsMatch(IEvent ev, Language language)
{
return MatchName(ev, language);
}
protected override bool IsMatch(IMethod m, Language language)
{
return MatchName(m, language);
}
}
}

34
ILSpy/Search/TypeSearchStrategy.cs

@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
using System;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy
{
class TypeSearchStrategy : AbstractSearchStrategy
{
public TypeSearchStrategy(params string[] terms)
: base(terms)
{
}
public override void Search(ITypeDefinition type, Language language, Action<SearchResult> addResult)
{
if (MatchName(type, language)) {
string name = language.TypeToString(type, includeNamespace: false);
var declaringType = type.DeclaringTypeDefinition;
addResult(new SearchResult {
Member = type,
Fitness = CalculateFitness(type),
Image = TypeTreeNode.GetIcon(type),
Name = name,
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeToString(declaringType, includeNamespace: true) : type.Namespace
});
}
foreach (var nestedType in type.NestedTypes) {
Search(nestedType, language, addResult);
}
}
}
}
Loading…
Cancel
Save