Static Code Analysis for XNA Applications Part 2: Spelling

In the first post in this series, we introduced FxCop a .NET static code analysis tool. We ran the GUI version of FxCop, and applied it to a simple XNA application. Now that we’ve got the basics, this tutorial will show you how to start up the spell checker for your source code.

We’re going to start with a much more complicated XNA application for this tutorial. I’ve chosen to use Rocket Commander XNA by Benjamin Nitschke. It’s got plenty of code and plays great. Go ahead and download the source code from Benjamin’s site. Once you’ve got it unzipped, go ahead and open up the RocketCommanderXna.sln file and run the FxCop tool, and analyze the code.

Holy Cow! 686 messages! That’s a lot of messages, and the sheer volume of messages brings up a few interesting points. The first point is that if you are going to make heavy use of static code analysis (and I certainly recommend it,) it really pays to start your analysis runs early in the development cycle and fix the messages as you go along. Otherwise you could be staring down 686 messages or more, which can be really tedious to deal with, especially when you are looking at code that you have not written, or have not looked at in a long time. (Small update: there are a different number of messages for Release builds of Rocket Commander than Debug. That is because there is code in #if DEBUG blocks.)

There is an inherent danger in changing code, which is going to be a re-occurring theme in all of my code quality posts. Each time you change something you run a risk of introducing a build break, or worse a regression bug. So attempting to make 686 code changes to Benjamin’s code might not be the right thing to do (unless you are, in fact, Benjamin, or you’ve got plenty of time to test for regressions.)

The second interesting point is related to something I mentioned in the last post, but wanted to reinforce here: FxCop is not perfect. Scrolling through the message list, you can see that many of the messages are obviously not bugs, and some messages might not even be worth fixing (remember: this is not our code base, so we’re facing that regression risk I mentioned.) For example:

"Correct the spelling of the unrecognized token ‘Shader’ in member name ‘BaseGame.glowShader’."

Now, obviously Shader is a word that might appear quite frequently in an XNA application’s source code. There are 140 spelling related messages and 43 casing related messages in the log. At this point, we probably need to look into CustomDictionary.xml.

As a quick aside, I mentioned in the previous FxCop post, FxCop utilizes the spell checking engine from Microsoft Office to check spelling. It should be noted that the latest version of FxCop (1.35 at the time of this post,) is not compatible with Office 2007. I had to roll back to Office 2003 in order to get the spelling checker activated. That little limitation held back this post a few days.

CustomDictionary.xml identifies words and acronyms that are permissible in your code to FxCop. You may also specify words that might appear in the Office dictionary, but should not appear in your code (go watch “Pulp Fiction,” or use your imagination as to what those words might be.) A beginning of an XNA appropriate CustomDictionary.xml is shown below:

<?xml version="1.0" encoding="utf-8" ?><Dictionary>
 <Words>
  <Unrecognized />
  <Recognized>
   <Word>xna</Word>
   <Word>fxcop</Word>
   <Word>shader</Word>
   <Word>shaders</Word>
   <Word>specular</Word>
   <Word>multi</Word>
   <Word>fullscreen</Word>
  </Recognized>
  <Deprecated />
 </Words>
 <Acronyms>
  <CasingExceptions>
   <Acronym>XNA</Acronym>
  </CasingExceptions>
 </Acronyms>
</Dictionary>

You may download this file here.

<Recognized> contains a list of <Word>s that will not be in the dictionary, but are OK in the code. <Unrecognized> would also contain a list of <Word>s that exist in the dictionary, but are not permitted in the code. <Deprecated>, instead of <Word> elements, contains <Term> elements. An example <Term> is:

<Term PreferredAlternate=”EnterpriseServices”>ComPlus</Term>

Notice that <Term> calls out an alternative.

Finally, the <CasingExceptions> contains a list of <Acronym>s that are exempt from the usual .NET framework guideline casing rules.

You may simply drop CustomDictionary.xml into you FxCop install directory, or you can keep it with what’s called an “FxCop Project File.” Just like Visual C# 2005 Express keeps all of the various setting related to your project together, FxCop can do the same. If we are building multiple assemblies, we can add all of our assemblies to the FxCop project file so that they are all analyzed together.  There are many other settings that can be saved on a per-project scope. The feature we are concerned with now is that if we save our CustomDictionary.xml in the same directory as our project file, then FxCop will load it. Then, both files can be saved to source control, or backed up, or whatever.

If you do decide to go with project files, you’ll probably want to update the custom Tool menu item in Visual C# 2005 Express from the last post. Previously we had “$(TargetPath)” in the Arguments text box. Instead we might want to use a combination of $(ProjectDir), $(SolutionDir), $(TargetName), or simply hard-coding a file name such as $(SolutionDir)FxCop\Project.FxCop. You may also want to add both the Debug and Release targets to the project file. Just make sure you’re working with the right configuration!

Once we have set up our CustomDictionary.xml, we can re-run the analysis on Rocket Commander. (Down to 649!) In the results we see there are still many spelling related messages. Messages like this are very common:

"In method SpaceCamera.GetRotatedMovementVector(Vector3):Vector3, correct the spelling of the unrecognized token ‘rel’ in parameter name ‘relVector’ or strip it entirely if it represents any sort of Hungarian notation."

As well as this:

"In method ColorHelper.FromArgb(Byte, Byte, Byte):Color, consider providing a more meaningful name than the one-letter parameter name ‘g’."

In the first case, I believe the ‘rel’ is just a short-hand ‘relative’ and clearly in the second case, the ‘g’ means ‘green.’ Now, if I were actually working on the code, I might prefer the slightly longer but slightly more readable names for maintainability. The Visual C# 2005 Express “Refactor” feature is great for this sort of work, incidentally. It may not amortize all of the risk of changing method parameter names, but it certainly eliminates most of the risk.

Well, originally I was going to try to handle a bunch of more content in this post. I’m thinking this one is long enough. In the next couple posts in the FxCop saga, we’ll look at automatic build integration, the various other ways of handling messages without touching your code (much,) and maybe I’ll even see if we can cough up a rule to flag the foreach construct that XNA developers seem to want to avoid like the plague.

OE

Useful links:

  • FxCop help page for the IdentifiersShouldBeSpelledCorrectly rule.
  • FxCop help page for the UsePreferredTerms rule.
  • A blog entry with a little of the frustration you may face when trying to fix spelling in your code for FxCop.
Advertisement

One Trackback/Pingback

  1. [...] Code Analysis for XNA Applications Part 3: Suppressing Messages In the previous post, we examined how spelling related FxCop messages could be handled by using a custom dictionary [...]

Post a Comment

Required fields are marked *
*
*

Follow

Get every new post delivered to your Inbox.