Using Visual Studio’s Code Model objects for code base understanding

A bit of a diversion from the normal SQL Server posts. Recently I’ve found a very useful feature in Visual Studio that can help to analyze large amounts of source code – the Visual Studio Code Model objects

Depending on the language of the code base a different set of objects are available to you. In this example I’ve used the VCCodeModel to walk through all the code elements of a C++ project.

 

 

using System;

using System.Collections.Generic;

using System.Text;

using EnvDTE;

using EnvDTE80;

using Microsoft.VisualStudio.VCCodeModel;

namespace CodeModel

{

    class CodeWalker

    {

        static public void WalkCodeElements()

        {

           

            //get a reference to the visual studio environment

      EnvDTE80.DTE2 dte2;

            dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.

            GetActiveObject("VisualStudio.DTE.8.0");

            //assume the first project in the solution is the interesting one

            Project project = dte2.Solution.Projects.Item(1);

           

            //get the code model for the VC project

            VCCodeModel vcCM = ((VCCodeModel)(project.CodeModel));

            VCCodeElement vce = null;

            if (vcCM != null)

            {

                for (int i = 1; i < vcCM.CodeElements.Count; i++)

                {

                    vce = ((VCCodeElement)

                        (vcCM.CodeElements.Item(i)));

                    printElementInformation(vce, "");

                   

                }

            }

        }

       

        static public void printElementInformation(VCCodeElement el, string level)

        {

            Console.WriteLine("{0}{1} ({2} references)", level, el.Name, el.References.Count);

            //recursively print children

            foreach (VCCodeElement child in el.Children)

                printElementInformation(child, level + "t");

        }

    }

}

 

Given this input:

class ClassA

{

public:

      int MyFunction()

      {

            return 1;

      }

}

class ClassB: public class ClassA

{

public:

            int MyOtherFunction()

            {

                  return 2;

            }

}

class ClassC: public class ClassB

{

      public:

            int YetAnotherFunction()

            {

                  return 3;

            }

}

int main(void)

{

      ClassB MyClass;

      MyClass.MyOtherFunction();

}

 

The example generates this output:

main

ClassC

        YetAnotherFunction

        ClassB

ClassB

        MyOtherFunction

        ClassA

ClassA

        MyFunction

 

The possibilities are exciting. One could use this object model to graph dependencies, or generate documentation from only source code.

Cheers!