diff --git a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
index 8990fb5d82..032aa64832 100644
--- a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
+++ b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
@@ -1,4 +1,4 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@@ -26,6 +26,7 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
+using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Analysis
{
@@ -750,5 +751,57 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
return CreateConnectedEndNode(fixedStatement, bodyEnd);
}
}
+
+ ///
+ /// Debugging helper that exports a control flow graph.
+ ///
+ public static GraphVizGraph ExportGraph(IList nodes)
+ {
+ GraphVizGraph g = new GraphVizGraph();
+ GraphVizNode[] n = new GraphVizNode[nodes.Count];
+ Dictionary dict = new Dictionary();
+ for (int i = 0; i < n.Length; i++) {
+ dict.Add(nodes[i], i);
+ n[i] = new GraphVizNode(i);
+ string name = "#" + i + " = ";
+ switch (nodes[i].Type) {
+ case ControlFlowNodeType.StartNode:
+ case ControlFlowNodeType.BetweenStatements:
+ name += nodes[i].NextStatement.DebugToString();
+ break;
+ case ControlFlowNodeType.EndNode:
+ name += "End of " + nodes[i].PreviousStatement.DebugToString();
+ break;
+ case ControlFlowNodeType.LoopCondition:
+ name += "Condition in " + nodes[i].NextStatement.DebugToString();
+ break;
+ default:
+ name += "?";
+ break;
+ }
+ n[i].label = name;
+ g.AddNode(n[i]);
+ }
+ for (int i = 0; i < n.Length; i++) {
+ foreach (ControlFlowEdge edge in nodes[i].Outgoing) {
+ GraphVizEdge ge = new GraphVizEdge(i, dict[edge.To]);
+ if (edge.IsLeavingTryFinally)
+ ge.style = "dashed";
+ switch (edge.Type) {
+ case ControlFlowEdgeType.ConditionTrue:
+ ge.color = "green";
+ break;
+ case ControlFlowEdgeType.ConditionFalse:
+ ge.color = "red";
+ break;
+ case ControlFlowEdgeType.Jump:
+ ge.color = "blue";
+ break;
+ }
+ g.AddEdge(ge);
+ }
+ }
+ return g;
+ }
}
}