Welcome to roslyn-analyzers documentation

The roslyn-analyzers repository started as a learning experience about the Roslyn API. Hopefully it will grow to hold many more analyzers.

This documentation contains generic information regarding the Roslyn Platform that will help understand how the repository was created as well as convey the the information that is required to understand the code in the repository. In addition it contains a description of all the analyzers and code fixes present in the repository.

How to create a Roslyn Analyzer project for C#

This is a step by step guide on how to create a C# Roslyn Analyzer project for Visual Studio.

Requirements

Note

This guide was tested using:

  • Version 1.4 of the .NET Standard framework for the .NET Standard project that has the analyzers.
  • Version 4.6.2 of the .NET Framework for the unit test project.
  • Version 2.2.0 of the nuget Microsoft.CodeAnalysis.CSharp.Workspaces.
  • Visual Studio 2017 Version 15.2

See here for more information on what nuget versions you should use.

The quick and easy way

Once you have installed the .NET Compiler Platform SDK you can get started quickly by using the built in templates to create a new analyzer project. Go to File->New->Project then select Extensibility under Templates->Visual C#.

Make sure the .NET framework version selected is 4.6.2 and you will be able to see a template called Analyzer with Code Fix (Nuget + VSIX).

_images/vs_analyzers_template.PNG

Once you have created your new project the template will create three projects for you:

  • A portable class library: where the code for your analyzer is. This project is also configured to produce a nuget package upon building.
  • A test project: this test project is quite handy since it serves as a starting to point to how you can test your analyzers.
  • A VSIX project: this has two purposes. It produces a VSIX file which can be used to install your analyzers as a Visual Studio Extension and it will also enable you to debug your analyzer.
_images/vs_analyzers_template_2.PNG

And you’re set to go. I advise you to explore the default analyzer (DiagnosticAnalyzer.cs) and code fix provider (CodeFixProvider.cs) that are created as part of the template in the portable class library project as well as the tests (UnitTests.cs) that are in the test project.

The #Pro way

Although templates are great to get you started they might not fit your case. Also if you want to understand how everything works then this section will give you a better understanding of all the magic that the default template does for you.

Creating the project for your analyzer code

Let’s start by creating a blank solution. Once the blank solution is created we need to add a new project to it that will serve as the project where the code for your analyzers is. Although the template creates a portable class library project you are free to select another type of project as long as there is support from the .NET Compiler platform SDK for it.

In this case let’s create a .NET Standard Class library project. Go to File->Add->New Project, select .NET Standard under Templates->Visual C# and then select Class Library (.NET Standard).

Now let’s edit the project so that we can install the nugets we require to create our analyzers. Right click the project and select Edit.

_images/edit_cs_proj.png

Edit the cs proj file in order to set the PackageTargetFallback as follows:

<Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
                <TargetFramework>netstandard1.4</TargetFramework>
                <PackageTargetFallback>portable-net45+win8+wp8+wpa81</PackageTargetFallback>
        </PropertyGroup>
</Project>

Save and close the cs proj file and add the following nuget to the .NET Standard project:

Creating the debug project

The debug project as the name suggests will allow you to debug the code of your analyzers. For that we will create a VSIX project. VSIX projects are used to create extensions for Visual Studio and although we are creating a VSIX project the intent is not to then distribute the resulting VSIX file. We could do that and when users installed the VSIX file they would have access to the analyzers you’ve developed but for distributing the analyzers I think a nuget package is better.

The VSIX project is still what we want because once configured and set as the startup project it will launch an experimental version of Visual Studio that is being debugged by the Visual Studio process that launched it (the one that has your analyzer solution). This will allow you to create a new project and test your analyzers with break points to aid your development.

Go to File->New->Project then select Extensibility under Templates->Visual C#. Make sure the .NET framework version selected is 4.6.2 and you will be able to see a template called VSIX Project.

Once you’ve created the VSIX project you get three files:

  • stylesheet.css: you can delete this since you don’t need it.
  • index.html: you can delete this since you don’t need it.
  • source.extension.vsixmanifest: this one is where you configure the properties for your extension.

We need to configure the source.extension.vsixmanifest so that it uses the analyzer project we created in the previous step. Double click the source.extension.vsixmanifest and:

  • Change the Product Name on the top to be what you want.
  • Give it a description.
  • On the Assets tab click new and add an entry with a Type of Microsoft.VisualStudio.MefComponent. On Source select A project in current solution and in the Project select the project that has the code for your analyzers. In our case it would be the .NET Standard project created in the previous step. Leave the Embed in this folder empty and click OK.
  • On the Assets tab click new and add an entry with a Type of Microsoft.VisualStudio.Analyzer. On Source select A project in current solution and in the Project select the project that has the code for your analyzers. In our case it would be the .NET Standard project created in the previous step. Leave the Embed in this folder empty and click OK.

By adding an asset of type Microsoft.VisualStudio.Analyzer you have enabled the code for any analyzer you create in the analyzers project to be packaged by the VSIX project. And by adding an asset of type Microsoft.VisualStudio.MefComponent you have enabled the code for any code fix provicer you create in the analyzers project to be packaged by the VSIX project.

As a last step make sure the VSIX project will launch an experimental version of visual studio. This should be set by default but confirm by going to the VSIX project properties and checking that the Debug tab has the following:

  • Under Start action the option to Start external program should be selected and the location should be where you have installed visual studio. Something like C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/Common7/IDE/devenv.exe.
  • Under Start options the Command line arguments should be set to /rootsuffix Exp

Creating the test project

Just create a regular unit test project and add the following nugets:

Now you can reference the .NET Standard project and create your tests. I recommend that you copy the folders Helpers and Verifiers that are created as part of the test project when using the template Analyzer with Code Fix (Nuget + VSIX). See The quick and easy way. These classes contain methods that will greatly help you understand how to test your analyzers and code fixes.

In my own projects I’ve copied and changed the classes in these folder so that I could use them the way I wanted but they will work fine if you use them as they are.

How to configure Roslyn analyzers

You can alter the default behavior of the analyzers available in your solution. Let’s say you’ve installed a nuget with lots of useful analyzers but there are some that you would like to disable or maybe there is a project where you would like to have analyzer X enabled and another project where the same analyzer should be disabled. How do we handle this?

This can be achieved by using rule sets.

Configure a rule set for a project

Note

If you want to configure a rule set for a .NET Core or .NET Standard project skipt to .NET Core and .NET Standard projects.

Once you have installed the analyzer in your project, right click Analyzers under the project’s References and chose Open Active Rule Set.

_images/open_active_rule_set.png

This will open tooling inside Visual Studio that will enable you to change the default action of an analyzer. You can change an analyzer to go from a simple build warning to a build error or disable it by setting the action to None.

_images/config_rule_set.png

Once you’ve configured the rules as you want save the file. When the rule set is saved Visual Studio will create a ruleset file in the project’s directory, add it to the project and change the csproj file to add a <CodeAnalysisRuleSet> property into the <PropertyGroup> section that points to the custom rule set you just created.

.NET Core and .NET Standard projects

Unfortunately Visual Studio 2017 does not have tooling support for configuring ruleset files for .NET Core and .NET Standard projects. However you can still do it manually by creating a custom rule set and telling the csproj to use it. You start by creating the ruleset file. Once you have the ruleset file edit the csproj and add a <CodeAnalysisRuleSet> into the <PropertyGroup> that points to the ruleset file you want. The path can be a full path or a path relative to the project file. Here is an example:

<PropertyGroup>
        <TargetFramework>netstandard1.4</TargetFramework>
        <CodeAnalysisRuleSet>.\NetStandard.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

Once you’ve configured the rule set you might have to restart Visual Studio for the changes to take effect fully.

Note

If you’re not confortable with creating your own from scratch I advise creating a .NET Framework project, adding the analyzer you want to it and then following the steps mentioned previously. Once Visual Studio generates the ruleset file for you edit it to make sure it only contains the rules you care about.

Configure a rule set for a solution

The first thing you need is a custom rule set. To create one follow the indications in the previous steps.

Note

If you chose to create a custom rule set by using the tooling inside Visual Studio it will add that file to the project you’ve selected to create the custom rule set for. Since this rule set is going to be applied to the solution I advise you to copy the file from the projects directory and add it to the same direction as your solution. Do not leave the file in the projects directory after copying it to the solution’s directory.

Make sure the Name property of your custom rule set uniquely identifies the ruleset file as there can be many ruleset files in a solution and as we will see this name is what the Visual Studio tooling uses to let you chose which rule set you want to apply for each project.

Put the ruleset file in a directory of your chosing. For instance in the same directory as your solution file is. Once you have the custom rule set in the directory you want right click your solution in Visual Studio, chose Add->Existing Item and select the custom rule set.

Now that you have created and added the custom rule set to the solution go to the solution’s properties and select the Code Analysis Settings tab under Common Properties. This will show you all the projects that can have rule sets configured using the Visual Studio tooling. Just select the rule set you created from the drop down list.

_images/config_rule_set-solution.png

Keep in mind that the tooling for rule sets in Visual Studio 2017 does not support .NET Core and .NET Standard projects. This doesn’t mean you can not have a solution wide rule set for your projects. It just means you will have to manually add your solution wide rule set to your .NET Core and .NET Standard projects by following the indications here.

How to debug an analyzer

Once you’ve created your VSIX project make sure it is set as the default start up project by right clicking it and chosing the option Set as StartUp Project. Also go to the VSIX project’s properties and confirm that the Debug tab has the following:

  • Under Start action the option to Start external program should be selected and the location should be where you have installed visual studio. Something like C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/Common7/IDE/devenv.exe.
  • Under Start options the Command line arguments should be set to /rootsuffix Exp. See Devenv command-line switches for more info.

Once you’ve done this Start Debugging on Visual Studio which will launch the experimental version of Visual Studio. To confirm that your VSIX project with your analyzers is installed in this experimental version of Visual Studio go to Tools->Extensions and Updates and in the Installed extensions you will find the VSIX project that you launched. The Name and Description set in the source.extension.vsixmanifest file of the VSIX project will show up in the list.

_images/debug_installed_extensions.PNG

Now all you need to do is create a new solution to test your analyzer. Simply create a new project of the type of your chosing and add a code that should trigger the analyzer.

You can put breakpoints on the Visual Studio that has your analyzer code because it is debugging the experimental version of visual studio. If your breakpoints are not working see:

Resetting your experimental version of Visual Studio

If you’re not careful with the ids and versions of your VSIX projects that you deploy onto the experimental version of Visual Studio you might get into a place where you can not debug properly because the VSIX fails to be installed. If you think you’re in that position you should either:

  • Be patient: depending on your computer it might take some seconds for the analyzers and code fixes to show up.
  • Update the version of the VSIX: double click the source.extension.vsixmanifest and change the version number on the top right corner.
  • Launch a different experimental instance of Visual Studio: In the Command line arguments instead of “/rootsuffix Exp” change the word Exp to anything else you would like, for instance “/rootsuffix Exp2” and a new experimental version of Visual Studio will be launched. Each time you chose a new word a new experimental isntance is launched and unless you reset them they remember the VSIX that were deployed to them.
  • Reset your experimental instance: for that you will need to use the CreateExpInstance utility. For Visual Studio 2017 you can find this utility at C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VSSDK/VisualStudioIntegration/Tools/Bin.
  • Manualy reset the experimental instance: for Visual Studio 2017 what the utility does is the same as deleting a couple of folders from %localappdata%/Microsoft/VisualStudio. For instance if the parameter after /rootsuffix is Exp then Visual Studio 2017 creates two directories at that location with the following names: Exp and 15.0_18f5488bExp. In the latter folder the numbers between the underscore and the word Exp may vary. If you close all instances of Visual Studio and delete those two folder you’ve reset the experimental version of Visual Studio with the id Exp. If you’re using another parameter after /rootsuffix like Roslyn then the two folders would be somehting like: Roslyn and 15.0_18f5488bRoslyn.
  • Maybe the VSIX is installed properly: if none of the above worked check your nuget packages version

How to test an analyzer

Once you have created your test project I believe the best way to test your analyzer is to look at the example unit tests that are created as part of the default Visual Studio template for creating a Roslyn Analyzer.

The test project created by the default template has two folders inside with helper classes for testing Analyzers and Code Fix Providers:

  • Helpers
  • Verifiers

I recommend that you copy these and re-use the classes to test your analyzers and code fixes. In the roslyn-analyzers repository I have adapted the code from these folders to better suit my testing.

Testing strategy

Although you can create the contents of the C# source file as a string directly in the test I recommend that you create a test solution and add there all the files that are required for your tests. Add the cases that should trigger your analyzers, the cases that should not trigger the analyzers, how the code is before the code fix provider and how it should be after.

This solution should be a separate solution from the solution where you have your analyzer because it is likely that you will have code in there that will not compile. This solution is not meant to build sucessfully. It is only meant to have the source files for your test cases.

I believe this is a better strategy than using string because it will make it easier to mantain your tests, Visual Studio helps you right the test code and you can use the test solution when debugging with the experimental version of Visual Studio.

NuGet packages required to develop analyzers

When creating the analyzers and test projects you will have to reference nugets that contain the Roslyn APIs and not only enable the development of the Analyzers and Code Fix Providers as well as integrate them with Visual Studio.

To develop analyzers and code fixes you only need to referece:

All the required packages are dependencies of Microsoft.CodeAnalysis.CSharp.Workspaces.

Microsoft.CodeAnalysis.CSharp.Workspaces package

Although one might think that the latest versions of the packages is what we should use in this case it is not that simple. After asking around on the Gitter channel for Roslyn I found out that the version of Microsoft.CodeAnalysis.CSharp.Workspaces is actually related with the version of Visual Studio. Sadly this mapping does not exist anywhere but I was told the pattern works like this:

  • 1.0 -> Visual Studio 2015.0 (Version 14.0)
  • 1.1 -> Visual Studio 2015.1 (Version 14.1)
  • etc
  • 2.0 -> Visual Studio 2017.0 (Version 15.0)
  • 2.1 -> Visual Studio 2017.1 (Version 15.1)
  • 2.2 -> Visual Studio 2017.2 (Version 15.2)
  • etc

The major and minor versions of Microsoft.CodeAnalysis.CSharp.Workspaces are directly related with the major and minor version of Visual Studio. The build part of the version is used for improvements/bug fixes. This is why the default template for creating Roslyn analyzers uses version 1.0.1 of Microsoft.CodeAnalysis.CSharp.Workspaces. It ensures compatibility with Visual Studio 2015.

It is up to you to chose which version you want to support and there might be a analyzers that you probably won’t be able to do whilst at the same time keeping support for Visual Studio 2015. I’m thinking about analyzers for new C# 7.0 language features that came out with Visual Studio 2017. If you’re doing analyzers for those then you probably need to use at least version 2.0 of Microsoft.CodeAnalysis.CSharp.Workspaces.

Create a NuGet package for your analyzer

If you’ve used the default template to create your analyzer project then you don’t need to worry because it is already configured to produce a nuget package upon building. If you have followed The #Pro way then you have to do some work to create a nuget package that will work properly for distributing your analyzer.

See analyzers conventions for official documentation about packaging your analyzers.

All that is explained below was discovered from looking at how the default template generates the nuget package. In short by analyzing the nuspec file and the scripts inside the tools folder.

Using a nuspec file

If you are using a .NET Core or .NET Standard project for your analyzers consider using the support for creating NuGet packages present in the csproj config.

Nuspec file

There’s lot of metadata that you can configure on the nuspec file but to create nuget packages for analyzers you have to at least set the below metadata and files:

<?xml version="1.0" encoding="utf-8"?>
        <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
                <metadata>
                ...
                <frameworkAssemblies>
                        <frameworkAssembly assemblyName="System" targetFramework="" />
                </frameworkAssemblies>
                <developmentDependency>true</developmentDependency>
                </metadata>
        <!-- The convention for analyzers is to put language agnostic dlls in analyzers\portable50 and language specific analyzers in either analyzers\portable50\cs or analyzers\portable50\vb -->
        <files>
        <file src="*.dll" target="analyzers\dotnet\cs" exclude="**\Microsoft.CodeAnalysis.*;**\System.Collections.Immutable.*;**\System.Reflection.Metadata.*;**\System.Composition.*" />
        <file src="tools\*.ps1" target="tools\" />
        </files>
</package>

As explained in the section analyzers path format you can use more complex folder structures to target different languages. The line from the above config that is setting the framework to dotnet and the language to C# is:

<file src="*.dll" target="analyzers\dotnet\cs" exclude="**\Microsoft.CodeAnalysis.*;**\System.Collections.Immutable.*;**\System.Reflection.Metadata.*;**\System.Composition.*" />

The second file line:

<file src="tools\*.ps1" target="tools\" />

Makes sure the nuget package will contain the custom install and uninstall scripts that are required to add/remove the analyzer dll in the correct way when the nuget package is installed/removed.

Nuget Powershell Scripts

You will need to create a folder in the root directory of your analyzer project and add two scripts to it:

  • install.ps1
  • uninstall.ps1

The scripts that I’ve used were a copy of the ones produced by the default template to create an analyzer project. However you can use the ones from the official documentation.

They both do the same which is add all the dll files from your nuget package into the project’s analyzer references:

foreach ($analyzerFilePath in Get-ChildItem $analyzersPath -Filter *.dll)
{
        if($project.Object.AnalyzerReferences)
        {
                $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
        }
}

The uninstall script does the reverse by removing the analyzer dlls from the project’s analyzer references.

Note

There is a small difference between the scripts from the default template and the ones in the official documentation. The scripts from the default template don’t just get all the dlls from the nuget package. It gets all the dlls except the resource ones as you shown by:

foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll)

I have not tested but this line of the powershell script should only impact projects that are localized. Altough the official documentation in not excluding the resource files it is probably the correct thing to do but I have not tested it.

Using support from the csproj

If you are using .NET Core or .NET Standard project for your analyzers then you can make use of the csproj support to create NuGet packages. Here is an example of a csproj file configured to create a NuGet package for a .NET Standard analyzer project:

<Project Sdk="Microsoft.NET.Sdk">

        <PropertyGroup>
                <TargetFramework>netstandard1.4</TargetFramework>
                <PackageTargetFallback>portable-net45+win8+wp8+wpa81</PackageTargetFallback>
                <IncludeBuildOutput>false</IncludeBuildOutput>
                <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
        </PropertyGroup>

        <PropertyGroup>
                <PackageId>Id.Of.Your.Package</PackageId>
                <PackageVersion>1.0.0.0</PackageVersion>
                <Authors>YOUR_NAME</Authors>
                <PackageLicenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</PackageLicenseUrl>
                <PackageProjectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</PackageProjectUrl>
                <PackageIconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</PackageIconUrl>
                <RepositoryUrl>http://REPOSITORY_URL_HERE_OR_DELETE_THIS_LINE</RepositoryUrl>
                <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
                <Description>Description of the package</Description>
                <PackageReleaseNotes>Summary of changes made in this release of the package or delete this line.</PackageReleaseNotes>
                <PackageTags>tag1, tag2, tag3</PackageTags>
                <NoPackageAnalysis>true</NoPackageAnalysis>
        </PropertyGroup>

        <ItemGroup>
                <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.2.0" PrivateAssets="all" />
                <PackageReference Update="NETStandard.Library" PrivateAssets="all" />
        </ItemGroup>

        <ItemGroup>
                <None Update="tools\*.ps1" CopyToOutputDirectory="Always" Pack="true" PackagePath="tools" />
                <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
        </ItemGroup>

</Project>

For more information on the csproj configuration see additions to the csproj format and more specifically NuGet metadata properties.

The parts that are worth calling out on this csproj config are:

  • The GeneratePackageOnBuild property will determine if a NuGet package is created as part of building the project:

    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    
  • The NoPackageAnalysis will ignore warnings from building the NuGet package:

    <NoPackageAnalysis>true</NoPackageAnalysis>
    
  • The PackageReference lines will make sure that the NuGet package created has no dependencies. Otherwise when consuming the NuGet you would be required to install Microsoft.CodeAnalysis.CSharp.Workspaces and NETStandard.Library:

    <ItemGroup>
            <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.2.0" PrivateAssets="all" />
            <PackageReference Update="NETStandard.Library" PrivateAssets="all" />
    </ItemGroup>
    
  • You also need to make sure the NuGet package will contain the custom install and uninstall scripts that are required to add/remove the analyzer dll in the correct way when the nuget package is installed/removed. You will need to create a tools folder with the required scripts for this to work. The line responsible for this is:

    <None Update="tools\*.ps1" CopyToOutputDirectory="Always" Pack="true" PackagePath="tools" />
    
  • By default a NuGet package will contain the assembly inside a lib folder. However NuGet for analyzers follow a different convention as explained in the section analyzers path format. In summary for a C# analyzer the assembly packaged in the NuGet should be in the folder analyzers/dotnet/cs. The line responsible for this is:

    <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
    

Note

I have not tested packaging a localized analyzer so there might be an extra step necessary to make the localization work with the NuGet package. See this note about the install scripts.

Tips and more resources

Notes on the repository

There are two solutions in the roslyn-analyzers repository:

RoslynAnalyzers.sln

The main solution with the analyzers, unit tests and debug project:

The analyzers and respective code fix providers are grouped under the same folder. Not all analyzers have a code fix provider.

All the tests use either the CSharpDiagnosticAnalyzerTest or the CSharpCodeFixProviderTest as the base class depending if it’s a test for an analyzer or for a code fix provider.

The classes inside Tests/Analyzers.Tests/_TestEnvironment/Roslyn are a refactored version of the classes provided by the default template for unit testing analyzers and code fix providers.

To debug the analyzers set the project DebugAnalyzers.Vsix as the startup project and follow the instructions here.

Note

Because I used the Tuple syntax from C# 7.0 on the analyzers project I had to do the following for the unit test project to work:

  • Update the NuGet package System.ValueTuple to 4.3.1 on the unit test project.
  • Install the Nuget package System.Composition 1.0.31 on the unit test project.

RoslynAnalyzersTestData.sln

Contains test cases to be used in the unit test project.

It is also used when debugging the analyzers because once you run the DebugAnalyzers.Vsix you can chose to open this solution with the experimental version of Visual Studio and then open the classes that should or should not trigger the analyzer. While doing this you can set breakpoints and debug the behavior of the analyzer/code fix provider.

Documentation

The documentation for the repository is at the Docs folder.

Read this to understand how the documentation was created and how you can build it.

Analyzers in the repository

Here is the list of the analyzers present in the RoslynAnalyzers.sln.

Note

The analyzers created in the roslyn-analyzers repository were tested on Visual Studio 2017 15.2 on different project types:

  • .NET Framework 4.6.2
  • .NET Core 1.1
  • .NET Standard 1.4
Name Identifier Title Default action
AsyncMethodNamesShouldBeSuffixedWithAsync ASYNC0001 Asynchronous method names should end with Async Warning
NonAsyncMethodNamesShouldNotBeSuffixedWithAsync ASYNC0002 Non asynchronous method names should end with Async Warning
AvoidAsyncVoidMethods ASYNC0003 Avoid void returning asynchronous method Warning
UseConfigureAwaitFalse ASYNC0004 Use ConfigureAwait(false) on await expression Warning
SetClassAsSealed CLASS0001 Seal class Warning
DefaultLabelShouldBeTheLast ENUM0001 Default switch label Warning
MergeSwitchSectionsWithEquivalentContent ENUM0002 Merge switch sections Warning
SwitchOnEnumMustHandleAllCases ENUM0003 Populate switch Warning
DoNotReturnNull RETURN0001 Do not return null Warning