コマンドラインから使える理想のC#コードフォーマッタがほしいという気持ち
この記事は Unity 2 Advent Calendar 2015 9日目の記事です
概要
はじめましての方ははじめまして。ヒカリエのあたりでリアクティブUnityおじさんをしているtrapezoidです。Haruto Otakeとも言います。よろしくお願いいたします。
この記事は、OSXでUnityを使っているWeb上がりのゲーム基盤開発エンジニアが、Unityの(C#の)コードフォーマットを巡る悲哀をNRefactoryの力で解決したという、リアクティブプログラミングもUnityもあまり関係のない話をします。
Unityにおけるコードフォーマッタ事情
現状、"機能としては"どのプラットフォーム上のIDEも実用上十分な性能のコードフォーマッタを持っている。
ただ、Visual Studioは基本的にはなんの問題もないんだが、MonoDevelopで深刻なのが、Unityがコードフォーマット設定を上書きするという挙動のせいで、プロジェクト切り替え時などに唐突にコードフォーマット設定がぶっ飛ぶ。
気付かないで作業し続けて巨大なdiffになってるのにPull Request送った時に気付く、とかよくある。僕は基本的に基盤開発が仕事なので、一日百万回ぐらいこれが発生して発狂しそうになる。
OmniSharpならこんな問題はないけれど、OmniSharpでの開発を強制するのはさすがに自由無さ過ぎてつらい。
Unity5.3で実はこの挙動自体が治ったりしてるんだが、さすがに入れれるのはもう少し先になるし、コミットフックも仕込みたい。 それに、上記の挙動のせいで既存コードには異なるコードフォーマットが混在してしまっているので、一度まとめて何とかする必要がどのみちあった。
既存のコマンドラインベースのC#コードフォーマッタ
そうなったときにやはりコマンドラインベースでコードフォーマッタがほしい、みたいな話になるけれど、MonoDevelop/OmniSharpのコードフォーマッタはそのままコマンドラインでたたける形になってない(調べた限り)。そこで他の選択肢を探すのだが、
- MonoDevelop/OmniSharp主体の開発体制で使っている既存のフォーマット定義をなるべくそのまま利用したい、IDE上でフォーマットしたときと結果が一致するようにしたい
- コミットフックでかかるとはいえ、書いてる途中に把握のためにコードフォーマットかけることも多いし、その状況で一々差分吐かれると非常に面倒。
- クロスプラットフォームで動いてほしい
みたいなことを考え出すと、既存の選択肢だとそれぞれ色々と問題があった。
CodeFormatter
RoslynベースのMicrosoft製コードフォーマッタ。コマンドライン、今の設定を移行させるのが激しくめんどくさい。(チームのコーディング規約側を変えてやろうかと思った...) あと、Microsoft Build Tools 2015が必須なせいか、そのままだとMonoで動かなかった。上記の理由で選ばなかったので追っていない。
Artistic Style
古より存在するコードフォーマッタ。Cと名の付く言語とJavaなら全部フォーマットできますよという懐の深さを持っているが、設定はMonoDevelop/OmniSharpほど細かくはできない。 UniRxとかLINQとか使ってると、めっちゃ見辛いインデントにしてきて完全につらい気持ちになった。 基本UniRXとLINQ絡まないコード書くことのほうが少ないので、これは無し。
ないので作る
そもそもMonoDevelop/OmniSharpがどうやってるのやという話で、まああいつらのことだしどうせNRefactoryにあるんやろ、と考えて見てみたら、実際あった。
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter at master · icsharpcode/NRefactory · GitHub
このへん。使い方としてはCSharpFormatterにCSharpFormattingOptionsとTextEditorOptionsを食わせて、あとはソースコードをstringでぶちこむだけ。NRefactoryはすごい。
CSharpFormattingOptionsとTextEditorOptionsは一々指定するのはない話なので、両方まとめてXmlSerializerで読み書きするとコードフォーマット定義ファイルの出来上がりです。あとはCLIアプリとしての体裁を整えるだけ。
そのうち公開したいけど、本当に設定とコードのテキストぶち込むだけなので、諸々含めてもせいぜい2桁行に収まる規模にしかならんのでやめました。 とりあえず各位気持ちで書いて気持ちでやっていってください。
以上。
次はmasakam1さんです。