UPDATE 2015-06-25: Since NR6Pack was reborn as the separate project "Refactoring Essentials" (see here), this post is no longer applicable. We will provide a new post with up-to-date information soon!
This post is for people interested in contributing to NR6Pack (and NRefactory) project. Let's assume you want to implement a new analyzer for NR6Pack. How would you integrate it? I'll explain the structure of NR6Pack solution and where you should place your files.
NR6Pack solution consists of several projects:
- ICSharpCode.NRefactory6.CSharp and ICSharpCode.NRefactory6.CSharp.Refactoring
These two are main parts of NRefactory library itself. They were added to solution to simplify work. There are no references from NR6Pack to NRefactory on project/assembly level.
Unit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
Main assembly of NR6Pack.
Small project demonstrating how some actions/analyzers work in code editor.
Utility generating HTML output files with all supported actions and analyzers by reading code files in NR6Pack project. This tool is launched as post-build event on every compilation.
Project with manifest needed to generate a VSIX package of NR6Pack to be installed through Visual Studio Extension Gallery.
First of all it's important to know that NR6Pack doesn't bring it's
own analyzers. Instead, it links analyzer class files contained in
NRefactory 6 project:
Original class files:
That also means that if you integrate a new analyzer to NR6Pack, you actually add it to NRefactory!
A Simple Analyzer
I'll use the example of a very simple (and not very useful) analyzer, that suggests to prefix every class name with a "C" (like in "CString"). Let's call the analyzer "ClassNameWithoutPrefixIssue".
Step 1: Write a Test
Before starting implementation carefully think about what your analyzer should do and what it shouldn't. The best way to describe that is a unit test:
We use NUnit as our test framework. NRefactory offers an API for unit testing of analyzers and refactorings. Therefore every analyzer test class must be derived from InspectionActionTestBase (tests of plain refactorings use ContextActionTestBase instead). You can define the input code and the expected output code after applying the fix. Dollar signs ($) enclose the code part that your analyzer should recognize as a fixable issue. This is equal to the part that is often underlined in editor as warning or error.
Test classes should be added to ICSharpCode.NRefactory6.Tests project. For analyzer tests please use sub-directory CSharp/CodeIssues:
By the way: By "CodeIssues" NRefactory means diagnostic analyzers. "CodeActions" are NRefactory's synonym for code refactorings. These different names come from pre-Roslyn era and were used by SharpDevelop and MonoDevelop.
Step 2: Implement the Analyzer
Now it's time to create our ClassNameWithoutPrefixIssue:
I'm not going to dive into details of analyzer implementation here. But just a hint: If you already had a look at examples of analyzer creation with Roslyn, you will very likely have seen differing base classes. The reason is that NRefactory 6 has a wrapper layer around some Roslyn base classes. It originates from former NRefactory versions, that were based on their own C# parser instead of Roslyn.
The new class should be added to ICSharpCode.NRefactory6.CSharp.Refactoring project first. You can choose the sub-directory CodeIssues/Custom:
Now your analyzer is part of NRefactory library and can be tested using previously created unit tests.
Step 3: Link Analyzer to NR6Pack
As already said, NR6Pack just links code files from NRefactory. Therefore your final step will be to add a link to ClassNameWithoutPrefixIssue.cs in NR6Pack project. Just take the class file in Solution Explorer and drag it into CodeIssues/Custom directory of NR6Pack project while holding ALT key pressed:
This creates a link to the file instead of copying it.
Now you can experience your analyzer in action: Make sure that NR6Pack.Vsix is your start-up project. When pressing F5 (or the "Start" toolbar button) in Visual Studio a second Visual Studio instance is started, where NR6Pack with the new analyzer is automatically installed. You can open a project and test if it detects your code issue and allows to apply the implemented fix: