SLaks.Blog

Making the world a better place, one line of code at a time

Exploring Roslyn, part 2: Inside the End-User Preview

Posted on Wednesday, May 21, 2014

Last time, I described the basics of the Roslyn compiler platform, including how the different layers are built and interact with each-other. In this post, I’ll talk about what the End-User Preview does and how it works.

The Roslyn End-User Preview provides the first peek at the new Visual Studio managed editing & debugging experience, powered by Roslyn. The preview completely replaces all of the native language services (the old DLLs will not be loaded at all) with the new Roslyn-powered versions. These new DLLs are written entirely in C# and VB (except for a small C++ layer, used to hack around COM interop limitations when talking to other parts of VS).

As you can imagine, replacing the native language services is a gargantuan task, especially since the team is maintaining its usual commitment of not breaking muscle memory. All of the editing behaviors you’re used to, including snippets, IntelliSense preselection & commit patterns, and more, work as they did before, so your accustomed patterns of keyboard shortcuts will continue to work. To make sure this is done perfectly, the Roslyn team wants your feedback. Take out some time, download the preview, and enjoy the enhanced editor experience. If you notice anything that doesn’t behave the way it used to, take out a but of time and file a bug.

What’s in the preview?

The preview has two components: the new Roslyn compilers, which replace the native compilers when building your projects, and the language services, which power the editor & debugger within Visual Studio. Although these components sounds unrelated, they will not work in isolation; the debugger (in particular) makes very specific assumptions about the IL generated by the compiler, and won’t work properly with the wrong version of the compiler.

Compilers

The compiler preview is not hosted by Visual Studio. Instead, the preview extension will edit the per-user MSBuild targets file (see source) and replace the definition of the native Csc and Vbc tasks with the new Roslyn-based versions (Csc and Vbc).

Note: This means that as soon as the Roslyn Preview package is loaded (when you create or open a C# or VB project), in any Visual Studio hive, the Roslyn compilers will become active for all MSBuild v12 builds. If you want to build anything using the native compilers, you can either use an earlier version of MSBuild (eg, the VS 2012 command prompt), or set the DisableRoslyn environment variable to true. To check whether you’re running the Roslyn compiler, look for VBCSCompiler.exe in Task Manager.
The command-line vbc.exe and csc.exe are not affected. (since this just modifies the MSBuild task definition)

The compiler preview uses an interesting approach to maximize performance. Because it’s implemented as a per-user VS extension, the compiler assemblies cannot be NGen’d (since that requires that the assemblies be in the GAC, which needs admin privileges and is machine-wide). Therefore, every time you start the compiler, the JITter must re-compile all of the compiler’s IL to machine code. Since the compilers are enormously complicated, that would be a noticeable performance hit. To avoid this delay, the actual compiler code runs in a shared compilation server process called VBCSCompiler. When you first compile something (whether directly rcsc and rvbc command-line compilers, or whether through the MSBuild tasks), it will launch this compilation server (thus JITting all of the compilation code only once), then communicate over a named pipe (source) to ask it to compile your project. The server will then sit in the background until you next compile something, which it will be able to do instantly. Therefore, you may notice a delay the first time you compile something after rebooting your machine.

This hack is only necessary because the preview is a per-user install. The next release of Visual Studio will include the Roslyn-powered compilers as part of the machine-wide install of MSBuild v14, which will be properly NGen’d and won’t need to do any of this.

Language services

The second part of the preview is the new language services. This part replaces the native language services packages with new Roslyn-powered versions. Since this lives entirely within Visual Studio, the preview doesn’t need any ugly hacks to register itself. The only difference between the preview package and the built-in Roslyn-based language services that will be released with Dev14 is that the preview package also disables the VS package for the native language services (in the VS registry hive). Unlike the compilers, the language service has no effect outside the hive it was installed in.

The Roslyn-based language services faithfully reproduce the complete development experience from the native language services (except a couple of features that have not yet been implemented), as well as a host of new features that were made possible by the newly well-organized codebase. These new editor features fall into a couple of categories:

Syntax Highlighting

Roslyn extends the editor’s existing syntax highlighting to a number of new areas. Tooltips for types and method signatures now syntax-highlight the declarations, including keywords and separate colors for User Types (classes, structs, etc), if configured in Fonts & Colors options (the Productivity Power Tools extension also has this feature, but Roslyn’s works better). It will even show syntax highlighting for members referenced in <see /> tags in the doc comments!

Tooltips for collapsed methods or regions now show a fully syntax-highlighted preview of the code in the block.

References to members in <see>, <param>, <typeparam>, and <exception> when editing XML doc comments tags are now syntax highlighted, and participate in identifier highlighting.

The language service will also identify unnecessary qualifiers in your code (already-imported namespaces, inferable generic parameters, unnecessary casts, this., etc) and dim them in the editor to show that they can be removed. (there is also a refactoring to automatically remove them)

Roslyn Syntax Highlighting

IntelliSense

Roslyn also features a vastly improved IntelliSense engine. The editor now knows exactly what keywords can appear in every context, giving you accurate IntelliSense for areas like property declaration blocks, class modifier keywords, preprocessor directives, and many other areas that the old C# language services fell short.

The Roslyn editors also add IntelliSense for <see /> (and similar) tags in XML doc comments, allowing you to select any type or member and insert the correct doc comment ID (with generics declared appropriately). This makes it far more convenient to write correctly-structured XML comments, which is particularly useful when compiling them to documentation sites (eg, with Sandcastle).

Refactorings

The crown jewel of the new language services is the all-new refactoring engine. All of the existing refactorings have been reworked using the new semantic APIs to preserve the meaning of your code, even if you introduce conflicting names or other challenges. To make this work, the refactoring engine checks which symbol every identifier resolves to, then makes sure that each one still refers to the same symbol after the rename is complete. If it detects any changes, it will fully-qualify the offending reference to force it to refer to the correct (original) symbol (it will then reduce the reference to become as simple as possible).

The rename refactoring in particular has been completely redone. Instead of showing a modal dialog asking for a new name, the Roslyn-powered rename experience is completely inline. After pressing F2, you can start typing the new name directly in the editor, and all references to the symbol you’re renaming will be updated in real-time, including surrounding changes to resolve conflicts. (unresolvable conflicts will be highlighted in red)

The refactorings (both old and new) are now exposed contextually. Press Ctrl + Dot to see which refactorings are available for the current cursor or selection in a smart tag popup; the language service will even show a syntax-highlighted preview of the generated code for each action.

The existing refactorings include

As well as the existing VB-specific syntactic fixes:

There are also a number of completely new refactorings:

Roslyn Refactorings

Next time: Breaking Changes

Categories: Roslyn, .net, visual-studio Tweet this post

comments powered by Disqus