Getting Started on the Roslyn Journey
It’s not as though it’s new; Roslyn CTP was announced in the fall of 2011, and people have been able to play with it since then. Roslyn is a quietly ground-breaking concept — a set of compilers that exposes compiling, code modeling, refactoring, and analysis APIs. Oh, and it was recently announced that the tool would be open source meaning that all of you Monday morning quarterback language authors out there can take a crack at implementing multiple inheritance or whatever other language horrors you have in mind.
I have to say that I, personally, have little interest in modifying any of the language compilers (unless I went to work on a language team, which would actually be a blast, I think), but I’m very interested in the project itself. This strikes me as such an incredible, ground-breaking concept and I think a lot of people are just kind of looking at this as a curiosity for real language nerds and Microsoft fanboys. The essential value in this offering, to me, is the standardizing of code as data. I’ve written about this once before, and I think that gets lost in the shuffle when there’s talk about emitting IL at runtime and infinite loops of code generation and whatnot. Forget the idea of dispatching a service call to turn blobs of text into executables at runtime and let’s agree later to talk instead about the transformative notion of regarding source code as entity collections rather than instruction sheets, scripts, or recipes.
But first, let’s get going with Roslyn. I’m going to assume you’ve never heard of this before and I’m going to take you from that state of affairs to doing something interesting with it in this post. In subsequent/later posts, we’ll dive back into what I’m driving at philosophically in the intro to this post about code as data.
Getting Started
(Note — I have VS2013 on all my machines and that is what I’ve used. I don’t know whether any/all of this would work in Studio 2012 or earlier, so buyer beware)
First things first. In order to use the latest Roslyn bits, you actually need a fairly recent version of Nuget. This caught me off guard, so hopefully I’ll save you some research and digging. Go to “Tools” menu and choose “Extensions and Updates.” Click on the “Updates” section at the left, and then click on “Visual Studio Gallery.”
If you’re like me, your version was 2.7.something and it needs to be 2.8.1something or higher. This update will get you where you need to be. Once you’ve done that, you can simply install the API libraries via Nuget command line.
With that done, you’re ready to download the necessary installation files from Microsoft. Go to http://aka.ms/roslyn to get started. If you’re not signed in, you’ll be prompted to sign in with your Microsoft ID (you’ll need to create one if you don’t have one) and then fill out a survey. If you get lost along the way, your ultimate destination is to wind up here.
At this point, if you follow the beaten path and click the “Download” button, you’ll get something called download.dlm that, if your environment is like mine, is completely useless. So don’t do that. Click the circled “download” link indicated below to get the actual Roslyn SDK.
Once that downloads, unpack the zip file and run “Roslyn End User Preview” to install Roslyn language features. Now you can access the APIs and try out interesting new language features, like this one:
I've been waiting for this language feature for a long time — inline declaration expressions. #Roslyn FTW. pic.twitter.com/ADFqDrx37D
— Erik Dietrich (@daedtech) April 20, 2014
That’s all well and good for dog-fooding IDE changes and previewing new language features, but if you want access to the coolness from an API perspective, it’s time to fire up Nuget. Open up a project, and then the Nuget command line and type “Install-Package Microsoft.CodeAnalysis -Pre”
Once that finishes up, make your main entry point consist of the following code:
static void Main(string[] args)
{
const string sourceCodePath = @"C:\Path\To\A\Csharp\Class\File.cs";
var tree = CSharpSyntaxTree.ParseFile(sourceCodePath);
var root = (CompilationUnitSyntax)tree.GetRoot();
foreach (var field in root.DescendantNodes().OfType().Select(f => f.Declaration.GetLastToken()))
Console.WriteLine(field.ToString());
Console.ReadLine();
}
At this point, if you hit F5, what you’re going to see on the screen is a list of the fields contained in the class that you specify as your “sourceCodePath” variable (at least you will with the happy path — I haven’t tested this extensively to see if I can write classes that break it). Now, could you simply write a text parser (or, God forbid, some kind of horrible regex) to do this? Sure. Are there C# language modeling utilities like a Code DOM that would let you do this? Sure. Are any of these things the C# compiler? Nope. Just this.
So think about what this means. You’re not writing a utility that uses a popular C# source code modeling abstraction; you’re writing a utility that says, “hey, compiler, what are the fields in this source code?” And that’s pretty awesome.
My purpose here was to give you a path from “what’s this Roslyn thing anyway” to “wow, look at that, I can write a query against my own code.” Hopefully you’ve gotten that out of this, and hopefully you’ll go forth, tinker, and then you can come back and show me some cool tricks.
is this similar to introspection ?
(warning : I have never use C#, I don’t even know if there is such a thing as introspection in C#)
Assuming I recall this correctly, introspection is the read-only version of language reflection — the ability to retrieve information about the originating source code at runtime. This does exist in C# and I generally see it referred to simply as reflection, with people not distinguishing the read-only nature of introspection. To answer your question, the concepts are related, but Roslyn would be a large, conceptual superset. Reflection (as I’ve seen it implemented) takes advantage of just in time (JIT) compiling to allow you to map runtime object instances back to compile time source code (which is fairly straightforward when you… Read more »
Is it possible to execute script with roslyn in the end user preview?
Yes. The ability to have a C# REPL or to do ad-hoc scripting is one of the killer features. http://www.hanselman.com/blog/ProjectlessScriptedCWithScriptCSAndRoslyn.aspx
Are you really sure it works in end user preview? I think they might have removed the scripting bits.
I would think so, but I’m not entirely sure because I have not, admittedly, tried to use this part of the offering. Kevin Pilch-Bisson is a lead on Roslyn and someone who could definitely answer your questions on the subject: https://twitter.com/Pilchie
Forgot to answer, but the script engine is removed but it will be put back later according to the documentation.
Good to know — thanks for the follow up.
I’m unable to get the method ParseFile why so ?
The Roslyn project is under ongoing development, and this post is over a year old, so they may well have changed things around in the interim. I wish I could be more help, but it’s been a while since I’ve touched this.
Thanks for the introduction! Cool thing! ๐ Please let me show you my post about Roslyn performance considerations: http://bit.ly/1NR7egP Cheers! Robin
Looks really thorough. I’ll have to give it a more in-depth read when I get back from my vacation.
Sounds good! Looking forward to your opinion! Would be great to get some minds from you! ๐ So, enjoy your vacation and thanks for answering! ๐
Wow, that’s a very detailed writeup. Nice job! It’s interesting to see how and why they implemented the facets of the compiler. It’s been a lot of years since I did anything like compiler design, so a gentle introduction is certainly appreciated.