StyleCop is a tool that reports problems with the source code in C#. Up through Visual Studio 2013, it is provided as an extension to Visual Studio. For Visual Studio 2013 and earlier, StyleCop could be downloaded and installed from http://stylecop.codeplex.com/. The source code is available there as well.
For Visual Studio 2015, the way that extensions are installed changed. Because extensions from 2013 don't work the same way as 2015, the 2013 version of StyleCop won't work in Visual Studio 2015. A person branched the StyleCop 2013 sources and produced a 2015 version. The sources are available at https://github.com/Visual-Stylecop/Visual-StyleCop, however the package for it can be downloaded from the Visual Studio 2015 Extensions and Updates menu item. Search for "Visual StyleCop" in the online extensions and install the version there. This will work essentially the same as Visual Studio 2013 using the same parser for C# and interface into Visual Studio. Currently there are some issues with parsing the new syntax available with C# version 6, but they are getting resolved.
However Visual Studio 2015 has added a new feature: Custom Analyzers. These use the features of the Roslyn compiler to parse the source code. They also integrate into Visual Studio to provide an interface for fixing the reported problems. They can report problems at the time the code is written, not just after a compile. Custom Analyzers are clearly the way forward for tools like StyleCop.
A group of people have re-implemented StyleCop as a Visual Studio 2015 Analyzer. The source code is available at https://github.com/DotNetAnalyzers/StyleCopAnalyzers. The package can be installed from NuGet console by typing "install-package stylecop.analyzers -pre". Because, unlike previous versions of StyleCop, these analyzers don't have a configuration dialog, they must be configured in JSON code. Read the document at https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md on how to configure the settings.
Greg Reddick is a noted speaker, author, and software engineer. This blog covers all aspects of programming, particularly for Windows, and other related topics.
Showing posts with label StyleCop. Show all posts
Showing posts with label StyleCop. Show all posts
2015-10-09
2014-11-25
Resharper Code Cleanup Custom Type Member Layout that Works With StyleCop
I am a religious user of StyleCop to enforce coding standards in my C# code. It uses a coding standard that is fairly inflexible. You can turn rules on and off, but customizing the rules requires writing your own rule library, which is difficult. So you either buy into the way StyleCop does things or you don't. While I don't necessarily agree with every choice for how StyleCop does things, I feel StyleCop gets most things right, and the ones it gets wrong I can live with.
In some cases, I feel StyleCop doesn't go far enough. I wrote several additional rules that plug into StyleCop that enforces several coding standards that I use. One complains if members of a given type are not in alphabetical order. Another disallows multiple returns from inside a method: A method should have one exit point. I don't publish my rules since they have bugs in some cases.
I also use StyleCop+, which allows many additional rules. I do have to change a bunch of settings here to use it, because the defaults aren't right. Still, it does have a number of features I find useful when configured the right way.
One thing StyleCop enforces is the order of items in your code. It has a particular layout that it is looking for. I find it sometimes a little odd. For example, delegates and events come after the constructor...I would think putting them before the constructor makes more sense. However, knowing where things should be located in the file is much more important than exactly where that location is.
I just got a copy of Resharper. It seems many .NET programmers can't live without it, but I've gone 13 years so far. I think my rigid coding standards makes it less useful than it would be if I were more flexible. However, there are some things that I find useful. One thing it can do is reorder your code using the "Cleanup Code" command, which I have done by hand up until now. This is particularly useful when you acquire code from someone who doesn't use StyleCop. However, the default reordering in Resharper is incompatible with StyleCop.
Resharper has a way of customizing what Cleanup Code does. You can create custom rules using XML. I have produced a set of Custom Rules that is mostly compatible with StyleCop, shown at the end of this article.
There are a few issues with my rules. They do not order explicit interface implementations correctly: they will violate StyleCop rule SA1202. (Try implementing explicitly IConvertible, for example.) The ordering of overloaded operators is a little odd. Still, using Resharper with these rules is better than doing reordering by hand, as I can fix what it doesn't do right in few minutes.
Here are the rules. Let me know in the comments if you have any improvements. Be warned...I hate regions, and it will remove the region lines from your code. Change the RemoveAllRegions value to false if you want keep yours.
In some cases, I feel StyleCop doesn't go far enough. I wrote several additional rules that plug into StyleCop that enforces several coding standards that I use. One complains if members of a given type are not in alphabetical order. Another disallows multiple returns from inside a method: A method should have one exit point. I don't publish my rules since they have bugs in some cases.
I also use StyleCop+, which allows many additional rules. I do have to change a bunch of settings here to use it, because the defaults aren't right. Still, it does have a number of features I find useful when configured the right way.
One thing StyleCop enforces is the order of items in your code. It has a particular layout that it is looking for. I find it sometimes a little odd. For example, delegates and events come after the constructor...I would think putting them before the constructor makes more sense. However, knowing where things should be located in the file is much more important than exactly where that location is.
I just got a copy of Resharper. It seems many .NET programmers can't live without it, but I've gone 13 years so far. I think my rigid coding standards makes it less useful than it would be if I were more flexible. However, there are some things that I find useful. One thing it can do is reorder your code using the "Cleanup Code" command, which I have done by hand up until now. This is particularly useful when you acquire code from someone who doesn't use StyleCop. However, the default reordering in Resharper is incompatible with StyleCop.
Resharper has a way of customizing what Cleanup Code does. You can create custom rules using XML. I have produced a set of Custom Rules that is mostly compatible with StyleCop, shown at the end of this article.
There are a few issues with my rules. They do not order explicit interface implementations correctly: they will violate StyleCop rule SA1202. (Try implementing explicitly IConvertible, for example.) The ordering of overloaded operators is a little odd. Still, using Resharper with these rules is better than doing reordering by hand, as I can fix what it doesn't do right in few minutes.
Here are the rules. Let me know in the comments if you have any improvements. Be warned...I hate regions, and it will remove the region lines from your code. Change the RemoveAllRegions value to false if you want keep yours.
<?xml version="1.0" encoding="utf-8" ?>
<!-- StyleCop compatible custom rules by Greg Reddick, http://blog.xoc.net -->
<Patterns xmlns="urn:shemas-jetbrains-com:member-reordering-patterns">
<!--Do not reorder COM interfaces and structs marked by StructLayout attribute-->
<Pattern RemoveAllRegions="true">
<Match>
<Or Weight="100">
<And>
<Kind Is="interface" />
<Or>
<HasAttribute CLRName="System.Runtime.InteropServices.InterfaceTypeAttribute" />
<HasAttribute CLRName="System.Runtime.InteropServices.ComImport" />
</Or>
</And>
<HasAttribute CLRName="System.Runtime.InteropServices.StructLayoutAttribute" />
</Or>
</Match>
</Pattern>
<Pattern RemoveAllRegions="true">
<Entry>
<Match>
<Or>
<Kind Is="constant" />
<Kind Is="field" />
</Or>
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Static />
<Readonly />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="constructor" />
</Match>
<Sort>
<Static />
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="destructor" />
</Match>
</Entry>
<Entry>
<Match>
<Kind Is="delegate" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="event" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Static />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="enum" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="interface" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="property" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Static />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="indexer" Weight="100" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Or>
<Kind Is="method" />
<Kind Is="operator" />
</Or>
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Static />
<Name IgnoreCase="false" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="struct" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Name IgnoreCase="true" />
</Sort>
</Entry>
<Entry>
<Match>
<Kind Is="class" />
</Match>
<Sort>
<Access Order="public internal protected-internal protected private" />
<Static />
<Name IgnoreCase="true" />
</Sort>
</Entry>
</Pattern>
</Patterns>
Subscribe to:
Posts
(
Atom
)