Click here to Skip to main content
15,881,709 members
Articles / Programming Languages / C#
Article

XML Comments for Managed C++ Applications

Rate me:
Please Sign up or sign in to vote.
4.70/5 (17 votes)
9 Nov 20046 min read 213.5K   2K   36   62
Visual Studio .NET Add-in allowing XML style comments in Managed C++ applications.

Image 1

Introduction

Most of my application development these days is in C#. Over the past two years, I have grown accustomed to the C# XML comments built into the C# editor. As we all know by now, you can edit the project properties of your C# application and define an XML documentation file. With that processed XML file and the compiled assembly, NDoc can automatically build a Windows help file for your software.

There are days, though, when I have to leave the friendly confines of C# and drop down to C++. When this happens, I am usually writing a managed C++ class that hides unmanaged functionality (for example, serial port access). At that point, though, we have lost our ability to use XML commenting of our source code. Without XML commenting and the processing of those XML comments, we cannot use NDoc for that subsystem. That is a real problem, given that 90% of my projects are C# and documented in NDoc!

A while back, I wrote a Visual Studio Add-in (in C#) that handles XML commenting for managed C++ applications. It allows you to type XML comments. When the assembly is compiled, it processes the XML comments and builds a processed XML file that can be used as input to NDoc. This way, I can consistently comment all of my source code!

Writing Add-Ins

Support for add-ins in Visual Studio exists in the form of an "extensibility" project called "Visual Studio .NET Add-in". I will not cover the nuances of creating add-ins. If you want a good book on the subject, refer to the book "Developing Visual Studio .NET Macros and Add-Ins" by Jeff Cogswell. It is one of the few references I found.

Once you create an add-in project, you can then create event handlers for the specific events that are relevant for your add-in. There is an extensive object model describing the layout of the Visual Studio environment, solutions, and projects.

Two Areas To Address

When designing this add-in, there were two separate areas of concern. The first is to provide support for entering XML comments into source code. As we all know, when you start typing '///' in the C# editor, it automatically will expand if it precedes a method or property definition. I wanted to try to maintain a similar user experience.

The second area to address is the processing of those XML comments in order to build the XML comment files that can be used by NDoc.

Entering XML Comments Into Source Code

The first decision I made was that XML comments would be added to the header file. That is where all methods and properties will be defined, so naturally it is a logical place for the user to enter the XML comments. When I created the project, I was hoping to find an event that would fire each time the user pressed a key in the editor. However, that level of notification does not exist. I quickly discovered that the only editor event that came close was a line changed event from the TextEditorEvents object. This event gets fired every time the line number changes, including when the enter key is pressed.

Practically, this means that we cannot duplicate the exact behavior of the C# comment completion feature. The best that could be done is to make a check for '///' when a line changes. Hence, if you type '///' then press the enter key, the add-in will determine if XML comments are appropriate. If so, then it will expand the section to look like the familiar:

C#
///<summary>
///
///</summary>
CSerialPort(void);

From there, you can enter a summary comment.

As noted above, when you enter a new comment section, the code in the Line Changed event will scan the editor to see if the comment is before a function or a variable definition. If it determines the target is a function, it will attempt to decode the parameters of the function and build the appropriate XML comment structure. For example:

C#
///<summary>
/// 
///</summary>
///<param name="port"> </param>
///<returns> </returns>
bool    Open(int port);

If you are in the middle of an XML comment section and you press Enter, it will recognize your position and automatically add '///' to the start of the new line and space it with the other comment tags in the section. For example, in the example above, if the cursor was at the end of the 'param name = "port"' line and you pressed Enter, the comment section would look like this...

C#
///<summary>
/// 
///</summary>
///<param name="port"> </param>
///
///<returns> </returns>
bool    Open(int port);

Processing XML Comments to make the XML File

After the XML comments are entered into the header file, they need to be processed to create the XML comment file. To do that, I create an event handler to monitor the Build Done event for the project. Whenever a project is built, that event will fire and the add-in is notified. It will check to make sure that the XML comment file should be built. It only builds the comment file for managed C++ projects that have been successfully built.

The building of the XML file is fairly straightforward. When the project is built, the compiler creates a data structure that describes all the entities associated with the code. Every property, method, enumeration, namespace, etc. is represented as a CodeElement. We can examine the CodeElement object for the project after it is built, to get a list of all entities in the project. We can iterate through the object list and examine the Kind each element represents. Based on the type, we create nodes in the XML document object that follows the format for the XML commenting scheme.

The code is not perfect

I developed this code rather quickly. Like most of us, I do not have time to make it perfect. It does what I need it to do.

There was one area in particular I wanted to address, but was unsuccessful. The way the add-in works now, the XML comment file will always be built if you are compiling a managed C++ application. The file it creates is based on the project file name. The file is always placed in the active configuration directory. For example, if the project is called 'MyProj' and you are building a Release build, the XML file will always be "Release/MyProj.xml". What I tried to do was build a project extender property that would allow you to specify the XML file name and location. I was unsuccessful in getting that done. If anyone has suggestions, let me know.

Limitations

The add-in assumes that attribute definitions are defined immediately preceding a function definition on the lines above the function. When processing the code, the add-in examines each line using a simple Regex.IsMatch function. When looking for attributes, it uses "\\[(.)*\\]".

History

  • 5/14/2004 - Corrections for bug when processing function parameters.
  • 5/20/2004 - Added exception handling and stack trace when failure occurs.
  • 5/26/2004 - Handles interface documentation. Fixed misc. bugs in decoding parameter text.
  • 8/09/2004 - Attributes are now handled. See 'Limitations' section above for more details.
  • 9/22/2004 - Updated based on user feedback. Should fix problems with enumerations and parameters. Many thanks to M Ward and FredericM102LI90.
  • 11/09/2004 - Fixed exception being thrown when no .h file exists. Thanks to barrd for pointing this one out.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Omron Adept Technologies, Inc
United States United States
I have been developing software professionaly since 1991 writing software in automation and manufacturing environments. For 14 years I worked for companies that built custom robotic automated equipment for the semiconductor, telecommunications, and other industies. Presently, I work for a company that manufacturers industrial robots where I write high level coordination and control software.

My undergraduate degrees are in Mathematics and Philosopy. My graduate degree is in Management Information Systems. I am MCSD certified in Visual C++ 6.0 and MCSD.NET certified in C#. I am also have the PMI-ACP certification.

I enjoy karate and reading.

Comments and Discussions

 
GeneralRe: Making NDoc work... Pin
Bloodflowers13-Dec-04 4:29
Bloodflowers13-Dec-04 4:29 
GeneralBug if there is no header file Pin
barrd7-Oct-04 12:48
professionalbarrd7-Oct-04 12:48 
GeneralRe: Bug if there is no header file Pin
Ummm_Hello4-Nov-04 6:16
Ummm_Hello4-Nov-04 6:16 
GeneralRe: Bug if there is no header file Pin
barrd5-Nov-04 10:21
professionalbarrd5-Nov-04 10:21 
GeneralRe: Bug if there is no header file Pin
barrd16-Nov-04 5:41
professionalbarrd16-Nov-04 5:41 
GeneralClasses with events and delegates Pin
M Ward21-Sep-04 13:53
M Ward21-Sep-04 13:53 
GeneralProblem with enums and strings (with fix) Pin
FredericM102LI9025-Aug-04 12:08
FredericM102LI9025-Aug-04 12:08 
GeneralGreat Stop gap until 2005 Pin
SRG Fraser19-Aug-04 6:40
SRG Fraser19-Aug-04 6:40 
This ia a great stop gap until Microsoft release Visual Studio .NET 2005 which will finally include this feature! (It's about time cause then I can finally add it to the second release of my book "Managed C++ and .NET 2.0 Development", Apress)

Not sure what Microsoft was thinking by not including this feature. Confused | :confused:


Author of:
Real World ASP.NET: Building a Content Management System (Apress)
Managed C++ and .NET Development (Apress)
Managed C++ and .NET 2.0 Development (Apress) releasing this winter.
General'StartIndex' exception when processing simple interface declaration Pin
Claus Brod29-Jul-04 6:03
Claus Brod29-Jul-04 6:03 
GeneralAttributes cause an exception Pin
Glen_Summers13-Jul-04 4:26
Glen_Summers13-Jul-04 4:26 
GeneralSome MC++ prototypes dont work with nDoc Pin
Glen_Summers12-Jul-04 6:28
Glen_Summers12-Jul-04 6:28 
Generalenums members get summary from enum not themselves Pin
Glen_Summers12-Jul-04 5:50
Glen_Summers12-Jul-04 5:50 
GeneralCool thing, thanks a lot! Pin
irrlicht6-Jun-04 0:06
irrlicht6-Jun-04 0:06 
GeneralRe: Cool thing, thanks a lot! Pin
Jay Nelson7-Jun-04 3:09
Jay Nelson7-Jun-04 3:09 
GeneralProblems with Template Types Pin
Member 11526115-Jun-04 14:45
Member 11526115-Jun-04 14:45 
GeneralRe: Problems with Template Types Pin
Anonymous25-Oct-04 6:20
Anonymous25-Oct-04 6:20 
GeneralDoes it work with unmanaged C++ Pin
Michael Kennedy19-May-04 20:19
Michael Kennedy19-May-04 20:19 
GeneralRe: Does it work with unmanaged C++ Pin
Jay Nelson20-May-04 3:08
Jay Nelson20-May-04 3:08 
GeneralRe: Does it work with unmanaged C++ Pin
Anonymous25-Oct-04 6:15
Anonymous25-Oct-04 6:15 
GeneralXML Comment File not generated Pin
Jon Lea13-May-04 5:54
Jon Lea13-May-04 5:54 
GeneralRe: XML Comment File not generated Pin
Jay Nelson14-May-04 12:00
Jay Nelson14-May-04 12:00 
GeneralRe: XML Comment File not generated Pin
sloutsky16-May-04 21:34
sloutsky16-May-04 21:34 
GeneralRe: XML Comment File not generated Pin
finkwt18-May-04 4:36
finkwt18-May-04 4:36 
GeneralRe: XML Comment File not generated Pin
Jay Nelson18-May-04 5:24
Jay Nelson18-May-04 5:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.