Browse Source

Add support for resolving WinRT metadata.

pull/205/merge
Daniel Grunwald 14 years ago
parent
commit
21f6f01b36
  1. 11
      ILSpy/AssemblyList.cs
  2. 7
      ILSpy/Languages/Language.cs
  3. 38
      ILSpy/LoadedAssembly.cs
  4. 2
      ILSpy/MainWindow.xaml.cs
  5. 10
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

11
ILSpy/AssemblyList.cs

@ -42,6 +42,7 @@ namespace ICSharpCode.ILSpy @@ -42,6 +42,7 @@ namespace ICSharpCode.ILSpy
bool dirty;
internal readonly ConcurrentDictionary<string, LoadedAssembly> assemblyLookupCache = new ConcurrentDictionary<string, LoadedAssembly>();
internal readonly ConcurrentDictionary<string, LoadedAssembly> winRTMetadataLookupCache = new ConcurrentDictionary<string, LoadedAssembly>();
/// <summary>
/// The assemblies in this list.
@ -103,7 +104,7 @@ namespace ICSharpCode.ILSpy @@ -103,7 +104,7 @@ namespace ICSharpCode.ILSpy
void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
assemblyLookupCache.Clear();
ClearCache();
// Whenever the assembly list is modified, mark it as dirty
// and enqueue a task that saves it once the UI has finished modifying the assembly list.
if (!dirty) {
@ -114,12 +115,18 @@ namespace ICSharpCode.ILSpy @@ -114,12 +115,18 @@ namespace ICSharpCode.ILSpy
delegate {
dirty = false;
AssemblyListManager.SaveList(this);
assemblyLookupCache.Clear();
ClearCache();
})
);
}
}
internal void ClearCache()
{
assemblyLookupCache.Clear();
winRTMetadataLookupCache.Clear();
}
/// <summary>
/// Opens an assembly from disk.
/// Returns the existing assembly node if it is already loaded.

7
ILSpy/Languages/Language.cs

@ -127,7 +127,12 @@ namespace ICSharpCode.ILSpy @@ -127,7 +127,12 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, assembly.FileName);
WriteCommentLine(output, assembly.AssemblyDefinition.FullName);
var name = assembly.AssemblyDefinition.Name;
if ((name.Attributes & (AssemblyAttributes)0x0200) != 0) {
WriteCommentLine(output, name.Name + " [WinRT]");
} else {
WriteCommentLine(output, name.FullName);
}
}
public virtual void WriteCommentLine(ITextOutput output, string comment)

38
ILSpy/LoadedAssembly.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.ILSpy @@ -135,7 +135,7 @@ namespace ICSharpCode.ILSpy
disposed = true;
assemblyLoadDisableCount--;
// clear the lookup cache since we might have stored the lookups failed due to DisableAssemblyLoad()
MainWindow.Instance.CurrentAssemblyList.assemblyLookupCache.Clear();
MainWindow.Instance.CurrentAssemblyList.ClearCache();
}
}
}
@ -151,13 +151,13 @@ namespace ICSharpCode.ILSpy @@ -151,13 +151,13 @@ namespace ICSharpCode.ILSpy
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
var node = parent.LookupReferencedAssembly(name.FullName);
var node = parent.LookupReferencedAssembly(name);
return node != null ? node.AssemblyDefinition : null;
}
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{
var node = parent.LookupReferencedAssembly(name.FullName);
var node = parent.LookupReferencedAssembly(name);
return node != null ? node.AssemblyDefinition : null;
}
@ -179,6 +179,17 @@ namespace ICSharpCode.ILSpy @@ -179,6 +179,17 @@ namespace ICSharpCode.ILSpy
return new MyAssemblyResolver(this);
}
public LoadedAssembly LookupReferencedAssembly(AssemblyNameReference name)
{
if (name == null)
throw new ArgumentNullException("name");
if ((name.Attributes & (AssemblyAttributes)0x0200) != 0) {
return assemblyList.winRTMetadataLookupCache.GetOrAdd(name.Name, LookupWinRTMetadata);
} else {
return assemblyList.assemblyLookupCache.GetOrAdd(name.FullName, LookupReferencedAssemblyInternal);
}
}
public LoadedAssembly LookupReferencedAssembly(string fullName)
{
return assemblyList.assemblyLookupCache.GetOrAdd(fullName, LookupReferencedAssemblyInternal);
@ -214,6 +225,27 @@ namespace ICSharpCode.ILSpy @@ -214,6 +225,27 @@ namespace ICSharpCode.ILSpy
}
}
LoadedAssembly LookupWinRTMetadata(string name)
{
foreach (LoadedAssembly asm in assemblyList.GetAssemblies()) {
if (asm.AssemblyDefinition != null && name.Equals(asm.AssemblyDefinition.Name.Name, StringComparison.OrdinalIgnoreCase))
return asm;
}
if (assemblyLoadDisableCount > 0)
return null;
if (!App.Current.Dispatcher.CheckAccess()) {
// Call this method on the GUI thread.
return (LoadedAssembly)App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Func<string, LoadedAssembly>(LookupWinRTMetadata), name);
}
string file = Path.Combine(Environment.SystemDirectory, "WinMetadata", name + ".winmd");
if (File.Exists(file)) {
return assemblyList.OpenAssembly(file);
} else {
return null;
}
}
public Task ContinueWhenLoaded(Action<Task<AssemblyDefinition>> onAssemblyLoaded, TaskScheduler taskScheduler)
{
return this.assemblyTask.ContinueWith(onAssemblyLoaded, taskScheduler);

2
ILSpy/MainWindow.xaml.cs

@ -515,7 +515,7 @@ namespace ICSharpCode.ILSpy @@ -515,7 +515,7 @@ namespace ICSharpCode.ILSpy
{
e.Handled = true;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = ".NET assemblies|*.dll;*.exe|All files|*.*";
dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|All files|*.*";
dlg.Multiselect = true;
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() == true) {

10
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -63,7 +63,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
var assemblyListNode = parentAssembly.Parent as AssemblyListTreeNode;
if (assemblyListNode != null) {
assemblyListNode.Select(assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r.FullName)));
assemblyListNode.Select(assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r)));
e.Handled = true;
}
}
@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
var assemblyListNode = parentAssembly.Parent as AssemblyListTreeNode;
if (assemblyListNode != null) {
var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r.FullName));
var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r));
if (refNode != null) {
AssemblyDefinition asm = refNode.LoadedAssembly.AssemblyDefinition;
if (asm != null) {
@ -85,7 +85,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -85,7 +85,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, r.FullName);
if ((r.Attributes & (AssemblyAttributes)0x0200) != 0) {
language.WriteCommentLine(output, r.Name + " [WinRT]");
} else {
language.WriteCommentLine(output, r.FullName);
}
}
}
}

Loading…
Cancel
Save