Browse Source

Fix #2234: Implement support for nuget packages/bundles in search, analyzers and the derived types list.

pull/2320/head
Siegfried Pammer 4 years ago
parent
commit
feb623d602
  1. 11
      ILSpy/Analyzers/AnalyzerScope.cs
  2. 45
      ILSpy/AssemblyList.cs
  3. 6
      ILSpy/Search/SearchPane.cs
  4. 3
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs

11
ILSpy/Analyzers/AnalyzerScope.cs

@ -75,13 +75,8 @@ namespace ICSharpCode.ILSpy.Analyzers
public IEnumerable<PEFile> GetAllModules() public IEnumerable<PEFile> GetAllModules()
{ {
foreach (var module in AssemblyList.GetAssemblies()) return AssemblyList.GetAllAssemblies().GetAwaiter().GetResult()
{ .Select(asm => asm.GetPEFileOrNull());
var file = module.GetPEFileOrNull();
if (file == null)
continue;
yield return file;
}
} }
public IEnumerable<ITypeDefinition> GetTypesInScope(CancellationToken ct) public IEnumerable<ITypeDefinition> GetTypesInScope(CancellationToken ct)
@ -138,7 +133,7 @@ namespace ICSharpCode.ILSpy.Analyzers
do do
{ {
PEFile curFile = toWalkFiles.Pop(); PEFile curFile = toWalkFiles.Pop();
foreach (var assembly in AssemblyList.GetAssemblies()) foreach (var assembly in AssemblyList.GetAllAssemblies().GetAwaiter().GetResult())
{ {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
bool found = false; bool found = false;

45
ILSpy/AssemblyList.cs

@ -110,6 +110,48 @@ namespace ICSharpCode.ILSpy
} }
} }
/// <summary>
/// Gets all loaded assemblies recursively, including assemblies found in bundles or packages.
/// </summary>
public async Task<IList<LoadedAssembly>> GetAllAssemblies()
{
var assemblies = GetAssemblies();
var results = new List<LoadedAssembly>(assemblies.Length);
foreach (var asm in assemblies)
{
var result = await asm.GetLoadResultAsync();
if (result.Package != null)
{
AddDescendants(result.Package.RootFolder);
}
else if (result.PEFile != null)
{
results.Add(asm);
}
}
void AddDescendants(PackageFolder folder)
{
foreach (var subFolder in folder.Folders)
{
AddDescendants(subFolder);
}
foreach (var entry in folder.Entries)
{
if (!entry.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
continue;
var asm = folder.ResolveFileName(entry.Name);
if (asm == null)
continue;
results.Add(asm);
}
}
return results;
}
public int Count { public int Count {
get { get {
lock (lockObj) lock (lockObj)
@ -233,6 +275,7 @@ namespace ICSharpCode.ILSpy
/// </remarks> /// </remarks>
public LoadedAssembly OpenAssembly(string file, bool isAutoLoaded = false) public LoadedAssembly OpenAssembly(string file, bool isAutoLoaded = false)
{ {
file = Path.GetFullPath(file);
return OpenAssembly(file, () => { return OpenAssembly(file, () => {
var newAsm = new LoadedAssembly(this, file); var newAsm = new LoadedAssembly(this, file);
newAsm.IsAutoLoaded = isAutoLoaded; newAsm.IsAutoLoaded = isAutoLoaded;
@ -245,6 +288,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public LoadedAssembly OpenAssembly(string file, Stream stream, bool isAutoLoaded = false) public LoadedAssembly OpenAssembly(string file, Stream stream, bool isAutoLoaded = false)
{ {
file = Path.GetFullPath(file);
return OpenAssembly(file, () => { return OpenAssembly(file, () => {
var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream)); var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream));
newAsm.IsAutoLoaded = isAutoLoaded; newAsm.IsAutoLoaded = isAutoLoaded;
@ -254,7 +298,6 @@ namespace ICSharpCode.ILSpy
LoadedAssembly OpenAssembly(string file, Func<LoadedAssembly> load) LoadedAssembly OpenAssembly(string file, Func<LoadedAssembly> load)
{ {
file = Path.GetFullPath(file);
bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread; bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread;
LoadedAssembly asm; LoadedAssembly asm;

6
ILSpy/Search/SearchPane.cs

@ -237,7 +237,7 @@ namespace ICSharpCode.ILSpy
MainWindow mainWindow = MainWindow.Instance; MainWindow mainWindow = MainWindow.Instance;
searchProgressBar.IsIndeterminate = true; searchProgressBar.IsIndeterminate = true;
startedSearch = new RunningSearch(mainWindow.CurrentAssemblyList.GetAssemblies(), searchTerm, startedSearch = new RunningSearch(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage, (SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage,
mainWindow.SessionSettings.FilterSettings.ShowApiLevel); mainWindow.SessionSettings.FilterSettings.ShowApiLevel);
currentSearch = startedSearch; currentSearch = startedSearch;
@ -290,14 +290,14 @@ namespace ICSharpCode.ILSpy
sealed class RunningSearch sealed class RunningSearch
{ {
readonly CancellationTokenSource cts = new CancellationTokenSource(); readonly CancellationTokenSource cts = new CancellationTokenSource();
readonly LoadedAssembly[] assemblies; readonly IList<LoadedAssembly> assemblies;
readonly string[] searchTerm; readonly string[] searchTerm;
readonly SearchMode searchMode; readonly SearchMode searchMode;
readonly Language language; readonly Language language;
readonly ApiVisibility apiVisibility; readonly ApiVisibility apiVisibility;
public readonly IProducerConsumerCollection<SearchResult> resultQueue = new ConcurrentQueue<SearchResult>(); public readonly IProducerConsumerCollection<SearchResult> resultQueue = new ConcurrentQueue<SearchResult>();
public RunningSearch(LoadedAssembly[] assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility) public RunningSearch(IList<LoadedAssembly> assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility)
{ {
this.assemblies = assemblies; this.assemblies = assemblies;
this.searchTerm = NativeMethods.CommandLineToArgumentArray(searchTerm); this.searchTerm = NativeMethods.CommandLineToArgumentArray(searchTerm);

3
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -84,8 +84,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken ct) IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken ct)
{ {
// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread
var assemblies = list.GetAssemblies().Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray(); return DerivedTypesTreeNode.FindDerivedTypes(list, type, ct);
return DerivedTypesTreeNode.FindDerivedTypes(list, type, assemblies, ct);
} }
public override void ActivateItem(System.Windows.RoutedEventArgs e) public override void ActivateItem(System.Windows.RoutedEventArgs e)

Loading…
Cancel
Save