Exploring Roslyn .NET Compiler Platform SDK
Making developers lives easier by utilizing an open compiler platform
5 min read
In this series of articles, I will explore how Roslyn enhances the development process and allows developers to write code analysis, transformation, and manipulation tools.
(This series is a work in progress. I will update the article with relevant links as I progress through the series)
Episode 1: Exploring Roslyn .NET Compiler Platform SDK (this article)
Episode 2: Getting Started With Roslyn Analyzers
Episode 3: Fixing Mistakes With Roslyn Code Fixes
Episode 4: (soon)
What is Roslyn anyway? Okay, let me just...
.NET Compiler Platform, also known by its codename Roslyn, is a set of open-source compilers and code analysis APIs for C# and Visual Basic languages from Microsoft.
Clear, concise. That makes sense, right? But wait, there's more. To better understand Roslyn, we need to go back to its inception (well, we don't, but why not). Here is a brief replay of the events that lead up to all the fun stuff I'm about to describe in this series.
A (very) brief history of Roslyn
On December 2010, Eric Lippert posted an article, Hiring for Roslyn announcing a major re-architecture of the C# compiler (and VB compiler too).
At a 2014 Build conference, Microsoft made the Roslyn project open-source under the stewardship of the newly founded .NET Foundation. Roslyn gets shipped with VisualStudio 2015.
In 2015, C# 6 gets released with several prominent language features, which somewhat hides the fact, that the C# compiler (and VB compiler too) has been completely rewritten in C# (and VB too), making this year a significant milestone for the language.
Compiler as a service
The .NET compiler SDK consists of several layers of APIs, allowing you to effectively integrate into the compilation process, starting at the parsing phase and ending in the emit phase.
The Compiler API surface allows you to access the information exposed by the compiler at each stage of the compilation process.
As a part of the compilation process, the compiler may produce diagnostics of varying severity that may be purely informational or expose a compilation error. The Diagnostic API allows you to integrate into the pipeline naturally. It enables you to produce a set of custom diagnostic messages or even provide the ability to execute code fixes.
Scripting API allows you to execute various code snippets effectively, enabling you to use C# as a scripting language. The C# interactive (Read-Evaluate-Print-Loop) is one tool that utilizes this API.
Of course, modern C# tooling allows you to perform various types of code analysis and refactoring jobs. These are all possible because the Workspaces API provides a virtual, well, workspace making it possible to format code across projects, find type references and even generate source code.
Okay, now I have a bunch of APIs to which I somehow have access. Any idea what to do with them?
Analyze code and report diagnostics
Roslyn allows you to inject components that interact with the compilation process and can ultimately emit diagnostics. These diagnostics can have varying severities and can be used to inform the developer of non-significant compilation events (missing comment on a public member) or can halt the compilation process entirely (missing semicolon at the end of a statement).
This allows you to tailor the entire compilation process to your project needs and standards. While writing custom code analysis tools may be a good exercise, there is already a vast ecosystem of Roslyn analyzers that might fit your needs. These can be installed as IDE extensions or injected into your project as standard NuGet package dependencies.
Provide code fixes
As it turns out, nagging about things without having the ability to fix them is pretty useless(a life lesson right here). For that reason, Roslyn allows you to define a code fix corresponding to a diagnostic.
Code fixes can be applied manually through editor actions or automatically be applied using a tool such as dotnet format (so many tools).
Rewrite existing code
There are various reasons why you would want to rewrite your code. Perhaps a method has become too complex. Possibly you can improve the code readability by hiding away some implementation details (e.g. writing declarative code). Whichever reason you may have to refactor your solutions - manually doing so can be tedious work.
Roslyn allows you to plug in a refactoring solution that can analyze your syntax to provide intelligent means of automatically refactoring code.
Generate source code
Have you heard of the saying the best code is no code at all? It turns out source code is evil. It has bugs. It rots over time. It requires maintenance. It needs engineers to write it.
Wait, what am I saying? I'm an engineer. I love writing code, though not all code. There is code I am always hesitant to start writing. Not because it's hard but because it's solving the same problem I have solved numerous times before.
Roslyn allows you to automate this too. You can
use create a source generator that can automatically analyze relevant parts of your solution to spit out code without you typing a single syntax token (well, apart from writing the actual source generator).
Before we proceed
Just a fair warning. The tools described in this article integrate perfectly with Microsoft VisualStudio IDE and will work on any updated version of VisualStudio 2022 (and above). That being said, the Roslyn Compiler Platform is a part of the mentioned IDE, meaning that the utilities described in this series of articles will (with minor exceptions) work in any IDE that supports modern .NET and will even work without an IDE(dotnet CLI).
All examples in these articles were developed using .NET 7, VisualStudio 2022 Community Edition, and JetBrains Rider.