Custom StyleCop Rules
Microsoft’s StyleCop is a code style and consistency analysis tool for C#. The tool integrates into the Visual Studio IDE, or can be run on the command line. StyleCop ships with a default set of rules enforcing common style guidelines.
This article describes how to write custom StyleCop rules.
How to write a custom StyleCop rule
Lets say you want to check your code for methods longer than 50 lines.
- Create a Class Library project in Visual Studio
- Add a reference to Microsoft.StyleCop and Microsoft.StyleCop.CSharp
- Create your analyzer class that inherits from SourceAnalyzer
- Add an XML file with the same name as the analyzer class. Set the properties of the Xml file to be an Embedded Resource and not copy to the output directory.
- Override the AnalyzeDocument method
- You are ready to write your own analysis code
Here’s an example of the analyzer class:
namespace CustomStyleCopRule
{
using System;
using Microsoft.StyleCop;
using Microsoft.StyleCop.CSharp;
namespace CustomStyleCopRule
{
using System;
using Microsoft.StyleCop;
using Microsoft.StyleCop.CSharp;
[SourceAnalyzer(typeof(CsParser))]
public class CustomSourceAnalyzer : SourceAnalyzer
{
public override void AnalyzeDocument(CodeDocument document)
{
var csharpDocument = document as CsDocument;
if (csharpDocument != null)
{
csharpDocument.WalkDocument(
new CodeWalkerElementVisitor<CustomSourceAnalyzer>(this.VisitElement),
new CodeWalkerStatementVisitor<CustomSourceAnalyzer>(this.VisitStatement),
new CodeWalkerExpressionVisitor<CustomSourceAnalyzer>(this.VisitExpression),
this);
}
}
private bool VisitElement(CsElement element, CsElement parentElement, CustomSourceAnalyzer context)
{
// Add your code here.
return true;
}
private bool VisitStatement(Statement statement, Expression parentExpression, Statement parentStatement, CsElement parentElement, CustomSourceAnalyzer context)
{
// Add your code here.
return true;
}
private bool VisitExpression(Expression expression, Expression parentExpression, Statement parentStatement, CsElement parentElement, CustomSourceAnalyzer context)
{
// Add your code here.
return true;
}
}
}
As you can see in the example class above, StyleCop has some important concepts to walk through a Document. The Document represents the code file itself, Elements are children of a Document. In an upcoming article I will explain Statement and Expression. For our example to inspect a method, we can start with the Element. To give you some concrete examples the Elements can be Class, Constructor, Delegate, Destructor, Event, Field, Method, Property and some more.
And here’s an example of the corresponding Xml file:
<?xml version="1.0" encoding="utf-8" ?>
<SourceAnalyzer Name="CustomRules">
<Rules>
<RuleGroup Name="Custom Rules">
<Rule Name="TooLongMethod" CheckId="CR0001">
<Context>The method '{0}' has about {1} lines (allowed are {2} lines) and is too long.</Context>
</Rule>
</RuleGroup>
</Rules>
</SourceAnalyzer>
Every rule must have a unique Name and a CheckId consisting of two characters (StyleCop uses ‘SA’ here) and four digits. The Context tag can be used for the message in the Visual Studio Error List window. Additional parameters can be added to the AddViolation call, which will be formatted into your message. The RuleGroup can be used to enable or disable a whole group of rules.
With all the given information it’s relatively easy to add some code for the check of all the methods in a document:
private bool VisitElement(CsElement element, CsElement parentElement, CustomSourceAnalyzer context)
{
if (element.ElementType == ElementType.Method)
{
int firstLineNumber = element.LineNumber;
int lastLineNumer = firstLineNumber;
foreach (var statement in element.ChildStatements)
{
lastLineNumer = statement.LineNumber;
}
int numberOfLinesInMethod = lastLineNumer - firstLineNumber + 1;
if (numberOfLinesInMethod > 50)
{
context.AddViolation(element, "TooLongMethod", element.Declaration.Name,
numberOfLinesInMethod, 50);
}
}
return true;
}
The important thing in the code above is the AddViolation call, which was already mentioned with the Xml document above. The visitor delegates return true to continue the analysis, false to stop the analysis for the current document.
Install the custom rules
Your code should already compile, we just need to install the assembly. That’s relatively easy. Just copy the Assembly to the install folder of StyleCop or any subfolder. When you start Visual Studio, the custom rules will automatically be loaded by StyleCop.
Outlook
As mentioned I will explain more details of StyleCop’s code model with Elements, Statements and Expressions as well as how to write unit tests for your custom rules.
Until then you should have your first cutom rules up and running.

You defined the SourceAnalyzer attribute both on the namespace and the class. Is this necessary? Or would either be enough?
I’m looking forward to the complete clean code rule set
Urs
I’m sorry it’s not the real code; it’s the beginner’s sample. The SourceAnalyzer attribute only applies to the class. I’ve updated the post.
Cheers
Thomas
Hi,
I know that it’s just a sample, but you can check for a method length by quite easier way afaik:
int firstLineNumber = element.Tokens.First.Value.LineNumber;
int lastLineNumber = element.Tokens.Last.Value.LineNumber;
int numberOfLinesInMethod = lastLineNumber – firstLineNumber + 1;
// do whatever you want to
Hi georgem
You are completely right. I don’t count the first line, so I just left away “+ 1″.
Thanx
Thomas
Any link provided to this project, as I could not add this dll to Settings.StyleCop
Thanks,
Jackson C.
@Jackson
Code example see http://code.google.com/p/stylecopcustomrulecleancode/
Good luck
Thomas
Is there away removing a violation or extending a rule that has already been defined.
This is one of the many I am looking at regarding comments:
SA1515: SingleLineCommentMustBePrecededByBlankLine
We are merging with Japaneese code and I want programatically remove a violation.
We have already implemeneted some our own custom rules. I can break on the violation and but can’t figure out how to remove it.
The defined rules can be enabled/disabled at project level (see this article: http://blogs.msdn.com/b/sourceanalysis/archive/2008/05/25/enabling-or-disabling-source-analysis-rules.aspx). Can you explain what your scenario is to programmatically remove a violation?
As far as I know, existing rules cannot be extended. You have to create your own rule which can be derived from the (now) available source code. See announcement here: http://blogs.msdn.com/b/sourceanalysis/archive/2010/04/24/stylecop-is-going-open-source.aspx and http://stylecop.codeplex.com/
Essentially I want to write some some code to parse the source code of a violation. If we think this does not violate it then we want to remove the violation. We don’t want to remove a rule at a Project level as the rule/s still apply.
Essentially its to get round some problems we have merging some code from Japan. Bascically we want to ignore any code they put in. The problem is its a shared code base. i.e. They could start // [Japan] and we could ignore it
Looking at I think the answer is no once a violation has been generated it can not be removed. Removing them is not strictly what should happen.
The other way would be to pre-check a violation before it is added but I can’t see away of doing this.
I have started a discussion on this at:
http://stylecop.codeplex.com/discussions/252749