C# Corner

Roslyn Update: The State of the .NET Compiler Platform

Now that Visual Studio 2015 is upon us, here's a brief overview of the capabilities of the .NET Compiler Platform.

"Project Roslyn," formally known as the Microsoft .NET Compiler Platform, has been in incubation since 2008. Well, it's ready for inception in Visual Studio 2015.

Roslyn is a compiler API for both C# and Visual Basic. What this means is that you have full access to the internal compilation structure of your code now. This allows for many interesting use cases such as static code analysis, code generation and read-eval-print-loop (REPL) functionality for C# and Visual Basic.

In this article, I'll cover how to use the C# Roslyn API to create a code diagnostic, as well as a quick-fix that can uppercase constant field members.

To get started, install the .NET Compiler Platform SDK Templates for Visual Studio 2015 RC from the Visual Studio Gallery. You can also install the .NET Compiler Platform SDK from the Visual Studio Extensions and Updates window (see Figure 1).

[Click on image for larger view.] Figure 1. .NET Compiler Platform SDK Installation

Next, install the Visual Studio 2015 RC SDK from the download page.

Then, create a new Analyzer with Code Fix project as seen in Figure 2.

[Click on image for larger view.] Figure 2. New Analyzer with Code Fix Project

First, open up the Resources.resx resource file and update the values for each key (Figure 3) to reflect that the fix is for constant field names.

[Click on image for larger view.] Figure 3. Updated Resources.resx Resource File

Then open up the DiagnosticAnalyzer.cs code file. The DiagnosticAnalayzer class is responsible for generating the code fix warning for Visual Studio. Next, update the Initialize method to analyze only field symbols:

public override void Initialize(AnalysisContext context)
{
  context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Field);
}

Next, update the AnalyzeSymbol method to create a diagnostic for only field symbols that contain lowercase letters and have a constant value:

private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
  var fieldSymbol = (IFieldSymbol)context.Symbol;
  if (fieldSymbol.Name.ToCharArray().Any(char.IsLower) && fieldSymbol.ConstantValue != null)
  {
    var diagnostic = Diagnostic.Create(Rule, fieldSymbol.Locations[0], fieldSymbol.Name);
    context.ReportDiagnostic(diagnostic);
  }
}

Now it's time to update the CodeFixProvider class to allow the fix to be previewed and fixed. First, update the RegisterCodeFixesAsync method to find the field declarations that need to be fixed, as shown in Listing 1.

Listing 1: Updating the RegisterCodeFixesAsync Method
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
  var root = await context.Document.GetSyntaxRootAsync(
    context.CancellationToken).ConfigureAwait(false);
  var diagnostic = context.Diagnostics.First();
  var diagnosticSpan = diagnostic.Location.SourceSpan;
  var declaration = root.FindToken(
    diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<FieldDeclarationSyntax>().First();
  context.RegisterCodeFix(
    CodeAction.Create("Make uppercase", c => 
    MakeUppercaseAsync(context.Document, declaration, c)),
    diagnostic);
}

Then update the MakeUppercaseAsync method to fix the given field declaration syntax by making the type name be uppercase. First, get the semantic model:

var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

Then get the field symbol for the field declaration from the semantic model:

IFieldSymbol fieldSybmol = null;
fieldSybmol = 
  semanticModel.GetDeclaredSymbol(
  fieldDecl.Declaration.Variables.First()) as IFieldSymbol;

Then generate the uppercased field symbol name:

string newName = fieldSybmol.Name.ToUpperInvariant();
Next, get the original solution and workspace options:
var originalSolution = document.Project.Solution;
var optionSet = originalSolution.Workspace.Options;
Last, create and return a new solution with the field symbol renamed:
var newSolution = await Renamer.RenameSymbolAsync(
  document.Project.Solution, fieldSybmol, newName, optionSet, 
  cancellationToken).ConfigureAwait(false);
return newSolution;

Now you should be able to run the solution and test out the fix by creating a constant private field as seen in Figure 4.

[Click on image for larger view.] Figure 4. Code Fix in Action

Next you can click on the light bulb and preview the fix (Figure 5).

[Click on image for larger view.] Figure 5. Code Fix Preview in Action

Finally, you can apply the code fix and see it applied by clicking on the Make uppercase option as seen in Figure 6.

[Click on image for larger view.] Figure 6. Make Uppercase Option

I've covered creating a new diagnostic analyzer and code fix. You can analyze one or many symbol or syntax types using Rosyln. After the code fix is created you can deploy it either as a NuGet package or as a .vsix installer.

As you can see, Roslyn opens up Visual Studio to be extended with custom static code analysis and refactoring plug-ins.

About the Author

Eric Vogel is a Senior Software Developer for Red Cedar Solutions Group in Okemos, Michigan. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at [email protected].

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events