Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Reflexil integration #523

Merged
merged 4 commits into from
Feb 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions ILSpy/AssemblyList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,29 @@ public LoadedAssembly OpenAssembly(string file)
}
return newAsm;
}

/// <summary>
/// Replace the assembly object model from a crafted stream, without disk I/O
/// Returns null if it is not already loaded.
/// </summary>
public LoadedAssembly HotReplaceAssembly(string file, Stream stream)
{
App.Current.Dispatcher.VerifyAccess();
file = Path.GetFullPath(file);

var target = this.assemblies.FirstOrDefault(asm => file.Equals(asm.FileName, StringComparison.OrdinalIgnoreCase));
if (target == null)
return null;

var index = this.assemblies.IndexOf(target);
var newAsm = new LoadedAssembly(this, file, stream);
lock (assemblies)
{
this.assemblies.Remove(target);
this.assemblies.Insert(index, newAsm);
}
return newAsm;
}

public void Unload(LoadedAssembly assembly)
{
Expand Down
22 changes: 18 additions & 4 deletions ILSpy/LoadedAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public sealed class LoadedAssembly
readonly string fileName;
readonly string shortName;

public LoadedAssembly(AssemblyList assemblyList, string fileName)
public LoadedAssembly(AssemblyList assemblyList, string fileName, Stream stream = null)
{
if (assemblyList == null)
throw new ArgumentNullException("assemblyList");
Expand All @@ -44,7 +44,7 @@ public LoadedAssembly(AssemblyList assemblyList, string fileName)
this.assemblyList = assemblyList;
this.fileName = fileName;

this.assemblyTask = Task.Factory.StartNew<ModuleDefinition>(LoadAssembly); // requires that this.fileName is set
this.assemblyTask = Task.Factory.StartNew<ModuleDefinition>(LoadAssembly, stream); // requires that this.fileName is set
this.shortName = Path.GetFileNameWithoutExtension(fileName);
}

Expand Down Expand Up @@ -93,12 +93,26 @@ public bool HasLoadError {
get { return assemblyTask.IsFaulted; }
}

ModuleDefinition LoadAssembly()
ModuleDefinition LoadAssembly(object state)
{
var stream = state as Stream;
ModuleDefinition module;

// runs on background thread
ReaderParameters p = new ReaderParameters();
p.AssemblyResolver = new MyAssemblyResolver(this);
ModuleDefinition module = ModuleDefinition.ReadModule(fileName, p);

if (stream != null)
{
// Read the module from a precrafted stream
module = ModuleDefinition.ReadModule(stream, p);
}
else
{
// Read the module from disk (by default)
module = ModuleDefinition.ReadModule(fileName, p);
}

if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
try {
LoadSymbols(module);
Expand Down
14 changes: 10 additions & 4 deletions ILSpy/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ internal AssemblyListTreeNode AssemblyListTreeNode {
}

#region Node Selection
internal void SelectNode(SharpTreeNode obj)

public void SelectNode(SharpTreeNode obj)
{
if (obj != null) {
if (!obj.AncestorsAndSelf().Any(node => node.IsHidden)) {
Expand All @@ -500,7 +501,7 @@ internal void SelectNode(SharpTreeNode obj)
/// <summary>
/// Retrieves a node using the .ToString() representations of its ancestors.
/// </summary>
SharpTreeNode FindNodeByPath(string[] path, bool returnBestMatch)
public SharpTreeNode FindNodeByPath(string[] path, bool returnBestMatch)
{
if (path == null)
return null;
Expand All @@ -522,7 +523,7 @@ SharpTreeNode FindNodeByPath(string[] path, bool returnBestMatch)
/// <summary>
/// Gets the .ToString() representation of the node's ancestors.
/// </summary>
string[] GetPathForNode(SharpTreeNode node)
public string[] GetPathForNode(SharpTreeNode node)
{
if (node == null)
return null;
Expand Down Expand Up @@ -639,6 +640,9 @@ void SearchCommandExecuted(object sender, ExecutedRoutedEventArgs e)
void TreeView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DecompileSelectedNodes();

if (SelectionChanged != null)
SelectionChanged(sender, e);
}

Task decompilationTask;
Expand Down Expand Up @@ -689,7 +693,9 @@ public Language CurrentLanguage {
return sessionSettings.FilterSettings.Language;
}
}


public event SelectionChangedEventHandler SelectionChanged;

public IEnumerable<ILSpyTreeNode> SelectedNodes {
get {
return treeView.GetTopLevelSelection().OfType<ILSpyTreeNode>();
Expand Down
7 changes: 6 additions & 1 deletion ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Node within assembly reference list.
/// </summary>
sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
{
readonly AssemblyNameReference r;
readonly AssemblyTreeNode parentAssembly;
Expand All @@ -40,6 +40,11 @@ public AssemblyReferenceTreeNode(AssemblyNameReference r, AssemblyTreeNode paren
this.parentAssembly = parentAssembly;
this.LazyLoading = true;
}

public AssemblyNameReference AssemblyNameReference
{
get { return r; }
}

public override object Text {
get { return r.Name + r.MetadataToken.ToSuffixString(); }
Expand Down