妄想プログラマのらくがき帳 : 11月 2014

2014年11月24日月曜日

[Roslyn]SyntaxRewriterでソースコードを変更してみる。

今回は SyntaxRewriter を用いた方法でソースコードを変更してみます。

SyntaxRewriter を使ってアクセス修飾子を付加する

C#はメンバ変数のアクセス修飾子を指定しないと既定で private になります。そのため private 変数の場合、private を付けても付けなくても良いのですが、コード内で private 有りと private 無しが混在してると統一感に欠けるので統一したいところです。が、既存コードがすでに有り無し混在状態だと手作業で修正するのは大変ですよね。そこで SyntaxRewriter の出番です。

と前置きはこれくらいにしておいて、サンプルコードは以下の通りになります。


まず CSharpSyntaxRewriter を継承したクラスを作成し、 Visit***() メソッドをオーバーライドします。今回はフィールド宣言が変更対象なので、VisitFieldDeclaration() をオーバーライドします。
VisitFieldDeclaration() は SyntaxTree 内の各 FieldDeclarationSyntax ごとに呼び出されるメソッドで、メソッド内で引数で渡された node を変更し、変更後 node を base.VisitFieldDeclaration() に渡してやることで、SyntaxTree 内にある node を変更後のもので置き換えることができます。変更する必要が無い場合は node をそのまま base.VisitFieldDeclaration() に渡します。

このサンプルコードでは、 アクセス修飾子が付いていない FieldDeclarationSyntax に対し、private を付加して base.VisitFieldDeclaration() に渡しています。


次に作成したクラスを使用し、実際にソースコードを変更する方のサンプルコードです。
パース対象のコード内にある RoslynSample. field1 に private を付加しています。

こちらで行うことは、先ほど作成したクラスの Visit() に SyntaxTree のルートノードを渡すだけです。Visit() の戻り値として変更後の SyntaxTree を取得できます。

変更後の SyntaxTree が表すソースコードを出力すると以下のようになります。


変更前はアクセス修飾子が無かった field1 に private が付いていますね!

と、まあこんな感じで、ソースコードをコーディング規約に従うように自動修正したりするような用途に SyntaxRewriter は便利です。