Custom rules for Microsoft's StyleCop utility. These are similar to the custom rules I did for JSL FxCop but rely on StyleCop's parser based inspection compared to FxCop's IL based inspection.
I'm trying to make some fairly complex rules that can't be done in FxCop since they rely on source code, or more specifically an Abstract Syntax Tree (AST). StyleCop generates and AST by parsing the C# code. I also need flow analysis, which StyleCop doesn't supply so I had to write my own.
- Members Must be in Alphabetical Order: StyleCop already has a rule to group members of specific type together, such as all static private methods. This rule extends on that to also include alphabetically ordering the member. This may seem a little over the top, but classes should be small enough that you might as well order the members alphabetically.
- Dont Compare to Boolean Constants: Code like: if (control.Enabled == true) always bothered me. The following code is always more readable: if (control.Enabled). This rule will catch any comparisons of boolean values to boolean constants.
- Local Variable Assignment Unused: This rule catches where a variable is set to a value and that value is never used. Using flow analysis, I look at every variable assignment and see if any code path uses the variable before it is set to another value or the method ends. This catches a lot of stupid mistakes. It can also show you places where your code is doing something other than you thought.
- Local Variables Should be Set Where They are Declared: This rule catches where you can move the first assignment of a variable back into its declaration. Usually this mean moving the variable declaration to where the variable is first assigned.
- Move Variable Declaration to Usage Level: This rule catches variables that are declared at a "larger" scope than they are needed. This helps move variables into the "smallest" scope they can be used in. Keeping variables in smaller scopes makes it much easier to refactor methods into smaller methods. It also makes the code much more readable. WARNING: This rule produces a lot of false positives.
Some of the above rules require walking all the possible code paths. StyleCop doesn't come with this out of the box so I had to write me own. The FlowGraph class allows you to build a graph of all the code paths of a unit. The CodeUnitGraphHelper class lets you walks all the code paths from a specific ICodeUnit. I use http://www.codeplex.com/quickgraph
to build and walk the paths. For example, a simple if statement will have an IfStatement node with two possible outgoing paths. The first will be to the statements inside the if and the second will be around the if. Flow analysis based on the parsed C# code allows us to do some very cool rules that can't be done in FxCop since when code is compiled into IL, most of the control structures are replaced with "goto" like instructions.
For some of the rules, I needed a good way of building lists of variables and how they are being used. The AstHelper class will take a LiteralExpression, determine if it is a variable and return that information as well as how the variable is being used. The information returned is in the VariableUsageInformation class.
How could you possibly write code without writing unit tests with it? StyleCop didn't seem to be designed to allow you to easily write unit tests against it. After digging around for hours using Reflector, I was able to put together a way of running unit tests against specific chunks of code. The actual work is pretty messy, but the unit tests are very clean.
Compiling and Running
The rule assemblies need to be put into the StyleCop directory under Program Files. This won't work on Vista so you have to run Visual Studio as an Administrator. Also, the StyleCop assemblies are loaded into Visual Studio the first time StyleCop is used. Therefore, you have to get out of Visual Studio and back in before you can compile the rule assembly again. If you are just testing if your rules work against "real" code, you should set up your project to run devenv.exe in debug mode (this is the Visual Studio program) and run StyleCop from there. That way, the Visual Studio that you are compiling the rule assembly in won't lock the StyleCop assemblies.
You will need the QuickGraph.dll from the http://www.codeplex.com/quickgraph
project to compile and run these rules.
- Similar to StyleCop but uses FxCop. The project is much farther along than this one.http://jslmstesthelper.codeplex.com/
- Some useful helper for MSTest. The test project uses this.