How to: Use the CodeModel Object to Analyze Visual Basic Code
Using the CodeModel2 object hierarchy is an alternative to the potentially complex task of parsing text in a code file. You can use the CodeModel2 object:
To analyze the structure of your code.
As a basis for documenting your code.
The procedures that follow assume that you know how to access the Macros development environment and create a macro project. For more information, see Add Macro Project Dialog Box.
Namespaces are contained at the root level of the CodeModel2 object or nested in other CodeNamespace objects. This reflects the syntax constraints on namespaces. A namespace is either a top-level code block or contained in another namespace. To use the following procedures, you must have a project open in the Visual Studio integrated development environment (IDE).
Note
The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. These procedures were developed with the General Development Settings active. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Customizing Development Settings in Visual Studio.
To find all the namespaces contained in your project
Write a recursive method to retrieve all the namespaces in an application.
The CodeNamespace object has a Members property that contains all the CodeElements at the first level of the namespace.
' Macro editor Sub FindAllNamespaces() Dim cm As CodeModel cm = DTE.Solution.Projects.Item(1).CodeModel ' Look for all the namespaces in the CodeElements ' of the project. Dim list As String Dim ce As CodeElement For Each ce In cm.CodeElements If TypeOf ce Is CodeNamespace Then GetNamespace(CType(ce, CodeNamespace), list) End If Next MsgBox(list) End Sub Sub GetNamespace(ByVal ns As CodeNamespace, ByRef list As String) ' Add this namespace to the list. list &= ns.Name & ControlChars.CrLf Dim aspace As CodeNamespace Dim ce As CodeElement ' Look for more namespaces. For Each ce In ns.Members If TypeOf ce Is CodeNamespace Then GetNamespace(CType(ce, CodeNamespace), list) End If Next End Sub
Note
You can find all the namespaces in one source file by using the FileCodeModel property of the ProjectItem object associated with the source file. Using this approach would require a slight change to the FindAllNamespaces method.
Finding the Default Namespace
The procedure above returns only the namespaces you have defined in your application. Every Visual Basic project also contains a default namespace. All the code elements in your application are contained in the default namespace, although the CodeElements collection does not contain a CodeNamespace object for it. The default namespace can be retrieved from any top-level CodeType element.
To find the default namespace for your project
Test the top-level code elements of the project. Any code element that is a CodeType returns the CodeNamespace element for the project.
Sub FindDefaultNamespace() Dim cm As CodeModel cm = DTE.Solution.Projects.Item(1).CodeModel Dim ce As CodeElement Dim ct As CodeType = Nothing Dim defNameSpace As CodeNamespace For Each ce In cm.CodeElements If TypeOf ce Is CodeType Then ct = CType(ce, CodeType) defNameSpace = ct.Namespace End If Next If Not IsNothing(defNameSpace) Then MsgBox(defNameSpace.Name) End If End Sub
Finding Classes
Class declarations and namespaces are retrieved through similar means. Because classes can be nested in other classes, you can find classes defined both in namespaces and in other classes.
To find all the classes contained in your project
Write a recursive method, such as the one that follows, to find the class declarations in a project.
' Macro editor Sub FindAllClasses() Dim cm As CodeModel cm = DTE.Solution.Projects.Item(1).CodeModel ' Look for all the namespaces and classes in the ' project. Dim list As String Dim ce As CodeElement For Each ce In cm.CodeElements If (TypeOf ce Is CodeNamespace) Or (TypeOf ce Is CodeClass) Then ' Determine whether that namespace or class ' contains other classes. GetClass(ce, list) End If Next MsgBox(list) End Sub Sub GetClass(ByVal ct As CodeElement, ByRef list As String) ' ct could be a namespace or a class. Add it to the list ' if it is a class. If (TypeOf ct Is CodeClass) Then list &= ct.Name & ControlChars.CrLf End If ' Determine whether there are nested namespaces or classes that ' might contain other classes. Dim aspace As CodeNamespace Dim ce As CodeElement Dim cn As CodeNamespace Dim cc As CodeClass Dim elements As CodeElements If (TypeOf ct Is CodeNamespace) Then cn = CType(ct, CodeNamespace) elements = cn.Members Else cc = CType(ct, CodeClass) elements = cc.Members End If For Each ce In elements If (TypeOf ce Is CodeNamespace) Or (TypeOf ce Is CodeClass) Then GetClass(ce, list) End If Next End Sub
See Also
Tasks
How to: Create a C# Class by Using the CodeModel Object
Concepts
Overview of the CodeModel Object for Visual Basic and C# Applications