Jul 06, 2007

Reverse Engineering CLR 2.0 Generics

There are two goals with this new Reverse Engineering API:

  1. Implement an extensible, clean and easy-to-use Reverse Engineering API, hiding complex things by using UML-magic methods.
  2. Implement CIL plugin by using this new API, to read 1.1 and 2.0 CLR assemblies.

To accomplish second goal I decided to use Cecil instead of Reflection because, IMO, Cecil has a cleaner API (not yet documented, but going to sources helps and, of course, you can always ask) and thinking on the future we might read the full assembly (including method body, for example) to define some diagrams, such as Sequence Diagram.

Most notable difference between first version and this new one, is the 2.0 CIL support, and reverse engineering Generics isn't that easy, to do so the following are my ideas to face and finish both implementations:

  1. Refactor CIL plugin to handle on a clean way all the Cecil's TypeReference, including PointerType, ArrayType, ReferenceType and GenericInstanceType. Today am using the if-else-if "pattern" not even close to best solution.
  2. Test nUML to handle Templates, I did some tests and many worked, template binding and XMI exporting seems to crash, however template definition doesn't. The following is my test case:

using System;
using System.IO;
using NUml.Xmi2;
using NUml.Uml2;

class MainClass
{
public static void Main(string[] args)
{
DataType TObj = Create.DataType ();
TObj.Name = "TKey";
DataType KObj = Create.DataType ();
KObj.Name = "TValue";
TemplateSignature signature = Create.TemplateSignature ();
ClassifierTemplateParameter T = Create.ClassifierTemplateParameter ();
ClassifierTemplateParameter K = Create.ClassifierTemplateParameter ();
T.Signature = signature;
T.Default = TObj;
K.Signature = signature;
K.Default = KObj;
signature.Parameter.Add (T);
signature.Parameter.Add (K);
Class klass = Create.Class ();
/* Systems.Collection.Dictionary`2[TKey , TValue] emulation */
klass.Name = "Dictionary";
klass.OwnedTemplateSignature = signature;

SerializationDriver driver = new SerializationDriver ();
driver.AddSerializer (new NUml.Uml2.Serialization.Serializer ());
driver.Serialize (new object [] { klass, T, K, TObj, KObj },
Console.OpenStandardOutput(), "urn:numl.sourceforge.net:testing:templates");
}

}

  1. Implement the MonoUML visualizer, to show the Parameters defined on the Templates.
  2. Test, test and test.

If you are wondering about Templates and so on, UML 2 Super Structure (05-07-04) defines them from page 600 to 631, go ahead.