Method Tree Visualizer :: Fun with IronPython, Cecil and Netron Graph - Part III
As I said in the last post, the output from Microsoft GLEE looked but not ideal and as the method tree gets bigger with more relationships, the diagram gets out of control. Disappointed with that, my further search takes me to the Netron Project, which is a diagramming and graph layout toolkit for Microsoft .NET Framework.
Note that you'll find multiple sources of the Netron Project on the net. I found 3 different places where I can download the toolkit.
http://sourceforge.net/projects/netron/
http://sourceforge.net/projects/netron-reloaded
http://www.orbifold.net/Netron/
I believe the third one is the latest and supported. Netron also has a cousin for WPF diagramming called Unfold which is also available from http://www.orbifold.net/default/.
The download comes with the Lithium tree control which is a perfect match for our methods tree. Combine that with the XML Visualizer (Also included with the download) by Howard Van Rooijen and my work is almost done. All I need to do it to generate the XML file for the method tree. Here is how it will work:
To generate the XML file, I'll again use IronPython and the .NET XML support. Remember we have the drawMethodTree() function in our python script which we were using to generate the GLEE graph. As we are no longer using GLEE, therefore I replaced it to generate XML elements.
As we any other new library, we need to add the reference and import the namespace members.
>>> clr.AddReference("System.Xml")
>>> from System.Xml import *
>>> from System.IO import *
>>> from System.Text import *
The code to create an XML file using FileStream is pretty simple and self-explanatory.
>>> fs = FileStream("methods.xml", FileMode.Create)
>>> w = XmlTextWriter(fs, Encoding.UTF8)
>>> w.WriteStartDocument()
>>> w.WriteStartElement("methods")
>>> drawMethodTree(pMet, 0, w, 1)
>>> w.WriteEndElement()
>>> w.WriteEndDocument()
>>> w.Flush()
>>> fs.Close()
The drawMethodTree() now takes in XMLTextWriter as argument and writes the child elements.
>>> def drawMethodTree(mDef, level, writer, callSeq):
>>> if isinstance(mDef, MethodDefinition):
>>> msg = '\r\n>>> %d - Parent Method: %s' % (level, mDef)
>>> print msg
>>> writer.WriteStartElement(mDef.DeclaringType.Name + '.' + mDef.Name)
>>> for ins in mDef.Body.Instructions:
>>> if isValidInstruction(ins):
>>> print ins.OpCode.Name
>>> msg = '\r\n' + ins.Operand.ToString()
>>> nextLevel = level + 1
>>> callSeq = callSeq + 1
>>> drawMethodTree(ins.Operand, nextLevel, writer, callSeq)
>>>
>>> writer.WriteEndElement()
This generates the following XML file (considering that we are using the original .NET solution we started with):
<?xml version="1.0" encoding="utf-8"?>
<methods>
<MainCase.PublicMethod>
<MainCase.PrivateMethod />
<SecondCase.Help>
<SecondCase.HelpMeToo />
</SecondCase.Help>
</MainCase.PublicMethod>
</methods>
And loading this XML file through the XML Visualizer gives us the nice clean method tree shown below.
Cool? I know :)
What's next? I'll try to run some other code through this to check if it still works. Any suggestions/comments are most welcome.
Download Binary (Extract and run FrontEnd.exe - You need to have methods.xml in the same directory)
View Python Script