If you haven't checked it out, SharpDevelop is an open source IDE for .NET and, to a lesser extent, Mono. Among the open source products out there for .NET, SharpDevelop is quite mature and has numerous features. For many developers, myself included, it is readily becoming a substitute for Visual Studio.
Background (or, several anecdotes)
With that sort of shameless plug aside, let's deal with the topic of this article. Whereas SharpDevelop has several features for interacting with code when one developer is involved, team scenarios are the most common development scenario for professionals. At my place of employment, we have several custom application lifecycle management (ALM) applications and plug-ins for SharpDevelop and Visual Studio that are intended to fill in the gaps for our unique business needs. In the spirit of SharpDevelop, this article introduces one of them for general use in the open source community. More are planned, so stay tuned.
Say that you have recently run FXCOP, the tool from Microsoft for checking your code for all the various rules of security, globalization, mobility, portability and other patterns. FXCOP generates numerous warnings and errors that you need to process in order to improve your code base, but there are several problems here that you cannot solve.
First, although the tool generates the warnings and errors in XML and SharpDevelop reports them in the IDE, you lose all of this information when you rebuild your project. At Carbonfrost, we all had our ways of solving this. Some of us used to solve this by printing out dozens of pages of error messages in order to fix them. A little ancient, but I preferred this method because I actually prefer paper, scratching notes and tick marks to webpages and long meetings. Shortly after that, however, new paper quotas were installed at our company, so that idea no longer works. Others of us wrote scripts and other build automation tools to generate web pages and databases. It was all quite tedious and, worst of all, it disconnected us from the IDE and made us less productive.
Second, even though you have the error messages, the code elements move around. So, line numbers quickly become fruitless as you make modifications to the code. Correlating the FXCOP data directly to the source code is a little more involved than just getting the report.
Third, how do you signal to your co-workers and others that you have completed the work? Most of the value in making a change to a code base is communicating how and why you've made that change. At Carbonfrost, we built an external IDE for this specifically. Thus, my colleagues can use Visual Studio while I can use SharpDevelop and others can use text editors. We communicate via this secondary IDE and some internal Web applications.
It is a mash-up of technologies that any small company should be proud of because they don't want to shell out for the expensive stuff yet. Needless to say, however, it is very disconnected from the IDE experience. It is also very tricky to code the interop behavior. So, in need of improvement, I ventured to write an add-in for SharpDevelop to address this problem somewhat. This article introduces my answer to the problem. I hope the solution is at least somewhat useful.
Metaphors and insights
SharpDevelop has a well-structured DOM for interacting with code that models every class, method, etc. that you interact with. So, we start there. The DOM is useful in that it largely removes the language-specific behaviors and provides a structured model for interacting with source code. This enables refactoring and other things. In our model, we "attach" data to the DOM elements so that if a class is moved to a new source file, the data is attached to it. As you may now imagine, we incorporate data from FXCOP into this attachment model, which allows us to retain the meaningfulness of the FXCOP report.
When we attach data to a code element, we call it an "annotation." Annotations are associated with the code element, project or solution, and the annotations support histories. For example, you can change the various fields of the annotations and add new comments, and the annotation history will be persisted. This is beyond the "TODO" and "FIXME" code comments because they are separate from the code. Annotations are useful because they are semantically attached to the code DOM elements and are part of the metadata of the source and the project. This theoretically means that the data can be shared via other mechanisms like bug trackers and that the data will remain meaningful even if file names change or code elements are renamed.
Using the add-in
The add-in is packaged as a single file. This file is actually a simple ZIP with a manifest *.addin file, the DLL and the resources. The file has the extension *.sdaddin.
Start by unzipping the file included with this article. It contains the source code and the *.sdaddin file. If you have already installed SharpDevelop, you should install the add-in by double-clicking on the *.sdaddin file from your desktop. This is explained excellently in another article about SharpDevelop add-ins.
We store the annotations in a file named
<solution-name>.review. Really, this file-based annotations store is not the best idea if you are working in a team, but it illustrates the idea. Internally, we actually store all annotations in a MySQL database and other tools interact with the data.
For skimmers that don't read the article until they've seen enough pretty pictures (I'm guilty of this!), this section is for you. No article would be complete without gratuitous screenshots, so here they are. I won't spend much time explaining how it works, but here it is in a nutshell. The add-in introduces a new pad called the Annotations Gallery. Here, we display on each of the annotations. There are three buttons for adding an annotation, deleting one or navigating to elements that already contain annotations.
The add-in also adds new menu options. Some are added to the Projects pad:
A similar menu is added to the Classes pad. These items allow you to select a class or class member and "Add an Annotation" to it or "Show Annotations" that already exist for it. There is also a command for taking the FXCOP output and transforming it into annotations.. Use the built-in command "Check with FXCOP" first, though.
The illustration that starts this article shows the screen you will see when you add an annotation. This dialog allows you to choose an arbitrary Resolution and Status level, to enter a comment and to select an arbitrary representative icon.
Caveats and future work
Admittedly, the Annotations Gallery is not obvious to use because you have to add annotations via the Classes or Projects pads. I considered rolling my own implementation of the class browser or creating a secondary pad that displays all the elements that have annotations, but those were big undertakings that would've duplicated a lot of code.
There is also a limit on the number of items classes and projects with annotations that will appear in the drop-down. I make the annotations save periodically in a safe way to prevent them from being lost if the environment crashes. This should somewhat prevent a corrupted or partial annotations file or very big data loss. The backup file is saved to
<solution-name>.review~. In the future, I may look into providing an SQL Server database back-end rather than a file.
Although we support adding annotations to the namespace, we can't do this because the class browser does not expose menus for namespaces. Currently, there is also a hack to get the Annotations Gallery to interact with the Class Browser. The code to get some parts of the gallery to work with it are also hacks, so I don't think that it will version well if the Class Browser is changed. I didn't test this with SharpDevelop "Montferrer," either. On the SharpDevelop+Community website on CodePlex, you will find myriad other opportunities for expanding this.
Out of the sandbox and onto the stage
This whole add-in -- source code, testing, documentation and this article -- was developed in about five days. This was with my regular ongoing responsibilities, so it was rather easy, other than the hacks and workarounds. This was also my first CodeProject article, so it was all a rather interesting experience and surprisingly shorter-term than I had planned for.
This add-in and its future editions will be released in something we're calling SharpDevelop+Community, a series of open source projects that are intended to enhance SharpDevelop. If you are interested, please join us at our website! We are in the process of working up a couple of add-ins to contribute to this project. In subsequent articles, I'll write about them. If not, sufficient -- although probably less entertaining -- documentation will definitely be in the distro.
I had help from some folks on the art, legal, copy editing and website material for this add-in. Your work is very much appreciated!
- Version 1. June 3, 2007. Original contribution
- June 22, 2007. Article edited and moved to the main CodeProject.com article base