Browse Source

Add support for opening .netmodules.

pull/384/merge
Daniel Grunwald 13 years ago
parent
commit
b813092cfe
  1. 23
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 18
      ILSpy/Languages/CSharpLanguage.cs
  3. 9
      ILSpy/Languages/ILLanguage.cs
  4. 12
      ILSpy/Languages/Language.cs
  5. 29
      ILSpy/LoadedAssembly.cs
  6. 8
      ILSpy/MainWindow.xaml.cs
  7. 6
      ILSpy/SearchPane.cs
  8. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedAssemblyTreeNode.cs
  9. 23
      ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs
  10. 2
      ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs
  11. 12
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  12. 6
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
  13. 19
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  14. 4
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  15. 8
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  16. 26
      ILSpy/VB/VBLanguage.cs
  17. 2
      TestPlugin/ContextMenuCommand.cs

23
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -167,7 +167,12 @@ namespace ICSharpCode.Decompiler.Ast
public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false) public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{ {
if (assemblyDefinition.Name.Version != null) { AddAssembly(assemblyDefinition.MainModule, onlyAssemblyLevel);
}
public void AddAssembly(ModuleDefinition moduleDefinition, bool onlyAssemblyLevel = false)
{
if (moduleDefinition.Assembly != null && moduleDefinition.Assembly.Name.Version != null) {
syntaxTree.AddChild( syntaxTree.AddChild(
new AttributeSection { new AttributeSection {
AttributeTarget = "assembly", AttributeTarget = "assembly",
@ -176,22 +181,24 @@ namespace ICSharpCode.Decompiler.Ast
Type = new SimpleType("AssemblyVersion") Type = new SimpleType("AssemblyVersion")
.WithAnnotation(new TypeReference( .WithAnnotation(new TypeReference(
"System.Reflection", "AssemblyVersionAttribute", "System.Reflection", "AssemblyVersionAttribute",
assemblyDefinition.MainModule, assemblyDefinition.MainModule.TypeSystem.Corlib)), moduleDefinition, moduleDefinition.TypeSystem.Corlib)),
Arguments = { Arguments = {
new PrimitiveExpression(assemblyDefinition.Name.Version.ToString()) new PrimitiveExpression(moduleDefinition.Assembly.Name.Version.ToString())
} }
} }
} }
}, EntityDeclaration.AttributeRole); }, EntityDeclaration.AttributeRole);
} }
ConvertCustomAttributes(syntaxTree, assemblyDefinition, "assembly"); if (moduleDefinition.Assembly != null) {
ConvertSecurityAttributes(syntaxTree, assemblyDefinition, "assembly"); ConvertCustomAttributes(syntaxTree, moduleDefinition.Assembly, "assembly");
ConvertCustomAttributes(syntaxTree, assemblyDefinition.MainModule, "module"); ConvertSecurityAttributes(syntaxTree, moduleDefinition.Assembly, "assembly");
AddTypeForwarderAttributes(syntaxTree, assemblyDefinition.MainModule, "assembly"); }
ConvertCustomAttributes(syntaxTree, moduleDefinition, "module");
AddTypeForwarderAttributes(syntaxTree, moduleDefinition, "assembly");
if (!onlyAssemblyLevel) { if (!onlyAssemblyLevel) {
foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { foreach (TypeDefinition typeDef in moduleDefinition.Types) {
// Skip the <Module> class // Skip the <Module> class
if (typeDef.Name == "<Module>") continue; if (typeDef.Name == "<Module>") continue;
// Skip any hidden types // Skip any hidden types

18
ILSpy/Languages/CSharpLanguage.cs

@ -262,13 +262,13 @@ namespace ICSharpCode.ILSpy
{ {
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {
HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase); HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var files = WriteCodeFilesInProject(assembly.AssemblyDefinition, options, directories).ToList(); var files = WriteCodeFilesInProject(assembly.ModuleDefinition, options, directories).ToList();
files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); files.AddRange(WriteResourceFilesInProject(assembly, options, directories));
WriteProjectFile(new TextOutputWriter(output), files, assembly.AssemblyDefinition.MainModule); WriteProjectFile(new TextOutputWriter(output), files, assembly.ModuleDefinition);
} else { } else {
base.DecompileAssembly(assembly, output, options); base.DecompileAssembly(assembly, output, options);
output.WriteLine(); output.WriteLine();
ModuleDefinition mainModule = assembly.AssemblyDefinition.MainModule; ModuleDefinition mainModule = assembly.ModuleDefinition;
if (mainModule.EntryPoint != null) { if (mainModule.EntryPoint != null) {
output.Write("// Entry point: "); output.Write("// Entry point: ");
output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint);
@ -296,8 +296,8 @@ namespace ICSharpCode.ILSpy
// don't automatically load additional assemblies when an assembly node is selected in the tree view // don't automatically load additional assemblies when an assembly node is selected in the tree view
using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.AssemblyDefinition.MainModule); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition);
codeDomBuilder.AddAssembly(assembly.AssemblyDefinition, onlyAssemblyLevel: !options.FullDecompilation); codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation);
codeDomBuilder.RunTransformations(transformAbortCondition); codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output);
} }
@ -423,9 +423,9 @@ namespace ICSharpCode.ILSpy
return true; return true;
} }
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet<string> directories) IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet<string> directories)
{ {
var files = assembly.MainModule.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy( var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
delegate(TypeDefinition type) { delegate(TypeDefinition type) {
string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension; string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
if (string.IsNullOrEmpty(type.Namespace)) { if (string.IsNullOrEmpty(type.Namespace)) {
@ -443,7 +443,7 @@ namespace ICSharpCode.ILSpy
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
delegate(IGrouping<string, TypeDefinition> file) { delegate(IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) { using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.MainModule); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
foreach (TypeDefinition type in file) { foreach (TypeDefinition type in file) {
codeDomBuilder.AddType(type); codeDomBuilder.AddType(type);
} }
@ -461,7 +461,7 @@ namespace ICSharpCode.ILSpy
{ {
//AppDomain bamlDecompilerAppDomain = null; //AppDomain bamlDecompilerAppDomain = null;
//try { //try {
foreach (EmbeddedResource r in assembly.AssemblyDefinition.MainModule.Resources.OfType<EmbeddedResource>()) { foreach (EmbeddedResource r in assembly.ModuleDefinition.Resources.OfType<EmbeddedResource>()) {
string fileName; string fileName;
Stream s = r.GetResourceStream(); Stream s = r.GetResourceStream();
s.Position = 0; s.Position = 0;

9
ILSpy/Languages/ILLanguage.cs

@ -114,14 +114,15 @@ namespace ICSharpCode.ILSpy
ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken);
if (options.FullDecompilation) if (options.FullDecompilation)
rd.WriteAssemblyReferences(assembly.AssemblyDefinition.MainModule); rd.WriteAssemblyReferences(assembly.ModuleDefinition);
rd.WriteAssemblyHeader(assembly.AssemblyDefinition); if (assembly.AssemblyDefinition != null)
rd.WriteAssemblyHeader(assembly.AssemblyDefinition);
output.WriteLine(); output.WriteLine();
rd.WriteModuleHeader(assembly.AssemblyDefinition.MainModule); rd.WriteModuleHeader(assembly.ModuleDefinition);
if (options.FullDecompilation) { if (options.FullDecompilation) {
output.WriteLine(); output.WriteLine();
output.WriteLine(); output.WriteLine();
rd.WriteModuleContents(assembly.AssemblyDefinition.MainModule); rd.WriteModuleContents(assembly.ModuleDefinition);
} }
} }

12
ILSpy/Languages/Language.cs

@ -88,11 +88,15 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, assembly.FileName); WriteCommentLine(output, assembly.FileName);
var name = assembly.AssemblyDefinition.Name; if (assembly.AssemblyDefinition != null) {
if (name.IsWindowsRuntime) { var name = assembly.AssemblyDefinition.Name;
WriteCommentLine(output, name.Name + " [WinRT]"); if (name.IsWindowsRuntime) {
WriteCommentLine(output, name.Name + " [WinRT]");
} else {
WriteCommentLine(output, name.FullName);
}
} else { } else {
WriteCommentLine(output, name.FullName); WriteCommentLine(output, assembly.ModuleDefinition.Name);
} }
} }

29
ILSpy/LoadedAssembly.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public sealed class LoadedAssembly public sealed class LoadedAssembly
{ {
readonly Task<AssemblyDefinition> assemblyTask; readonly Task<ModuleDefinition> assemblyTask;
readonly AssemblyList assemblyList; readonly AssemblyList assemblyList;
readonly string fileName; readonly string fileName;
readonly string shortName; readonly string shortName;
@ -44,15 +44,15 @@ namespace ICSharpCode.ILSpy
this.assemblyList = assemblyList; this.assemblyList = assemblyList;
this.fileName = fileName; this.fileName = fileName;
this.assemblyTask = Task.Factory.StartNew<AssemblyDefinition>(LoadAssembly); // requires that this.fileName is set this.assemblyTask = Task.Factory.StartNew<ModuleDefinition>(LoadAssembly); // requires that this.fileName is set
this.shortName = Path.GetFileNameWithoutExtension(fileName); this.shortName = Path.GetFileNameWithoutExtension(fileName);
} }
/// <summary> /// <summary>
/// Gets the Cecil AssemblyDefinition. /// Gets the Cecil ModuleDefinition.
/// Can be null when there was a load error. /// Can be null when there was a load error.
/// </summary> /// </summary>
public AssemblyDefinition AssemblyDefinition { public ModuleDefinition ModuleDefinition {
get { get {
try { try {
return assemblyTask.Result; return assemblyTask.Result;
@ -62,6 +62,17 @@ namespace ICSharpCode.ILSpy
} }
} }
/// <summary>
/// Gets the Cecil AssemblyDefinition.
/// Is null when there was a load error; or when opening a netmodule.
/// </summary>
public AssemblyDefinition AssemblyDefinition {
get {
var module = this.ModuleDefinition;
return module != null ? module.Assembly : null;
}
}
public AssemblyList AssemblyList { public AssemblyList AssemblyList {
get { return assemblyList; } get { return assemblyList; }
} }
@ -82,22 +93,22 @@ namespace ICSharpCode.ILSpy
get { return assemblyTask.IsFaulted; } get { return assemblyTask.IsFaulted; }
} }
AssemblyDefinition LoadAssembly() ModuleDefinition LoadAssembly()
{ {
// runs on background thread // runs on background thread
ReaderParameters p = new ReaderParameters(); ReaderParameters p = new ReaderParameters();
p.AssemblyResolver = new MyAssemblyResolver(this); p.AssemblyResolver = new MyAssemblyResolver(this);
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, p); ModuleDefinition module = ModuleDefinition.ReadModule(fileName, p);
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) { if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
try { try {
LoadSymbols(asm.MainModule); LoadSymbols(module);
} catch (IOException) { } catch (IOException) {
} catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) {
} catch (InvalidOperationException) { } catch (InvalidOperationException) {
// ignore any errors during symbol loading // ignore any errors during symbol loading
} }
} }
return asm; return module;
} }
private void LoadSymbols(ModuleDefinition module) private void LoadSymbols(ModuleDefinition module)
@ -244,7 +255,7 @@ namespace ICSharpCode.ILSpy
} }
} }
public Task ContinueWhenLoaded(Action<Task<AssemblyDefinition>> onAssemblyLoaded, TaskScheduler taskScheduler) public Task ContinueWhenLoaded(Action<Task<ModuleDefinition>> onAssemblyLoaded, TaskScheduler taskScheduler)
{ {
return this.assemblyTask.ContinueWith(onAssemblyLoaded, taskScheduler); return this.assemblyTask.ContinueWith(onAssemblyLoaded, taskScheduler);
} }

8
ILSpy/MainWindow.xaml.cs

@ -275,9 +275,9 @@ namespace ICSharpCode.ILSpy
} }
} else { } else {
foreach (LoadedAssembly asm in commandLineLoadedAssemblies) { foreach (LoadedAssembly asm in commandLineLoadedAssemblies) {
AssemblyDefinition def = asm.AssemblyDefinition; ModuleDefinition def = asm.ModuleDefinition;
if (def != null) { if (def != null) {
MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def.MainModule, args.NavigateTo); MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
if (mr != null) { if (mr != null) {
found = true; found = true;
JumpToReference(mr); JumpToReference(mr);
@ -294,7 +294,7 @@ namespace ICSharpCode.ILSpy
} else if (commandLineLoadedAssemblies.Count == 1) { } else if (commandLineLoadedAssemblies.Count == 1) {
// NavigateTo == null and an assembly was given on the command-line: // NavigateTo == null and an assembly was given on the command-line:
// Select the newly loaded assembly // Select the newly loaded assembly
JumpToReference(commandLineLoadedAssemblies[0].AssemblyDefinition); JumpToReference(commandLineLoadedAssemblies[0].ModuleDefinition);
} }
commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore
} }
@ -550,6 +550,8 @@ namespace ICSharpCode.ILSpy
return assemblyListTreeNode.FindEventNode(((EventReference)reference).Resolve()); return assemblyListTreeNode.FindEventNode(((EventReference)reference).Resolve());
} else if (reference is AssemblyDefinition) { } else if (reference is AssemblyDefinition) {
return assemblyListTreeNode.FindAssemblyNode((AssemblyDefinition)reference); return assemblyListTreeNode.FindAssemblyNode((AssemblyDefinition)reference);
} else if (reference is ModuleDefinition) {
return assemblyListTreeNode.FindAssemblyNode((ModuleDefinition)reference);
} else { } else {
return null; return null;
} }

6
ILSpy/SearchPane.cs

@ -244,11 +244,11 @@ namespace ICSharpCode.ILSpy
} }
foreach (var loadedAssembly in assemblies) { foreach (var loadedAssembly in assemblies) {
AssemblyDefinition asm = loadedAssembly.AssemblyDefinition; ModuleDefinition module = loadedAssembly.ModuleDefinition;
if (asm == null) if (module == null)
continue; continue;
CancellationToken cancellationToken = cts.Token; CancellationToken cancellationToken = cts.Token;
foreach (TypeDefinition type in asm.MainModule.Types) { foreach (TypeDefinition type in module.Types) {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
PerformSearch(type); PerformSearch(type);
} }

6
ILSpy/TreeNodes/Analyzer/AnalyzedAssemblyTreeNode.cs

@ -23,9 +23,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{ {
internal class AnalyzedAssemblyTreeNode : AnalyzerEntityTreeNode internal class AnalyzedAssemblyTreeNode : AnalyzerEntityTreeNode
{ {
private readonly AssemblyDefinition analyzedAssembly; private readonly ModuleDefinition analyzedAssembly;
public AnalyzedAssemblyTreeNode(AssemblyDefinition analyzedAssembly) public AnalyzedAssemblyTreeNode(ModuleDefinition analyzedAssembly)
{ {
if (analyzedAssembly == null) if (analyzedAssembly == null)
throw new ArgumentNullException("analyzedAssembly"); throw new ArgumentNullException("analyzedAssembly");
@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{ {
get get
{ {
return analyzedAssembly.Name.Name; return analyzedAssembly.Name;
} }
} }

23
ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
var currentAssembly = analyzedType.Module.Assembly; var currentAssembly = analyzedType.Module.Assembly;
var assemblies = analyzedType.IsPublic ? GetReferencingAssemblies(currentAssembly, ct) : GetAssemblyAndAnyFriends(currentAssembly, ct); var assemblies = analyzedType.IsPublic ? GetReferencingAssemblies(currentAssembly, ct) : GetAssemblyAndAnyFriends(currentAssembly, ct);
var results = assemblies.AsParallel().WithCancellation(ct).SelectMany(a => FindReferencesInAssembly(a.Item1, a.Item2, ct)); var results = assemblies.AsParallel().WithCancellation(ct).SelectMany(a => FindReferencesInAssembly(a.Item1.MainModule, a.Item2, ct));
foreach (var result in results.OrderBy(n => n.Text)) { foreach (var result in results.OrderBy(n => n.Text)) {
yield return result; yield return result;
@ -105,13 +105,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
#region standard custom attributes #region standard custom attributes
private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(AssemblyDefinition asm, TypeReference tr, CancellationToken ct) private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(ModuleDefinition module, TypeReference tr, CancellationToken ct)
{ {
//since we do not display modules as separate entities, coalesce the assembly and module searches //since we do not display modules as separate entities, coalesce the assembly and module searches
bool foundInAssyOrModule = false; bool foundInAssyOrModule = false;
if ((usage & AttributeTargets.Assembly) != 0) { if ((usage & AttributeTargets.Assembly) != 0) {
if (asm.HasCustomAttributes) { AssemblyDefinition asm = module.Assembly;
if (asm != null && asm.HasCustomAttributes) {
foreach (var attribute in asm.CustomAttributes) { foreach (var attribute in asm.CustomAttributes) {
if (attribute.AttributeType == tr) { if (attribute.AttributeType == tr) {
foundInAssyOrModule = true; foundInAssyOrModule = true;
@ -126,13 +127,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
//search module //search module
if ((usage & AttributeTargets.Module) != 0) { if ((usage & AttributeTargets.Module) != 0) {
foreach (var module in asm.Modules) { if (module.HasCustomAttributes) {
if (module.HasCustomAttributes) { foreach (var attribute in module.CustomAttributes) {
foreach (var attribute in module.CustomAttributes) { if (attribute.AttributeType == tr) {
if (attribute.AttributeType == tr) { foundInAssyOrModule = true;
foundInAssyOrModule = true; break;
break;
}
} }
} }
} }
@ -141,12 +140,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
} }
if (foundInAssyOrModule) { if (foundInAssyOrModule) {
yield return new AnalyzedAssemblyTreeNode(asm); yield return new AnalyzedAssemblyTreeNode(module);
} }
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes).OrderBy(t => t.FullName)) { foreach (TypeDefinition type in TreeTraversal.PreOrder(module.Types, t => t.NestedTypes).OrderBy(t => t.FullName)) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
foreach (var result in FindReferencesWithinInType(type, tr)) { foreach (var result in FindReferencesWithinInType(type, tr)) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();

2
ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies) public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
{ {
foreach (LoadedAssembly asm in removedAssemblies) { foreach (LoadedAssembly asm in removedAssemblies) {
if (this.Member.Module.Assembly == asm.AssemblyDefinition) if (this.Member.Module == asm.ModuleDefinition)
return false; // remove this node return false; // remove this node
} }
this.Children.RemoveAll( this.Children.RemoveAll(

12
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -132,6 +132,18 @@ namespace ICSharpCode.ILSpy.TreeNodes
#region Find*Node #region Find*Node
public AssemblyTreeNode FindAssemblyNode(ModuleDefinition module)
{
if (module == null)
return null;
App.Current.Dispatcher.VerifyAccess();
foreach (AssemblyTreeNode node in this.Children) {
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.ModuleDefinition == module)
return node;
}
return null;
}
public AssemblyTreeNode FindAssemblyNode(AssemblyDefinition asm) public AssemblyTreeNode FindAssemblyNode(AssemblyDefinition asm)
{ {
if (asm == null) if (asm == null)

6
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -72,9 +72,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (assemblyListNode != null) { if (assemblyListNode != null) {
var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r)); var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r));
if (refNode != null) { if (refNode != null) {
AssemblyDefinition asm = refNode.LoadedAssembly.AssemblyDefinition; ModuleDefinition module = refNode.LoadedAssembly.ModuleDefinition;
if (asm != null) { if (module != null) {
foreach (var childRef in asm.MainModule.AssemblyReferences) foreach (var childRef in module.AssemblyReferences)
this.Children.Add(new AssemblyReferenceTreeNode(childRef, refNode)); this.Children.Add(new AssemblyReferenceTreeNode(childRef, refNode));
} }
} }

19
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -83,15 +83,15 @@ namespace ICSharpCode.ILSpy.TreeNodes
get { return !assembly.HasLoadError; } get { return !assembly.HasLoadError; }
} }
void OnAssemblyLoaded(Task<AssemblyDefinition> assemblyTask) void OnAssemblyLoaded(Task<ModuleDefinition> moduleTask)
{ {
// change from "Loading" icon to final icon // change from "Loading" icon to final icon
RaisePropertyChanged("Icon"); RaisePropertyChanged("Icon");
RaisePropertyChanged("ExpandedIcon"); RaisePropertyChanged("ExpandedIcon");
if (assemblyTask.IsFaulted) { if (moduleTask.IsFaulted) {
RaisePropertyChanged("ShowExpander"); // cannot expand assemblies with load error RaisePropertyChanged("ShowExpander"); // cannot expand assemblies with load error
// observe the exception so that the Task's finalizer doesn't re-throw it // observe the exception so that the Task's finalizer doesn't re-throw it
try { assemblyTask.Wait(); } try { moduleTask.Wait(); }
catch (AggregateException) { } catch (AggregateException) { }
} else { } else {
RaisePropertyChanged("Text"); // shortname might have changed RaisePropertyChanged("Text"); // shortname might have changed
@ -102,20 +102,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren() protected override void LoadChildren()
{ {
AssemblyDefinition assemblyDefinition = assembly.AssemblyDefinition; ModuleDefinition moduleDefinition = assembly.ModuleDefinition;
if (assemblyDefinition == null) { if (moduleDefinition == null) {
// if we crashed on loading, then we don't have any children // if we crashed on loading, then we don't have any children
return; return;
} }
ModuleDefinition mainModule = assemblyDefinition.MainModule;
this.Children.Add(new ReferenceFolderTreeNode(mainModule, this)); this.Children.Add(new ReferenceFolderTreeNode(moduleDefinition, this));
if (mainModule.HasResources) if (moduleDefinition.HasResources)
this.Children.Add(new ResourceListTreeNode(mainModule)); this.Children.Add(new ResourceListTreeNode(moduleDefinition));
foreach (NamespaceTreeNode ns in namespaces.Values) { foreach (NamespaceTreeNode ns in namespaces.Values) {
ns.Children.Clear(); ns.Children.Clear();
} }
foreach (TypeDefinition type in mainModule.Types.OrderBy(t => t.FullName)) { foreach (TypeDefinition type in moduleDefinition.Types.OrderBy(t => t.FullName)) {
NamespaceTreeNode ns; NamespaceTreeNode ns;
if (!namespaces.TryGetValue(type.Namespace, out ns)) { if (!namespaces.TryGetValue(type.Namespace, out ns)) {
ns = new NamespaceTreeNode(type.Namespace); ns = new NamespaceTreeNode(type.Namespace);

4
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -27,10 +27,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{ {
private readonly TypeDefinition type; private readonly TypeDefinition type;
private readonly AssemblyDefinition[] assemblies; private readonly ModuleDefinition[] assemblies;
private readonly ThreadingSupport threading; private readonly ThreadingSupport threading;
public DerivedTypesEntryNode(TypeDefinition type, AssemblyDefinition[] assemblies) public DerivedTypesEntryNode(TypeDefinition type, ModuleDefinition[] assemblies)
{ {
this.type = type; this.type = type;
this.assemblies = assemblies; this.assemblies = assemblies;

8
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -61,14 +61,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken cancellationToken) IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken cancellationToken)
{ {
// 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.AssemblyDefinition).Where(asm => asm != null).ToArray(); var assemblies = list.GetAssemblies().Select(node => node.ModuleDefinition).Where(asm => asm != null).ToArray();
return FindDerivedTypes(type, assemblies, cancellationToken); return FindDerivedTypes(type, assemblies, cancellationToken);
} }
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, AssemblyDefinition[] assemblies, CancellationToken cancellationToken) internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, ModuleDefinition[] assemblies, CancellationToken cancellationToken)
{ {
foreach (AssemblyDefinition asm in assemblies) { foreach (ModuleDefinition module in assemblies) {
foreach (TypeDefinition td in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes)) { foreach (TypeDefinition td in TreeTraversal.PreOrder(module.Types, t => t.NestedTypes)) {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (type.IsInterface && td.HasInterfaces) { if (type.IsInterface && td.HasInterfaces) {
foreach (TypeReference typeRef in td.Interfaces) { foreach (TypeReference typeRef in td.Interfaces) {

26
ILSpy/VB/VBLanguage.cs

@ -72,13 +72,13 @@ namespace ICSharpCode.ILSpy.VB
{ {
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {
HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase); HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var files = WriteCodeFilesInProject(assembly.AssemblyDefinition, options, directories).ToList(); var files = WriteCodeFilesInProject(assembly.ModuleDefinition, options, directories).ToList();
files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); files.AddRange(WriteResourceFilesInProject(assembly, options, directories));
WriteProjectFile(new TextOutputWriter(output), files, assembly.AssemblyDefinition.MainModule); WriteProjectFile(new TextOutputWriter(output), files, assembly.ModuleDefinition);
} else { } else {
base.DecompileAssembly(assembly, output, options); base.DecompileAssembly(assembly, output, options);
output.WriteLine(); output.WriteLine();
ModuleDefinition mainModule = assembly.AssemblyDefinition.MainModule; ModuleDefinition mainModule = assembly.ModuleDefinition;
if (mainModule.EntryPoint != null) { if (mainModule.EntryPoint != null) {
output.Write("' Entry point: "); output.Write("' Entry point: ");
output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint);
@ -106,9 +106,9 @@ namespace ICSharpCode.ILSpy.VB
// don't automatically load additional assemblies when an assembly node is selected in the tree view // don't automatically load additional assemblies when an assembly node is selected in the tree view
using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.AssemblyDefinition.MainModule); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition);
codeDomBuilder.AddAssembly(assembly.AssemblyDefinition, onlyAssemblyLevel: !options.FullDecompilation); codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, assembly.AssemblyDefinition.MainModule); RunTransformsAndGenerateCode(codeDomBuilder, output, options, assembly.ModuleDefinition);
} }
} }
} }
@ -248,9 +248,9 @@ namespace ICSharpCode.ILSpy.VB
return true; return true;
} }
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet<string> directories) IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet<string> directories)
{ {
var files = assembly.MainModule.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy( var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
delegate(TypeDefinition type) { delegate(TypeDefinition type) {
string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension; string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
if (string.IsNullOrEmpty(type.Namespace)) { if (string.IsNullOrEmpty(type.Namespace)) {
@ -268,11 +268,11 @@ namespace ICSharpCode.ILSpy.VB
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
delegate(IGrouping<string, TypeDefinition> file) { delegate(IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) { using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.MainModule); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
foreach (TypeDefinition type in file) { foreach (TypeDefinition type in file) {
codeDomBuilder.AddType(type); codeDomBuilder.AddType(type);
} }
RunTransformsAndGenerateCode(codeDomBuilder, new PlainTextOutput(w), options, assembly.MainModule); RunTransformsAndGenerateCode(codeDomBuilder, new PlainTextOutput(w), options, module);
} }
}); });
AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes(); AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
@ -285,7 +285,7 @@ namespace ICSharpCode.ILSpy.VB
{ {
//AppDomain bamlDecompilerAppDomain = null; //AppDomain bamlDecompilerAppDomain = null;
//try { //try {
foreach (EmbeddedResource r in assembly.AssemblyDefinition.MainModule.Resources.OfType<EmbeddedResource>()) { foreach (EmbeddedResource r in assembly.ModuleDefinition.Resources.OfType<EmbeddedResource>()) {
string fileName; string fileName;
Stream s = r.GetResourceStream(); Stream s = r.GetResourceStream();
s.Position = 0; s.Position = 0;
@ -306,8 +306,8 @@ namespace ICSharpCode.ILSpy.VB
Stream entryStream = (Stream)pair.Value; Stream entryStream = (Stream)pair.Value;
entryStream.Position = 0; entryStream.Position = 0;
if (fileName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) { if (fileName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) {
MemoryStream ms = new MemoryStream(); //MemoryStream ms = new MemoryStream();
entryStream.CopyTo(ms); //entryStream.CopyTo(ms);
// TODO implement extension point // TODO implement extension point
// var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName); // var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName);
// string xaml = null; // string xaml = null;

2
TestPlugin/ContextMenuCommand.cs

@ -29,7 +29,7 @@ namespace TestPlugin
if (context.SelectedTreeNodes == null) if (context.SelectedTreeNodes == null)
return; return;
AssemblyTreeNode node = (AssemblyTreeNode)context.SelectedTreeNodes[0]; AssemblyTreeNode node = (AssemblyTreeNode)context.SelectedTreeNodes[0];
AssemblyDefinition asm = node.LoadedAssembly.AssemblyDefinition as AssemblyDefinition; AssemblyDefinition asm = node.LoadedAssembly.AssemblyDefinition;
if (asm != null) { if (asm != null) {
SaveFileDialog dlg = new SaveFileDialog(); SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = node.LoadedAssembly.FileName; dlg.FileName = node.LoadedAssembly.FileName;

Loading…
Cancel
Save