'Y'

ErrorProne.NET. Part 1

I have been itching for a long time to make an analyzer which would help me catch different errors, specific in varying degrees to the .NET platform. Many of these errors are caught perfectly well by R#, but we always want to create our own stuff, right? Besides, Roslyn analyzers are seamlessly integrated into the build process, they can be used at night (*) and may contain rules specific to your product.

I have been itching for a long time to make an analyzer which would help me catch different errors, specific in varying degrees to the .NET platform. Many of these errors are caught perfectly well by R#, but we always want to create our own stuff, right? Besides, Roslyn analyzers are seamlessly integrated into the build process, they can be used at night (*) and may contain rules specific to your product.

So, based on the ideas from R#, and from a similar library for Java by Google called Error Prone, I set to work. Below is the first part of the results of my work.

Calling Pure Methods
 

The lack of "observation" of the results of pure method call is one of the most common mistakes that occur during local testing. The problem is that by simply reading the code it is very difficult to say in advance whether the call of someCollection.Union(anotherCollection) is “pure” and returns a new collection, or changes the original one.

Here are some examples of this rule:

ErrorProne1.jpg


This rule takes into account a number of known types of the BCL, which are guaranteed to be immutable or contain only "pure" methods. It also takes into account the PureAttribute attribute, which you can use to mark any method. I also added a couple of heuristics: all types with the prefix Immutable are considered immutable, all methods with the prefix With which return the type of the first argument, as well as all the immutable type extension methods are pure. There are some false positives for this rule, but not so many, and there is enough profit from it.

Unfortunately, it is not yet clear how to use the existing purity annotations of the Code Contracts library, and we need to think about how the degree to which we will make the solution scalable. But even now the rule has found a dozen minor bugs in the code of my project (all of them were in the tests and in the secondary code, but still).

Creating Objects Without Saving Values

A special case of the previous rule is a rule that looks for an object constructor call, without the use of the result, of the type new SomeObject();

Unfortunately, it is not possible to issue warnings to any standing alone new call, because people often do terrible things in the form of some operations with side effects in constructors. But in some cases it may be accurate to say that a constructor has no side effects. This refers to the calls of constructors of default value types, collections, objects or primitive immutable types.

ErrorProne2.jpg


There is also a special case of this rule which generates an error when creating an exception object:

ErrorProne3.jpg


String Formatting

Another popular type of error is a wrong argument when calling string.Format and similar methods. Yes, the frequency of string.Format methods use significantly decreased with the appearance of string interpolation in C# 6.0, but there is a lot of legacy code, and format strings are used frequently in other places.

ErrorProne.NET contains three rules:
  • Unknown arguments in the format string
  • Redundant arguments which are not used in the format string
  • Invalid format string
(Yes, the second problem does not occur during execution and does not lead to the generation of FormatException exception, but, IMHO, this can only hide mistakes, and it may occur in practice even more often than the other options. This is the rule which helped find an obvious bug in Roslyn code. Here’s the ticket, if you are interested).

Unknown arguments:

ErrorProne4.jpg


Redundant arguments:

ErrorProne5.jpg


Invalid format string:

ErrorProne6.jpg


And there is also a separate rule which validates the regular expression pattern:

ErrorProne7.jpg


Note that the rule takes into account the attribute JetBrains.Annotations.StringFormatMethodAttribute, which can be obtained via NuGet, or simply be created in your own code (with the use of some kind of duck typing).

-----------------

(*) Yes, I know about the existence of ReSharper Command Line Tools.

Conclusion

I am well aware that there are quite a lot of tools on the market; it is hard to compete with R#, or analyzers from PVS-Studio, and I did not set such a goal. This task is simply quite interesting and I would like to gather in one place all the valuable analyzers which will be useful here and now in my personal projects and projects of my colleagues.

Yes, only a part of the rules supported by ErrorProne.NET is considered here, so expect a continuation in the next part ;)

References
Sergey Teplyakov
Expert in .Net, Ń++ and Application Architecture

Share the knowledge

Still have questions?
Connect with us
Thank you.
Your request has been received.