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; @@ -8,16 +8,29 @@ using Decompiler.Rocks;
namespace Decompiler.ControlFlow
{
public enum ILAstOptimizationStep
{
SplitToMovableBlocks,
FindLoops,
FindConditions,
FlattenNestedMovableBlocks,
SimpleGotoRemoval,
RemoveDeadLabels,
None
}
public class ILAstOptimizer
{
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()) {
SplitToMovableBlocks(block);
}
if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint);
@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow @@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow
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()) {
ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint);
@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow @@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow
}
// OrderNodes(method);
if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks) return;
FlattenNestedMovableBlocks(method);
if (abortBeforeStep == ILAstOptimizationStep.SimpleGotoRemoval) return;
SimpleGotoRemoval(method);
if (abortBeforeStep == ILAstOptimizationStep.RemoveDeadLabels) return;
RemoveDeadLabels(method);
}

3
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

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

24
ILSpy/ILAstLanguage.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Decompiler;
using Decompiler.ControlFlow;
using Decompiler.Transforms;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy @@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy
/// </summary>
public class ILAstLanguage : Language
{
string name;
bool inlineVariables = true;
ILAstOptimizationStep? abortBeforeStep;
public override string Name {
get {
return "ILAst";
return name;
}
}
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);
output.WriteLine();
}
@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy @@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy
#if DEBUG
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

3
ILSpy/TreeNodes/ILSpyTreeNode.cs

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

4
SharpTreeView/SharpTreeNodeView.cs

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

29
SharpTreeView/SharpTreeView.cs

@ -151,12 +151,35 @@ namespace ICSharpCode.TreeView @@ -151,12 +151,35 @@ namespace ICSharpCode.TreeView
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()) {
var list = SelectedItems.Cast<SharpTreeNode>().Except(selectedChilds).ToList();
list.AddOnce(Node);
list.AddOnce(node);
SetSelectedItems(list);
}
}

Loading…
Cancel
Save