"Cloning" Comments

Feb 17, 2008 at 8:58 PM
I am working on a large (10,000+ source files) project. We have developed extensive comments for the interfaces and key base classes. We would like to leverage this work to apply the identical comments (in the actual source code) to the implementations and derived classes (at the class, and member levels). Unfortunately all avenues of investigation and development have led to dead ends. Being able to accomplish this would save hundreds of man hours.

Any suggestions, comments, etc would be greatly appreciated.
Feb 17, 2008 at 10:22 PM

I'm not sure because I've never used it myself, but GhostDoc might help with that.

An alternative, which I have used, is the <include> tag. See this discussion for more information:

Common remarks for overloads

- Dave
Feb 18, 2008 at 4:30 PM
Thanks for the response.

1) GhostDoc can help a little bit, buut it will only process individula methods, etc for "inherited" documentation cloning. Still have to hit the HotKey tens of thousands of times....
2) Using the include tag WILL cause the same documentation to appear in multiple places. However I need to ability to expand and/or tweak the documentation in many of the derived classes....

Still looking for a solution....
Feb 18, 2008 at 6:35 PM

I'm not sure what you're looking for then. It sounds like <include> is your best choice since you can use the same documentation in many places or, optionally, create a slightly-modified version and use it in a subset of places. What more do you need?

- Dave
Feb 18, 2008 at 7:15 PM
In this project there are a relatively small number of VERY general interfaces and base classes. It is not unusual for a single interface to be leveraged by 20-50 eventual leaf classes. While the "conceptual" functionallity is comment, the "behavioral" functionallity can differ significantly. This means that there is significant editing to the content at each of the base classes, but even with this editing, the bulk of the content (70-95% of the characters) is identical with the edits interpsersed throughout the text.

What we are currently doing is finding a method in the leaf class, setting a book mark, searching for the base implementation, copying and pasting the comments and then editing them. This is tedious and can be error prown. For example:

// Each of the following have RADICALLY different comments for "GetPressure...

interface IPressureSensorTypeA { double GetPressure(); }
interface IPressureSensorTypeB { double GetPressure(); }
interface IPressureSensorTypeC { double GetPressure(); }

class HaydenPressureGauge : IPressureSensorTypeC { double GetPressure() ; }
class OrcoPRessureGauge : IPressureSensorTypeA { double GetPressure() }

The "Hayden" needs all of the descriptive text of IPRessureSensorTypeC, but the limits, graphs, and other parameters (scattered throughout the remarks in a format "standard" to the system engineers (not programmers)) .

The "Orco" needs a completely different text basis (which has already been developed at the Interface level, but again with the same type of scattered substitutions.

Therefore there is NO place where we can segment out the "Fixed" from the variable, NOR is it acceptable from a documentation standpoint to have links or references, as all of the Documentation and specifications must eventually result in printed stabndalone "spec sheets".

Previously (over the last 20 years...) most of this documentation was done completely independantly from the source code, using custom applications (often based on nroff or other unix text processing environments). Our current requirements dictate that the material be inline with the actual source.

If I could only figure out a way to map back from "Type, MethodInfo, FieldInfo, PropertyInfo, EventInfo" to the actual source line where the declaration starts, I could easily adapt some of our existing tools. But this has proven to be a dead end. Tools such as mDbg, Pdb2Xml only cover those items that actually generate MSIL (ie have sequence points). I have looked into trying to do this part with a VS-2008 add-in, but none of the team has direct experience in that area, and no progress has been made.
Feb 18, 2008 at 8:32 PM

Thanks for the details.

So if you could get this to work with <include>, would it be acceptable even though your "current requirements dictate that the material be inline with the actual source"?

Because here's what I had in mind:

Example Documentation Comments
/// <remarks>
/// These are some remarks with a graph: 
/// <include file="graphs.xml" path="//*[@id='1']/*"/>
/// This text is not common, but <include file="remarks.xml" path="//*[@id='common']/text()"/>
/// We've just componentized our documentation! :)
/// </remarks>
<?xml version="1.0" encoding="utf-8" ?>
  <graph id="1">
    <img src="graph1.jpg"/>
<?xml version="1.0" encoding="utf-8" ?>
  <category id="common">this text is.</category>
XML Documentation File Result
These are some remarks with a graph: 
<img src="graph1.jpg"/>
This text is not common, but this text is.
We've just componentized our documentation! :)
- Dave
Feb 19, 2008 at 1:50 PM

Sweet! but I dont see how it helps me with the basic problem. The "Example Documentation Comments" still has to be manually inserted in front of each appropriate class/method/property/event.....

I did a search on "double GetPressure()" and there are over 100 implementations with 8 different templates (ie the 100 concerete implementations are implementations of 8 different interfaces).

How does the above help get the comments in front of the 100+ method declarations????
Feb 19, 2008 at 4:26 PM
As long as you require implemtation-specific documentation on the 100 concrete implementations, you are not going to get around the need for a lot of manual work. You're going to paste and manually edit the example documentation comments above in front of all 100 classes.

The approach described above at least factors out the common text into a separately maintained file, so you can add a sentence to all 100 classes by editing one file later on.

Another approach is to use the SHFB to suck in a comments-only XML file that you generate from a content-management system or similar.
This means you don't maintain the documentation in the source code, but keep track of the doc in a separate system, and have that generate an XML file for you that SHFB can merge with the documentation XML file from the compiler.
Feb 19, 2008 at 4:44 PM

Thanks for the reply. The manual editing I am NOT concerned with. It is the pasting of the appropriate "template" which already exists at the base class or interface.

Visual-Studio is capable of navigating to a base/declaation. And with add-ins like re-sharper, it can even go to the source in other projects (that are loaded in the solution), rather than showing the "reflected" view.

Therefore, it seems like a VS-2008 add-in could be developed which will

1) Reflect against an assembly, and gather all of the the Types, MethodInfo,, PropertyInfo, EventInfo signatures. These instances will also contain information related to "base" implementations.

2) Using the above information, go to the point in the source of the base/interface and parse backwards to gather the comments.

3) Go to the point in the source of the derived/concrete class, and paste this information if there are NO comments.

4) Repeat steps 2&3 for all of the items gathered in step #1

I have posted on a number os sites/forums, that I am willing to pay a reasonable amount for such an add-in (including source). I can then even update the add-in to do spcial substitution for other sources so that the complete set of comments are paced directly in-line with the code.....

Feb 19, 2008 at 7:19 PM

I can then even update the add-in to do spcial substitution for other sources so that the complete set of comments are paced directly in-line with the code.

It seems to me that you're taking this part too lightly, according to your former response:

"What we are currently doing is finding a method in the leaf class, setting a book mark, searching for the base implementation, copying and pasting the comments and then editing them."

and then editing them. is of particular interest to me. Inheriting raw documentation might be easy but adding the "changes" afterwards in an automated way probably won't be.

You also wrote that "edits [are] interspersed throughout", which might make it difficult to automate the insertion of specialized comments, and probably far too complex to manage even if it was implemented somehow. I.e., authors may still have to visit each API to include "limits, graphs, and other parameters" around the inherited documentation.

Brute force using external includes, with intuitive references, still might be your best choice IMO.

Sandcastle has a tool called MRefBuilder that generates an XML reflection file to describe APIs, including inheritance information. Instead of a VS Add-In you could write a tool that parses an XML reflection file for the different kinds of base APIs that you mentioned before. For each one the tool could look up the corresponding comments in XML documentation files generated by the compiler and copy them into some well-defined structure for your external XML include files. It could also add the include references to the XML documentation files automatically. Then you could pass the XML documentation files and the XML include files to authors who would just need to edit the raw XML documentation - outside of VS.

Although, if you absolutely must have the comments within the actual source code then this won't work.

Note that Microsoft doesn't use triple-slash comments either (according to some comments in blogs and videos that I've seen) because they have professional writers that write the documentation for the .NET Framework, so I don't see why having the comments in the actual source code on a project of this scale would even be a requirement - it doesn't seem to add any value. If it's IntelliSense that you want, an XSL transformation could pull out the appropriate elements from a larger XML documentation file and store them in an IntelliSense XML file that VS can use. The comments don't have to actually be in the source code.

- Dave
Feb 19, 2008 at 7:36 PM
I created an Intellisense build component for Sandcastle so extracting comments for that purpose can be done as part of the documentation build. It only pulls out the XML comments necessary for Intellisense and only for the documented APIs. It's available with SHFB or in the standalone build component download.

Feb 19, 2008 at 8:51 PM

I will definately have to look at the MRefBuilder output. That sounds like it might have what I need.

The "documentation with source" is a client requirement. I personally believe in the documentation being (primarily) external, and using technical writers rather than developers to create it. The thing that is a bit unusual with this particular project is that my Client (CompanyV) distributes many different subsets of the code (as source) to it's own customers (CompanyS, CompanyH, CompanyI) and in different versions for each of the custom (Industrial Automatioc) tools that they provide for the customer. They only want to "expose" the information that each company recieved as part of that specific tool.

This means that custom assemblies are dynamically created for each unique tool that they sell (MANY). That only include the classes which that tool will actually use. Even partial classes are heavily used to "fine-tune" the exact code that is exposed. Maintaining this independantly adds another set of operations that must be automated for the build process. Their though was that "hardbinding" the content (by including it directly in the source) would ensure that the documentation that was produced would ONLY contain those items for which the code was actually included in the build.

Feb 20, 2008 at 2:18 AM
Hi Eric,

How does it differ from the IntellisenseComponent2 that ships with Sandcastle?


I agree then that it does make sense to keep the documentation near the code.

Although, couldn't you just run the same "set of operations" for the XML documentation files as you do for the actual libraries in your automated builds? If you consider the documentation to be part of the product then it makes sense, even though it may be extra work; hopefully, only a one-time setup would be needed though.

- Dave
Feb 20, 2008 at 3:14 AM
I only looked VERY briefly at the IntellisenseComponent, but I did not see where it would do automated copy/paste of XML comments from one location to another........

I have been swamped this evening with negotiations on a new (major) contract, so I have not had a chance to look at the MRefBuilder output, but what I really need "when all is said and done" is a list with the following content:

1) Identifier that can be associated with an XML Comment : FileName and Line Number
2) ALL "base" identifiers (must match signature and inheritance) : FileName and Line Number


01) interface A
02) {
03) void Func1(int x);
04) void Func1(double y);
05) }
06) interface B
07) {
08) void Func1(int x);
09) void Func1(double y);
10) }

01) class C1 : InterfaceA
02) {
03) public void Func1(int x) {}
04) public void Func1(double y) {}
05) }
07) class C2: InterfaceB
08) {
09) public void Func1(int x) {}
10) public void Func1(double y) {}
11) }


File2.cs:01 = File1.cs:01
File2.cs:03 = File1.cs:03
File2.cs:04 = File1.cs:04
File2.cs:07 = File1.cs:06
File2.cs:09 = File1.cs:08
File2.cs:10 = File1.cs:09

From there, the rest is easy......
Feb 20, 2008 at 4:16 AM

The MRefBuilder utility generates an XML reflection file that doesn't contain source file information. (Sorry, but my point about using the compiler's <include> tag in this scenario is moot.)

Although I was not suggesting to update the code files anyway, but instead update the XML documentation files that were already compiled.

  1. Parse all api nodes in reflection.xml and build an in-memory index of the inheritance hierarchy as your tool should see it (e.g., index the IDs of base types).
  2. For each type, find the corresponding documentation in an XML documentation file that has already been generated by the compiler.
  3. If it's a base API then copy the documentation to all of its inherited elements in the XML documentation file (inheritance information can be retrieved from reflection.xml) based on whatever your proprietary rules are for including common documentation. If no documentation sections exist for derived types then create them based on the existing documentation of base types.
  4. You could then use a custom post-process include feature after the documentation is touched up (i.e., author doucmentation manually outside of VS and run the result through your tool again), which probably wouldn't be so difficult using XPath and a similar syntax as what the compiler supports. Then you could stick to my original idea of using include files to encapsulate portions of common documentation. (The pre-process would automatically copy in your comments into include files and just use a custom include tag in the XML documentation file instead. That should also keep the files smaller, making them easier to work with).
  5. Run the final documentation through your existing set of operations that remove APIs based on the tool that will be using them. (The logic should be identical to what's being used for the removal of actual APIs from code.)
Again, this does not have anything to do with the actual source code files though.

To get the final documentation back into the source code would probably take a hefty amount of work, whether in a custom tool or using Visual Studio automation (as you've already mentioned).

- Dave
Feb 20, 2008 at 1:16 PM

I would first like to really thank you for the time you have spend on this thread. And you have given me (and hopefully other who read this) some good tips on creating sophisticated documentation systems.

For my current situation however, finding a means to correlate source code locations is the ONE critical concern (wither source-2-soure or "ReflectionInfo"-2-source or some other means).

One idea I was given in another forum actually looks VERY promising although not "simple". It involves loading portins of the source into the CodeDom...I will post more if this pans out.

If you (or any other reader) knows of a good forum for Visual Studio 2008 add-in development, I would greatly appreciate it.
Feb 20, 2008 at 2:26 PM

It's really no problem. I enjoy brainstorming discussions :)

I understand that your real concern is updating the actual source code and I know that it's because of a client requirement. I just felt that it's worth pursing an alternative since, as I pointed out already, there's no good reason of which I'm aware to require the comments in the source code. Your clients may have the wrong idea about its advantages; e.g., quick access to documentation, yes. Easier than a compiled or intranet website help solution? Arguable. Code bloat, probably. Required for IntelliSense in Visual Studio? Nope. Using up your precious time, and possibly money, to work-around authoring issues and drawbacks? Yep.

The custom's always right though, right? ;)

Using CodeDom in a custom tool will probably work, it's just a question of whether that's easier and more effective than using Visual Studio's built-in code model feature and the code editor:

Discovering Code with the Code Model (Visual C#)

Discovering Code with the Code Model (Visual Basic)

System.CodeDom Namespace

I can't comment on its quality, but here's one forum that you might want to check out:

Visual Studio Extensibility Forum on MSDN

- Dave
Feb 20, 2008 at 2:41 PM

Thanks for the links :) :)

I agree 100% wih all of your points. Based on my (30+ years) experience, the ONLY advantage of the documentation embedded in the code is that is increases the odds that the documentation MIGHT actually get updated if the functionallity changes.

Yes, the customer is always "right" (but there is nothing "wrong" about convincing a client to change their minds). Fortunately all of the time I am spending on this issue is billable (but still fustrating).

Feb 20, 2008 at 4:46 PM
Edited Feb 20, 2008 at 4:46 PM

davedev wrote:
How does it differ from the IntellisenseComponent2 that ships with Sandcastle?

That's new to the January release and I hadn't seen it. It didn't exist when I wrote mine back in November, only the first one did which doesn't work with standard XML comments. With mine you don't have to supply all of the XPath queries to extract the various comment parts. It also lets you name the Namespaces comments file or exclude it if you don't want it.

Feb 20, 2008 at 6:51 PM
Hi Eric,

I think IntellisenseComponent was meant to extract comments from DDUE reference documentation (not the auto-generated stuff) and IntellisenseComponent2 made it more flexible so you could pull out the IntelliSense from comments in any XML file. It also seems to have some type of include feature.

Although it sounds like your component requires much less manual effort :)

- Dave