Recently a friend banged me over the head with Reflector, I had a play, and discovered the wonderful "Graph Plugin", which draws pictures of software. It didn't quite draw the pictures I wanted, so I've added one, and written this article about how easy it was.
The picture I wanted was methods within a class showing which method called which others. For most classes, this is minimal, but for some classes, especially complex UI classes, a diagram like this can be very useful.
This is Reflector, the MSIL dissassembler, by Lutz Roeder, and this is the Graph Plugin, with the instruction call graph, by Jonathan de Halleux. Reflector is obfuscated, sadly, but the source code is available for the Graph Plugin. It uses QuickGraph and GLEE, which I've included in the download, along with Reflector.
QuickGraph is the underlying graph structure, and Glee provides the viewer control and layered layout engine. The combination works well, in that generally a readable diagram is presented.
Finding Method Calls
When Reflector activates our plugin for a class
activeType, thanks to Reflector, we can run over the methods very simply like this :
foreach (IMethodDeclaration method in activeType.Methods)
For each method above, thanks to the Graph Plugin, we can now run over the instructions in the method, also very simply like this :
InstructionGraph igraph = new InstructionGraph(method);
foreach (IInstruction i in igraph.Body.Instructions)
We can also then pick out the "call" instructions that we're interested in like this :
FlowToCodeConverter flowConverter = new FlowToCodeConverter();
if (flowConverter.Convert(i.Code) !=
This is the basic mechanism that this modified plugin will use to locate method dependencies. We run over the list of methods in the class twice. Once to see which methods we have defined in the class, and a second time to see which methods call which others. Things are complicated by overloaded methods, which have to be tracked individually, and by property
get set methods, which can be shown or hidden.
Note that the code included here is not mine, but belongs to Jonathan de Halleux. All we're doing here is adding another control and using the IL call graph / visitor code he's built. I've also taken the liberty of modifying the selection for the original diagrams to click-select, rather than mouse over select.
There are some issues which would be nice to sort out with the Glee viewer control, which I haven't looked into yet:
- Zoom seems a little awkward, right click to "go back" might help.
- I haven't worked out how to adjust node position manually.
- Placement of disconnected nodes seems a little random.
- Only worked out how to affect the layout using AspectRatio.
Using the Code
You should be able to run reflector from the extracted bin folder, or take the Reflector.Graph.dll and put it in your Reflector folder, if you have it installed already. When you run Reflector, you may have to View|Addins|Add Reflector.Graph.dll before you'll see the extra right click menu options.
When you're on a class, you should have the right click menu for Method Dependencies, which will open the new control for the selected class. Selecting methods in the diagram should focus the method in the main tree control.
If you're interested, the code is mostly 3 methods in HuffsMethodDeps.cs, which are all commented line by line so you can see what's happening.
Points of Interest
Updating the plugin was surprisingly easy. We pretty much create a control, inform the plugin mechanism, and let it know what sort of item we want it to be available for :
UserControl huffsMethodDeps = new HuffsMethodDeps(serviceProvider);
huffsMethodDeps, "Huffs Internal Functional Dependencies");
this.AddCommand("Browser.TypeDeclaration", "Huffs Internal Functional Dependencies",
After that, we just add the button click and we're away.
private void HuffsMethodDeps_Click(object sender, EventArgs e)
this.windowManager.Windows["Graph.HuffsMethodDeps"].Visible = true;
- 06/08/2007 - Article created