Diving into Visual Studio 2015 (Day #2): Code Analyzers

Introduction

This is the continuation article of Diving into Visual Studio 2015 series. In first article of the series we learnt about Visual Studio’s capability of code suggestions and code optimizations. You can read more about code suggestion in Day #1. In this article we’ll cover another interesting and very useful feature of Visual Studio 2015 i.e. Live Static Code Analysis. The feature’s name in itself is self-explanatory. Visual Studio provides a power to a developer to know about the optimization techniques as well as compile time errors while coding itself i.e. a developer is not supposed to compile the code again and again to know about compile time errors or code optimizations, he can view all of these on the fly while coding and fix it then and there. Let’s cover the topic in detail with practical examples.

Live Static Code Analysis

Live Static Code Analysis is not a sentence or a phrase, each and every word has a unique meaning that adds value to the overall feature. Live means you can get the code analysis on the fly while you type your code. You get a real time code check facility without even compiling the code explicitly. Static means analyzing the code when it is not in running state. This feature is intended to save a lot of development time while coding. The code is checked through pre-defined analyzers while you type and you don’t have to build/compile the application again and again. Moreover these analyzers apart from just showing errors also provide certain warning or suggestive messages while coding that improves a developer’s coding skills and enable him to follow best coding practices. These in built analyzers work on specific set of rules, and the code when written is validated while typing against these rules.

Analyzers can be availed via Nuget Packages installed in Visual Studio. There are numerous analyzers available in Visual Studio 2015. In earlier versions of Visual Studio there were a very few of them available, but now you can get analyzers for each and every approach that you use in Visual Studio for development. There are analyzers available for Azure, Unit tests, Exception handling, Mocks, ORM etc. You can choose analyzers as per your need.

The best thing that this feature provides is that one can build our own analyzer against the type of code we want.This means we can define our own set of rules for coding, and these rules will be invoked against the live code that you or any other developer is writing. The rules may include warnings, errors, suggestions, automated code fixes etc.Let us see by some examples on how we can leverage this capability.

Code Analyzers

Create a console application that contains simple arithmetic operations as methods. I have created one in Day#1 of this article series and will use the same. The name of the console application used in this article is VS2015ConsoleApplication. it contains an interface named ICalculator and a class named Calculator that inherits from mentioned interface as shown below.

ICalculator:

1:using System;

2:using System.Collections.Generic;

3:using System.Linq;

4:using System.Text;

5:using System.Threading.Tasks;

6:

7:namespace VS2015ConsoleApplication

8: {

9:interface ICalculator

10: {

11:int Add(int a, int b);

12:int Subtract(int a, int b);

13:int Multiply(int a, int b);

14:float Divide(float a, float b);

15: }

16: }

Calculator:

1:using System;

2:using System.Collections.Generic;

3:using System.Linq;

4:using System.Text;

5:using System.Threading.Tasks;

6:

7:namespace VS2015ConsoleApplication

8: {

9:publicclass Calculator : ICalculator

10: {

11:publicint Add(int a, int b)

12: {

13:thrownew NotImplementedException();

14: }

15:

16:publicfloat Divide(float a, float b)

17: {

18:thrownew NotImplementedException();

19: }

20:

21:publicint Multiply(int a, int b)

22: {

23:thrownew NotImplementedException();

24:

25: }

26:

27:publicint Subtract(int a, int b)

28: {

29:thrownew NotImplementedException();

30: }

31: }

32: }

33:

As one can see there is not enough code. We’ll use this code to just check and understand the feature and concept behind Live Static Code Analysis.

Right click on the project file in Visual Studio and click on Manage Nuget Packages… option from the context menu.

When you click on this option a window will be launched in the IDE where you get an option to check for installed packages, updates for existing packages or browse for new Nuget Packages. Use search box to search for a keyword named “Analyzer” as show below .

You’ll see that a number of code analyzers will appear on the window . When you click them, they show the description in the right side window. Here we get a choice to use whatever analyzer we need to use with our existing project. We’ll use one of the analyzers to check its capability. I have chosen “codecracker.CSharp” analyzer for further explanation and detailing. Scroll down to this analyzer and click on codecracker.CSharp and install it by clicking install button as shown in below image.

Once installed, the package manager console in visual studio will show the message for successful installation as shown below.

And in Visual Studio , under References a new reference will be named saying “Analyzers->CodeCracker.Common,CodeCracker.CSharp”. Analyzers is the root reference where multiple analyzers can lie.

In addition to that a new “packages.config” file will be added having following code that contains package’s information.

Since we can see the packages.config and a reference added in the solution that means the analyzer we downloaded from Nuget is successfully installed for the console application project. You can check all set of rules of the chosen analyzer by clicking on the arrow of analyzer under reference in visual Studio. Click on “CodeCracker.CSharp” and get a list of all the messages, info, suggestions, warnings and errors that this set contains.

Each rule has a particular syntax like a unique code associated to it, with a descriptive symbol like warning, error, information, suggestion and a descriptive text. Like for an example if we check the first rule, it signifies that it is a sort of warning/suggestion with unique code CC0001 having a description as “You should use ‘var’ whenever possible”. This means that while coding if any such situation occurs where this rule violates, we’ll be shown a message like that with a warning symbol.

Code Analysis

Let us write some code to check how analyzers work. Following is some code I have written to implement Divide method in Calculator class.

1:publicfloat Divide(float a, float b)

2: {

3:try

4: {

5:float result;

6: result = a / b;

7: Console.WriteLine(String.Format("Results", result));

8:return result;

9:

10: }

11:

12:catch { }

13:

14: }

The above mentioned code block is purposely written in a way that may result in some compile time error. While writing the code, keep the Error List window open. You’ll notice that while writing the code, whenever you violate any of the Code Analyzer rule, it immediately flashes in Error List window. It shows that you are getting the feedback and optimizations options on the fly while coding, and you do not have to depend upon compiling the code. For example, check the following image. I have written the code and till now not compiled the project.

We see that two warnings are shown that means while writing the code we broke two rules of installed code analyzer. The first one says it is warning with code CC0111 with a description that number of arguments for “String.Format” method is incorrect. I purposely wrote the code in this way to explain how code analyzers work. As we can see and compare that the rule shown to us in Error List window matches exactly to that of shown in Code Analyzer’s set of rules list at right side. This proves the code analyzer is working as desired. Here we see that we need not have to compile the application and as soon as we fix the code, the error/warning of code analyzer is gone. I purposely left catch block empty so that the code analyzer may validate the code against its defined rule for catch block and suggest us. It clearly says CC0004 Empty catch Block rule is violated.

Case Study

Let us take another scenario and see how analyzers help in providing constructive suggestions w.r.t. code fix or optimization. The following code implements “Multiply” method, there are few errors, some un-optimized code in this method.

1:publicint Multiply(int a, int b)

2: {

3:try

4: {

5:int times = 7;

6:int result = 0;

7: result = a * b;

8:return result;

9:

10: }

11:

12:catch { }

13:

14:

15: }

While writing this code I got following messages, warnings and errors in Error List window.

Note that the Error List window here is configured for Current Document. You can change that to Current Project or all open documents as per your requirement. It shows 1 error, 4 warnings and 1 message. The error is displayed by compiler but the warnings and message is displayed through analyzer that we have used in this project. The warnings are self- explanatory. if you don’t know how to fix them, the light bulb icon helps you to fix those. For CC0105 i.e. use var instead of specifying a type name, if you click on int times=7; the light bulb icon will be shown with few suggestions as shown below.

We see here that Light bulb icon is smart enough to take care of analyzer’s suggestions and provide constructive workarounds to fix the code. The first suggestion is use ‘var’. You can have a preview before you actually apply it, and it’s your choice whether you want to make this fix in the opened document, project or solution. Another suggestion that Light bulb icon gives is for making the variable as constant. It suggests so because it is smart enough to analyze that the variable is having a fixed value throughout the method. Since the variable is not used anywhere in the method, it suggests to remove that unused variable therefore optimizing the code.

There are other suggestions like Suppress CC0105, CC0030, CS 0219. Light bulb icon provides you an option for what to do with similar kind of warnings and errors in future. In case you do not want a suggestion to be shown for a particular analyzer warning or message, then you can opt to suppress that message which means it will not be shown again.

There are two ways in which you can perform suppression and Code suggestion gives you option to choose any of two with a preview.

1. In Source. You can suppress the warning/message/error for that particular line of code as shown in above image. In this case a #pragma statement will encapsulate the underlying code and you’ll not be shown the message again. The code becomes like shown below.

2. In suppression file. Another option is to put that suppression in a separate file, which means the suppression is at project level and you’ll not be shown the message/warning for this rule throughout the code in this particular project. This option creates a separate class file and adds to your project.

The file is named GlobalSuppressions.cs and contains following format for the suppressed messages.

In this particular example I am not opting to suppress the message, instead I’ll go for fixing as per code analyzer’s recommendations. Let us make a fix for CC0105 first.

1:publicint Multiply(int a, int b)

2: {

3:try

4: {

5: var times = 7;

6: var result = 0;

7: result = a * b;

8:return result;

9:

10: }

11:

12:catch { }

13:

14:

15: }

Therefore Error List window becomes as shown below.

We see here that the first warning has been taken care of and now not shown here. Now fix the CS0219.

Since we are not using the variable I’ll go for removing the unused variable as suggested by Light Bulb Icon.preview the changes and apply it to code. This will remove the times variable from the code. now we are left with following code.

1:publicint Multiply(int a, int b)

2: {

3:try

4: {

5: var result = 0;

6: result = a * b;

7:return result;

8:

9: }

10:

11:catch { }

12:

13:

14: }

And the following Error List which shows one error and one is warning. The warning is regarding empty catch block that we are using i.e. CC0004 marked in analyzer’s rule list.

Again when you click on Light bulb icon that shows while you click on catch block code , you’ll see multiple code suggestion options to fix this code as shown below.

There are various options you can choose for your empty catch block code like 1. Removing the try catch block. You can choose this option if you have nothing to do with exceptions or maybe you accidently applied try catch block. If you go for option 2 i.e. Remove Empty catch Block and put a Documentation…, this option will remove the try-catch block and mark a TODO item there. If you preview the option and apply the fix, you’ll get following code for this method.

1:publicint Multiply(int a, int b)

2: {

3: {

4: var result = 0;

5: result = a * b;

6:return result;

7:

8: }

9://TODO: Consider reading MSDN Documentation about how to use Try...Catch => http://msdn.microsoft.com/en-us/library/0yd65esw.aspx

The method puts a commented TODO item stating to read MSDN documentation to read about how to use try-catch.

We have already seen how to suppress a message and warning, so let us try the third option i.e. Insert Exception class to catch. Note that you don’t have to explicitly write catch block unless you have some custom requirement in the case. Just choose the third option and preview changes.

You can see the option will insert implementation for catch block with Exception class object as a parameter and throw as exception in case catch block gets invoked. Therefore code becomes as follows.

1:publicint Multiply(int a, int b)

2: {

3:try

4: {

5: var result = 0;

6: result = a * b;

7:return result;

8:

9: }

10:

11:catch (Exception ex)

12: {

13:throw;

14: }

But as soon as you make this change, you’ll see that error that was shown earlier has been taken care of because now there is return at every exit point of method but a new warning is introduced as shown below.

This image shows that we are trying to declare a variable in catch block that we are not using. Again you can take help from light bulb icon.

There are two options, either remove the variable or suppress the message. Alternatively you can also apply your coding skills and does something with that variable in the code block itself, like displaying error message, logging etc. I’ll choose first option i.e. remove the unused variable. Immediately after choosing that option the variable gets removed and our code becomes cleaner as shown below with absolutely no error, warnings or messages.

1:publicint Multiply(int a, int b)

2: {

3:try

4: {

5: var result = 0;

6: result = a * b;

7:return result;

8: }

9:catch (Exception)

10: {

11:throw;

12: }

13: }

Conclusion

In this article we covered another great feature of Visual Studio 2015 i.e. Live Static Code Analysis. I explained a case study in detail but you may explore other rules and code scenarios while you play around with this feature. I again want to mention that you can try this feature and explore its capability of helping in code analysis and optimization and that too on the fly while you write without even compiling the code. You can try out with more code analyzers available on Nuget. In the next article I’ll cover new enhanced renaming and refactoring features that Visual Studio 2015 provides.