Roslyn(.NET Compiler Platform)の知識マップ(知識グラフ)
この記事は、C#/VBのコンパイラ基盤であるRoslynを、構文を表すSyntax Treeと意味を表すSemanticModelという2つのAPIを軸に整理した入門記事です。Compilationは複数のSyntax Treeと参照アセンブリからSemanticModelを解決するための材料をまとめ、Workspaceはソリューション・プロジェクト単位の操作をMSBuildWorkspaceなどの実装で提供します。この土台の上に、警告を出すAnalyzer、修正案を提示するCode Fix、コンパイル時にコードを追加するSource Generatorという3つの使い方が乗り、Analyzerの重大度は.editorconfigで構成でき、.NET 5以降で既定有効になる.NET SDK同梱Analyzerも同じ仕組みの上に成り立ちます。Source Generatorは複雑さゆえに、.NET Frameworkの既存資産への最初の導入手段としては推奨されません。
Roslyn(.NET Compiler Platform)
C#とVisual Basicのコンパイラ実装であると同時に、コード解析ツールを作るためのAPI群でもある基盤。
Roslynコンパイラ
Syntax Tree
ソースコードの構文構造を、クラス・メソッド・式・ステートメントなどのC#の構文要素として表すRoslynの木構造。
構文木
SemanticModel
構文木の各ノードが実際にどのシンボル(型・メソッドなど)に解決されたかなど、コードの意味をコンパイラの名前解決結果として取得できるRoslynのAPI。
Workspace(Roslyn)
Solution・Project・Documentという単位で、単一ファイルではなくソリューションやプロジェクト全体のコードを扱うためのRoslynのAPI。
Compilation(Roslyn)
SyntaxTreeの集合・参照アセンブリ・コンパイルオプション・言語バージョンなど、型解決や参照解決に必要な情報をまとめたRoslynの型。
Symbol(Roslyn)
型・メソッド・プロパティ・フィールド・引数・ローカル変数などを、ソースコード上の見た目ではなくコンパイラが解決した意味として表すRoslynのインターフェイス群。
MSBuildWorkspace
MSBuildを使ってソリューション・プロジェクトファイルを読み込む、RoslynのWorkspaceの実装。
Analyzer(Roslyn)
特定の構文やシンボルを検出し、Diagnostic(警告・エラー)としてコンパイラやIDEに報告する仕組み。
.editorconfig
Analyzerの診断IDごとの重大度やコードスタイル規則を、プロジェクト単位で調整するための設定ファイル。
Code Fix(Roslyn)
Analyzerが検出した問題に対して、安全に適用できる修正案を提示する仕組み。
Source Generator(Roslyn)
コンパイル時に実行され、生成したC#コードを同じコンパイルに追加する仕組み。既存コードの書き換えではなく追加コードの生成を行う。
IIncrementalGenerator
変更差分を効率よく扱えるよう設計された、Source Generatorの実装インターフェイス。
.NET SDK同梱Analyzer
.NET 5以降のプロジェクトで既定で有効になる、.NET SDKに同梱されたコード分析機能。コード品質・信頼性・性能・セキュリティ(CAxxxx)とコードスタイル(IDExxxx)の診断を含む。
.NET Framework
Windowsのコンポーネントとして扱われ、インストールされているOSのライフサイクルに沿ってサポートされるランタイム。System.Messagingの対象範囲。
.NET(Core以降)
.NET Frameworkの後継となる、クロスプラットフォーム対応の.NETランタイム(.NET 5以降)。
モダンな.NET
Roslynはソースコードの構文構造を、クラス・メソッド・式などのC#の構文要素として整理されたSyntax Treeとして表す
Roslynはコードの意味(このコードが何を指しているか)を、SemanticModelというAPIとして構文とは別に提供する
Roslynは単一ファイルではなくソリューションやプロジェクト全体を扱うためにWorkspaceを提供する
SemanticModelを取得するには、SyntaxTreeと参照アセンブリから構成されたCompilationが必要になる
SemanticModelはCompilation.GetSemanticModel(tree)のようにSyntaxTreeを指定して取り出すもので、意味を問い合わせる対象のSyntaxTreeを前提とする
SemanticModelは、構文ノードが実際にどのSymbol(型・メソッドなど)に解決されたかを取得する手段を提供する
MSBuildWorkspaceは、MSBuildプロジェクトファイルからソリューションを読み込むという形でWorkspaceのAPIの実装を担う
Analyzerはまず構文(SyntaxKind)で候補ノードを絞り込んでから、その先の判定に進む設計が推奨される
Analyzerは、構文で絞った候補が本当に対象のAPIかをSemanticModelでの名前解決によって確定させる
Analyzerが報告する診断の重大度は、dotnet_diagnostic.<ID>.severityのように.editorconfigで調整できる
Analyzerが検出した問題に対する修正案を提示する場合、Code FixはそのAnalyzerの診断IDを前提とする。CodeFixProviderは修正対象の診断IDを登録する仕組みなので、コンパイラ自身が出す診断に対するCode Fixも書ける。
Source Generatorはユーザーのソースコードを読み、生成したコードを同じCompilationに追加する
IIncrementalGeneratorは、変更差分を効率よく扱える形でSource Generatorの実装を担うインターフェイスである
.NET SDK同梱の.NETコード分析は、CAxxxx/IDExxxxの診断としてAnalyzerの仕組みの上に実装されている
.NET SDK同梱Analyzerの重大度も、他のAnalyzer同様に.editorconfigで調整できる
Workspace上の各Projectは、型解決や参照解決に使うCompilationを取得できる
.NET Frameworkの既存資産に対しては、最初からSource Generatorを組み込むよりRoslynベースの調査ツールやAnalyzerから始める方が安全とされる
Code Fixは不変なSyntax Treeに対し、WithIdentifierのような呼び出しで新しいノードを作る形で修正を適用する
.NET SDK同梱のコード分析は、.NET 5以降のプロジェクトで既定で有効になる。.NET Framework等の他のターゲットでは既定で有効ではなく、EnableNETAnalyzersを明示的にtrueにすれば利用できる