|
|
@ -1,9 +1,11 @@ |
|
|
|
using System; |
|
|
|
using System; |
|
|
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows; |
|
|
|
|
|
|
|
|
|
|
|
using ICSharpCode.Decompiler.FlowAnalysis; |
|
|
|
using ICSharpCode.Decompiler.FlowAnalysis; |
|
|
|
using ICSharpCode.Decompiler.IL; |
|
|
|
using ICSharpCode.Decompiler.IL; |
|
|
|
using ICSharpCode.Decompiler.IL.ControlFlow; |
|
|
|
using ICSharpCode.Decompiler.IL.ControlFlow; |
|
|
|
|
|
|
|
using ICSharpCode.ILSpy.Util; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.ILSpy.Commands |
|
|
|
namespace ICSharpCode.ILSpy.Commands |
|
|
|
{ |
|
|
|
{ |
|
|
@ -17,7 +19,7 @@ namespace ICSharpCode.ILSpy.Commands |
|
|
|
{ |
|
|
|
{ |
|
|
|
var container = (BlockContainer)context.Reference.Reference; |
|
|
|
var container = (BlockContainer)context.Reference.Reference; |
|
|
|
var cfg = new ControlFlowGraph(container); |
|
|
|
var cfg = new ControlFlowGraph(container); |
|
|
|
ControlFlowNode.ExportGraph(cfg.cfg).Show(); |
|
|
|
ExportGraph(cfg.Nodes).Show(); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -34,6 +36,41 @@ namespace ICSharpCode.ILSpy.Commands |
|
|
|
{ |
|
|
|
{ |
|
|
|
return context.Reference?.Reference is BlockContainer; |
|
|
|
return context.Reference?.Reference is BlockContainer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal static GraphVizGraph ExportGraph(IReadOnlyList<ControlFlowNode> nodes, Func<ControlFlowNode, string> labelFunc = null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (labelFunc == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
labelFunc = node => { |
|
|
|
|
|
|
|
var block = node.UserData as Block; |
|
|
|
|
|
|
|
return block != null ? block.Label : node.UserData?.ToString(); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
GraphVizGraph g = new GraphVizGraph(); |
|
|
|
|
|
|
|
GraphVizNode[] n = new GraphVizNode[nodes.Count]; |
|
|
|
|
|
|
|
for (int i = 0; i < n.Length; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
n[i] = new GraphVizNode(nodes[i].UserIndex); |
|
|
|
|
|
|
|
n[i].shape = "box"; |
|
|
|
|
|
|
|
n[i].label = labelFunc(nodes[i]); |
|
|
|
|
|
|
|
g.AddNode(n[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
foreach (var source in nodes) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach (var target in source.Successors) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
g.AddEdge(new GraphVizEdge(source.UserIndex, target.UserIndex)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (source.ImmediateDominator != null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
g.AddEdge( |
|
|
|
|
|
|
|
new GraphVizEdge(source.ImmediateDominator.UserIndex, source.UserIndex) { |
|
|
|
|
|
|
|
color = "green" |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return g; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
} |
|
|
|
} |
|
|
|