読者です 読者をやめる 読者になる 読者になる

Roslynと戯れてみる

NCC Advent Calendar 2015 12日目の記事です

前回は3846masa先輩による 3846masaのやりたいことリストの消化具合を確認する 2015 でした

今回はRoslynを使って遊んでみたことを書こうと思います

コードとかはこの辺を見て下さい.
github.com
github.com
github.com




Roslynとは

RoslynはC#(とVB?)のコンパイラです. 詳しいことはよく分かりませんが, RoslynのAPIを使うことでコンパイラが持っている中間情報などを取得したり出来ます. 例えばC#のコードを突っ込んで, 構文解析とか意味解析したり, インタプリタみたいに実行したり… 今まで面倒くさかったり, 出来なかったことが出来るようになってるらしい?
詳細に関してはぼんぷろ先生の記事とか見て下さい...
www.buildinsider.net
www.buildinsider.net

インタプリタみたいなことをしてみる

Microsoft.CodeAnalysis.CSharp.Scriptingなどを使うことで可能です

var Code = "using System;\n" +
           "Console.WriteLine(\"Hello, World!\");";
CSharpScript.Create(Code).RunAsync().Wait();

実行するとHello, World!と表示されます

CSharpScript.Createの第2引数に

var options = ScriptOptions.Default.
    AddReferences(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).GetTypeInfo().Assembly,
        typeof(System.Console).GetTypeInfo().Assembly)
    .AddImports(usings.ToArray());

とかを渡せば参照を追加したりも出来ます

コードの整形をする

Microsoft.CodeAnalysis.Formattingを使えばコードを整形することも可能です

var Code = "using System;class Program{static void Main(){Console.WriteLine(\"Hello, World!\");}}";
Code = Formatter.Format(
    CSharpSyntaxTree.ParseText(
        Code
            .Replace("{", "{\n")
            .Replace("}", "\n}")
        ).GetRoot(),
    MSBuildWorkspace.Create()
    ).ToFullString();
Console.WriteLine(Code);

こんな感じで書くとワンライナーだったコードが

using System;
class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}

こんな感じで整形されたものになります

構文・意味解析をしてシンタックスハイライトを入れる

ぼんぷろ先生の記事がめっちゃ参考になります
www.buildinsider.net
簡単に説明すると

var tree = CSharpSyntaxTree.ParseText(Code);

でコードを構文解析し, 構文木などを得ることが出来ます
後はテキトーに

foreach (var item in tree.GetDiagnostics())
{
  Console.WriteLine(item);
}

みたいなことをすればエラーとかを見ることが出来ます


ハイライトはNodeをゴリゴリ見ていって, 要素ごとに色を付けるだけです
この辺とか見て下さい
github.com

エラー箇所の背景を赤くするとか, この辺を見てもらえれば出来ると思います
https://raw.githubusercontent.com/kkrnt/CSharpViewer/master/cv.png
github.com



最近はこんな感じのことをしていて, Roslynで遊ぶの楽しいです^^;