Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
71c292d626
  1. 19
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 3
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  3. 24
      ILSpy/ILAstLanguage.cs
  4. 3
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  5. 4
      SharpTreeView/SharpTreeNodeView.cs
  6. 29
      SharpTreeView/SharpTreeView.cs

19
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -8,16 +8,29 @@ using Decompiler.Rocks;
namespace Decompiler.ControlFlow namespace Decompiler.ControlFlow
{ {
public enum ILAstOptimizationStep
{
SplitToMovableBlocks,
FindLoops,
FindConditions,
FlattenNestedMovableBlocks,
SimpleGotoRemoval,
RemoveDeadLabels,
None
}
public class ILAstOptimizer public class ILAstOptimizer
{ {
Dictionary<ILLabel, ControlFlowNode> labelToCfNode = new Dictionary<ILLabel, ControlFlowNode>(); Dictionary<ILLabel, ControlFlowNode> labelToCfNode = new Dictionary<ILLabel, ControlFlowNode>();
public void Optimize(ILBlock method) public void Optimize(ILBlock method, ILAstOptimizationStep abortBeforeStep = ILAstOptimizationStep.None)
{ {
if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
SplitToMovableBlocks(block); SplitToMovableBlocks(block);
} }
if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph; ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint); graph = BuildGraph(block.Body, block.EntryPoint);
@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow
block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, true); block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, true);
} }
if (abortBeforeStep == ILAstOptimizationStep.FindConditions) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph; ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint); graph = BuildGraph(block.Body, block.EntryPoint);
@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow
} }
// OrderNodes(method); // OrderNodes(method);
if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks) return;
FlattenNestedMovableBlocks(method); FlattenNestedMovableBlocks(method);
if (abortBeforeStep == ILAstOptimizationStep.SimpleGotoRemoval) return;
SimpleGotoRemoval(method); SimpleGotoRemoval(method);
if (abortBeforeStep == ILAstOptimizationStep.RemoveDeadLabels) return;
RemoveDeadLabels(method); RemoveDeadLabels(method);
} }

3
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -85,7 +85,8 @@ namespace Decompiler
public override void WriteTo(ITextOutput output) public override void WriteTo(ITextOutput output)
{ {
EntryPoint.WriteTo(output); if (EntryPoint != null)
EntryPoint.WriteTo(output);
foreach(ILNode child in this.Body) { foreach(ILNode child in this.Body) {
child.WriteTo(output); child.WriteTo(output);
output.WriteLine(); output.WriteLine();

24
ILSpy/ILAstLanguage.cs

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Decompiler; using Decompiler;
using Decompiler.ControlFlow;
using Decompiler.Transforms; using Decompiler.Transforms;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public class ILAstLanguage : Language public class ILAstLanguage : Language
{ {
string name;
bool inlineVariables = true;
ILAstOptimizationStep? abortBeforeStep;
public override string Name { public override string Name {
get { get {
return "ILAst"; return name;
} }
} }
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
var body = new ILAstBuilder().Build(method, false); ILBlock ilMethod = new ILBlock();
ilMethod.Body = new ILAstBuilder().Build(method, inlineVariables);
if (abortBeforeStep != null) {
new ILAstOptimizer().Optimize(ilMethod, abortBeforeStep.Value);
}
foreach (ILNode node in body) { foreach (ILNode node in ilMethod.Body) {
node.WriteTo(output); node.WriteTo(output);
output.WriteLine(); output.WriteLine();
} }
@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy
#if DEBUG #if DEBUG
internal static IEnumerable<ILAstLanguage> GetDebugLanguages() internal static IEnumerable<ILAstLanguage> GetDebugLanguages()
{ {
yield return new ILAstLanguage(); yield return new ILAstLanguage { name = "ILAst (unoptimized)", inlineVariables = false };
string nextName = "ILAst (variable inlining)";
foreach (ILAstOptimizationStep step in Enum.GetValues(typeof(ILAstOptimizationStep))) {
yield return new ILAstLanguage { name = nextName, abortBeforeStep = step };
nextName = "ILAst (after " + step + ")";
}
} }
#endif #endif

3
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -157,7 +157,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
void EnsureChildrenFiltered() void EnsureChildrenFiltered()
{ {
EnsureLazyChildren(); // No need to ensure lazy children here:
// if the children get lazy-loaded later, they'll still be filtered.
if (childrenNeedFiltering) { if (childrenNeedFiltering) {
childrenNeedFiltering = false; childrenNeedFiltering = false;
foreach (ILSpyTreeNode node in this.Children.OfType<ILSpyTreeNode>()) foreach (ILSpyTreeNode node in this.Children.OfType<ILSpyTreeNode>())

4
SharpTreeView/SharpTreeNodeView.cs

@ -95,7 +95,9 @@ namespace ICSharpCode.TreeView
} }
} }
} else if (e.PropertyName == "IsExpanded") { } else if (e.PropertyName == "IsExpanded") {
if (Node.IsExpanded == false) if (Node.IsExpanded)
ParentTreeView.HandleExpanding(Node);
else
ParentTreeView.HandleCollapsing(Node); ParentTreeView.HandleCollapsing(Node);
} }
} }

29
SharpTreeView/SharpTreeView.cs

@ -151,12 +151,35 @@ namespace ICSharpCode.TreeView
container.ParentTreeView = this; container.ParentTreeView = this;
} }
internal void HandleCollapsing(SharpTreeNode Node) internal void HandleExpanding(SharpTreeNode node)
{
SharpTreeNode lastVisibleChild = node;
while (true) {
SharpTreeNode tmp = lastVisibleChild.Children.LastOrDefault(c => c.IsVisible);
if (tmp != null) {
lastVisibleChild = tmp;
} else {
break;
}
}
if (lastVisibleChild != node) {
// Make the the expanded children are visible; but don't scroll down
// to much (keep node itself visible)
base.ScrollIntoView(lastVisibleChild);
// For some reason, this only works properly when delaying it...
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(
delegate {
base.ScrollIntoView(node);
}));
}
}
internal void HandleCollapsing(SharpTreeNode node)
{ {
var selectedChilds = Node.VisibleDescendants().Where(n => n.IsSelected); var selectedChilds = node.VisibleDescendants().Where(n => n.IsSelected);
if (selectedChilds.Any()) { if (selectedChilds.Any()) {
var list = SelectedItems.Cast<SharpTreeNode>().Except(selectedChilds).ToList(); var list = SelectedItems.Cast<SharpTreeNode>().Except(selectedChilds).ToList();
list.AddOnce(Node); list.AddOnce(node);
SetSelectedItems(list); SetSelectedItems(list);
} }
} }

Loading…
Cancel
Save