TabStateDecompile CreateTabState(TabStateDecompile tabState, SavedTabState savedState, IList<ILSpyTreeNode> newNodes = null, bool decompile = true) { var nodes = new List<ILSpyTreeNode>(savedState.Paths.Count); if (newNodes != null) nodes.AddRange(newNodes); else { foreach (var asm in savedState.ActiveAutoLoadedAssemblies) this.assemblyList.OpenAssembly(asm, true); foreach (var path in savedState.Paths) { var node = assemblyListTreeNode.FindNodeByPath(path); if (node == null) { nodes = null; break; } nodes.Add(node); } } if (decompile) { if (nodes != null) { var tmpNodes = nodes.ToArray(); var helper = new OnShowOutputHelper(tabState.TextView, (success, hasMovedCaret) => decompilerTextView_OnShowOutput(success, hasMovedCaret, tabState.TextView, savedState), tmpNodes); DecompileNodes(tabState, null, false, tabState.Language, tmpNodes); } else AboutPage.Display(tabState.TextView); } return tabState; }
void DecompileNodes(DecompileTabState tabState, ILSpyTreeNode[] nodes, bool recordHistory, Language language, Func<bool, bool, bool> onDecompileFinished, bool forceDecompile = false) { var helper = new OnShowOutputHelper(tabState.TextView, onDecompileFinished, nodes); bool? decompiled = DecompileNodes(tabState, null, recordHistory, language, nodes, forceDecompile); if (decompiled == false) { helper.Abort(); onDecompileFinished(true, false); } }
// Returns true if we could decompile the reference bool JumpToReferenceAsyncInternal(TabStateDecompile tabState, bool canLoad, object reference, Func<bool, bool, bool> onDecompileFinished) { ILSpyTreeNode treeNode = FindTreeNode(reference); if (treeNode != null) { var helper = new OnShowOutputHelper(tabState.TextView, onDecompileFinished, treeNode); var nodes = new[] { treeNode }; bool? decompiled = DecompileNodes(tabState, null, false, tabState.Language, nodes); if (decompiled == false) { helper.Abort(); onDecompileFinished(true, false); } SelectTreeViewNodes(tabState, nodes); return true; } else if (reference is dnlib.DotNet.Emit.OpCode) { string link = "http://msdn.microsoft.com/library/system.reflection.emit.opcodes." + ((dnlib.DotNet.Emit.OpCode)reference).Code.ToString().ToLowerInvariant() + ".aspx"; try { Process.Start(link); } catch { } return true; } else if (canLoad && reference is IMemberDef) { // Here if the module was removed. It's possible that the user has re-added it. var member = (IMemberDef)reference; var module = member.Module; if (module == null) // Check if it has been deleted return false; var mainModule = module; if (module.Assembly != null) mainModule = module.Assembly.ManifestModule; if (!string.IsNullOrEmpty(mainModule.Location) && !string.IsNullOrEmpty(module.Location)) { // Check if the module was removed and then added again foreach (var m in assemblyList.GetAllModules()) { if (mainModule.Location.Equals(m.Location, StringComparison.OrdinalIgnoreCase)) { foreach (var asmMod in GetAssemblyModules(m)) { if (!module.Location.Equals(asmMod.Location, StringComparison.OrdinalIgnoreCase)) continue; // Found the module var modDef = asmMod as ModuleDefMD; if (modDef != null) { member = modDef.ResolveToken(member.MDToken) as IMemberDef; if (member != null) // should never fail return JumpToReferenceAsyncInternal(tabState, false, member, onDecompileFinished); } break; } return false; } } } // The module has been removed. Add it again var loadedAsm = new LoadedAssembly(assemblyList, mainModule); loadedAsm.IsAutoLoaded = true; assemblyList.AddAssembly(loadedAsm, true, false, false); return JumpToReferenceAsyncInternal(tabState, false, reference, onDecompileFinished); } else return false; }