AddThis Social Bookmark Button

Print

Hacking Visual Studio
Pages: 1, 2, 3, 4, 5

Create Comments Faster

There are boring parts of the XML commenting process that you can automate to make documentation more fun (and more likely to happen).

The problem with XML documentation comments is that somebody has to write them. Even worse, often enough that someone is you. The Visual Studio IDE helps you by preparing an empty template when you type /// in front of a method, but in the end you still have to fill in the blanks.

Here's an example. Imagine a method "AppendHtmlText" that is used to append HTML text to some sort of buffer. This method has several overloads, and one of these overloads has a parameter of type "HtmlProvider". This is what Visual Studio will create when you start writing a new XML documentation comment:

/// <summary>
///
/// </summary>
/// <param name="htmlProvider"></param>

public void AppendHtmlText(HtmlProvider htmlProvider)
{
    ...
}

You would then add your text, so the XML documentation comment could, for example, look something like this:

/// <summary>
/// Appends the HTML text of the specified provider.
/// </summary>
/// <param name="htmlProvider">The HTML provider.</param>

public void AppendHtmlText(HtmlProvider htmlProvider)
{
    ...
}

This is a typical method that comes by the dozen: the method name pretty much says what it is doing and you definitely do not need much imagination to write the comment—after some time, these methods become a real drain to document. On the other hand, you simply have no choice. If you want the benefits of XML documentation comments (perhaps a nice help file generated by NDoc [Hack #71] ), you have to comment all public (and protected) members, period.

Let's take a closer look at the earlier example. The method is written according to Microsoft's Design Guidelines for Class Library Developers; some of these rules are:

  • Identifier names consisting of multiple words are written in PascalCasing (the method name) or camelCasing (the parameter name).

  • Acronyms are treated like normal words and are formatted accordingly (for example, "Html" instead of "HTML").

  • Identifier names do not contain abbreviations.

  • Method names usually start with a verb.

Now when you look at this set of rules on one hand and the documentation you have written on the other, it is pretty safe to say that a large part of the documentation could have been generated automatically.

GhostDoc

GhostDoc is an add-in for Visual Studio .NET 2003 that tries to do just that. With GhostDoc installed, you move the cursor into the method or property you want to document, invoke the Document This command using either the source editor's context (right-click) menu or a hotkey, and GhostDoc will create an XML documentation comment. The result for the previous example would be:

/// <summary>
/// Appends the HTML text.
/// </summary>
/// <param name="htmlProvider">The HTML provider.</param>

public void AppendHtmlText(HtmlProvider htmlProvider)
{
    ...
}

Pretty close—but how does GhostDoc do that? First of all, it's important to note that the add-in has no idea of what the identifiers actually mean—GhostDoc simply assumes that the code is written according to the guidelines and does the following:

  • It breaks up identifier names into single words by analyzing the casing.

  • A word consisting of only consonants (for example, "HTML") is automatically treated as an abbreviation (other abbreviations, for example, "UML," can be specified explicitly).

  • For methods, the first word is treated as a verb and thus an s (in some cases es) is added.

  • A "the" is added between the first and the second word of the method name (unless the second word belongs to a configurable list of words that are never preceded by a "the").

After GhostDoc has created the XML documentation comment, the developer has to edit only a few details (for example, for the AppendHtmlText method, add "using the specified provider" to the end of the sentence) before moving on to the really interesting part of the documentation: remarks on usage, references to related methods or properties, example code—information that cannot be created automatically.

GhostDoc is driven by generation rules. When an XML documentation comment is about to be generated, the add-in will collect information about the code element (method, property, indexer, etc.) like name, return type, parameter names and types, and so on. This information is then compared to a set of rules, and the rule that fits best is then used to generate the documentation.

With each version of GhostDoc, the number of rules grows; the more specialized they are (for example, rules for handling Boolean properties, methods with a name consisting of only one word, etc.), the better the results.

Here are a few more examples that show only a part of what GhostDoc can automatically generate:

Documentation for an indexer

Note that the rule for indexers takes the name of the parameter into account, so it is "at the specified index", but "with the specified name":

/// <summary> /// Gets the <see cref="System.String"/> at the specified index. 
/// </summary> /// <value></value> public string this[int index] 
{ 
    get { ... } 
}

Boolean properties with a name consisting of only one word

If you comment Boolean properties in .NET Framework documentation style, you will definitely recognize the "Gets or sets a value indicating whether..." rule, and most likely you already have stopped counting the times you have typed this phrase:

/// <summary> /// Gets or sets a value indicating whether 
/// this <see cref="Demo"/> is cool. 
/// </summary> /// <value> /// <c>true</c> if cool; otherwise, <c>false</c>. 
/// </value> public bool Cool 
{ 
    get { return true; } 
    set { ; } 
}

A method with "of the" reordering for method and parameter names

The so-called "of the" reordering is triggered by specific words such as "size," "length," or "name" (the list of trigger words can be configured):

/// <summary> /// Determines the size of the page buffer. 
/// </summary> /// <param name="initialPageBufferSize">

/// Size of the initial page buffer.</param> 
/// <returns></returns> 
   public int DeterminePageBufferSize(int initialPageBufferSize)

Getting Started

First, you will need to download and run the GhostDoc installer from http://www.roland-weigelt.de/ghostdoc.

After running the GhostDoc installer, the next time you start Visual Studio, a couple of configuration dialogs appear to complete the setup (for example, choose a hotkey). Note that GhostDoc cannot install a hotkey if Visual Studio is not already using a custom keyboard scheme—this is a limitation of Visual Studio's extensibility model. If you are not sure, simply try to assign a hotkey; if GhostDoc setup encounters a problem, it will tell you what to do.

GhostDoc comes with a C# source file that demonstrates the features of this add-in; simply load the demo project, which can be found in a subdirectory of the folder GhostDoc was installed to. Inside Visual Studio, open the Demo.cs C# file, move the cursor into the body of a method, for example, and invoke the Document This command. The Document This command can be invoked using the hotkey, from the right-click menu, or from Tools → GhostDoc → DocumentThis.

After you invoke the Document This command, GhostDoc will go to work and generate as much of your XML comments as it can.

Tweaking GhostDoc

Certain aspects of GhostDoc can be configured:

  • Which words are treated as acronyms

  • Which words must not be preceded by "the"

  • Which words trigger the "of the" reordering of an identifier name's words

  • The fixed parts of the generated texts.

You can edit the configuration settings in the dialog that is opened Tools → GhostDoc → Configure GhostDoc. This dialog is shown in Figure 8-2.


Figure 8-2. GhostDoc Configuration dialog

In this dialog, you can also export settings to a file that can then be imported on a different computer. This is pretty handy if, for example, you want to keep the configurations at home and at work in sync.

Roland Weigelt

Pages: 1, 2, 3, 4, 5

Next Pagearrow