matarillo.com

The best days are ahead of us.

31日間ReSharper一周 Day 7: コードフォーマット

2012-12-30 18:17:12

元記事

31日間ReSharper一周」の7日目にようこそ。

ReSharperは、コードフォーマットについて多くの支援をする。支援方法は大きく3つのカテゴリーに分類される。入力時、ファイル単位での必要時、複数ファイルでの必要時だ。

入力時のフォーマット

こんなの目新しくないよね。Visual Studioだってこの機能はしばらく前から持ってた。でも、ReSharperのフォーマット設定はもちろんバージョン管理できるし共有もできる。だから、型変換の直後にスペースを置くマシンと置かないマシンが混在したりしない。ここだけは勝っている。

ReSharperの他のフォーマット機能で素晴らしい所は、空のカーリーブレースの中でEnterを取り扱う方法だ。Visual Studioでの取り扱いより少しよくて、自動終了デリミタにきちんと関連づいている。

空文で始める。
開始ブレースを入力して…
Enterを押す。

ファイル全体をフォーマットする: Ctrl+Alt+F

ReSharperには、作業中のソースファイル全体を再フォーマットするコマンドもある。Ctrl+Alt+Fを押せば、「コードを再フォーマットする」ダイアログボックスが出る。

注目してほしいのは、この機能は空白文字をいじるより多くのことができるってことだ。コード中の灰色部分を修正させることもできる。「using文を最適化する」とか「冗長な’this.‘修飾子を削除する」なんてのは見たまんまだ。「参照を短くする」では、System.Drawing.Graphicsが単にGraphicsに変更され(、usingが足りなければ追加され)る。

僕らはいつも、このチェックボックスの全部にチェックを入れている。コードはできるだけきれいであってほしいからね。ここでの設定は次回にも引き継がれる。

追記: Maruis曰く、Ctrl+Alt+Shift+Fならサイレントモードになり、ダイアログはポップアップしない。しかもちゃんと前回選択した設定を使ってくれる。すばらしい!ありがとうMaruis!

コードを再フォーマットする時に、ReSharperは以下のこともする。

  • 明示的な可視性修飾子を追加する。可視性修飾子のないクラスにはinternalが追加される。可視性修飾子のないフィールドにはprivateが追加される。(これは、ReSharperの他のすべてと同じように、変更可能だ。だから、コードを読みやすくしたくない理由があるのなら、この設定をオフにしたっていい。)
  • 単純なゲッターとデリゲートを一行に置く。もし、ゲッター/セッター/デリゲートの本体が1文なら(例えば、値の付与だけとか、return文だけとか)、ReSharperは閉じカッコもまとめて1文にする。だからReSharperは下のようなひどいフォーマットのコードを見つけて……
public Color BorderColor {
    get
    {
        return _borderColor;
    }
    set { _borderColor = value; Invalidate(); }
}

こんな具合に再フォーマットする。

public Color BorderColor
{
    get { return _borderColor; }
    set
    {
        _borderColor = value;
        Invalidate();
    }
}

Visual Studio 2005は、ゲッターやセッターが1行なら「折りたたみ」用の+記号を出さないでいてくれるので、この機能は本当にありがたい。

プロジェクトまたはソリューションを再フォーマットする

最後になるけど、ReSharperにはたくさんのファイルをまとめて再フォーマットするオプションがある。フォルダかプロジェクトかソリューションを右クリックして、「コードを再フォーマットする」を選択するだけだ。

言うまでもないことかもしれないが、一応注意しておこう。コードを変更していたのなら、まとめて再フォーマットする前にソース管理リポジトリにコミットするべきだ。ソリューション全体の再フォーマットをするなら、また別途コミットするほうがいい。この機能で変更する場合、やってほしくない変更をしてしまう時だってある。設定を変更するにしろ、予想外の結果を受け入れるにしろ、その前に一部だけ前の状態に戻したいと思うこともあるだろうからね。

あんまりうまくいかないところ #1:デリゲートのインデント

デフォルトでは、ReSharperはインラインのデリゲートをおかしなところにインデントする。これはReSharperのデフォルトが間違ってると思うことの1つだ。コードは普通にインデントしてほしい。コードの半分がこんな風にでこぼこの中央揃えになるのは嫌だ。

Block incrementer = delegate {
                        ++i;
                        ++j;
                    };
Block resetter = delegate {
                     i = 0;
                     j = 0;
                 };

これを直す方法をやっと見つけた。匿名メソッドのフォーマット設定はReSharperオプションの2つのページに分けられている。「Braces Layout」と「Other」だ。「おかしなインデントはやめろ」は「Other」のページにある「匿名メソッドの本体をインデントする」だ。これをオフにして、カッコの設定を「行の最後に置く」にすれば、ずっとましになる。

Block incrementer = delegate {
    ++i;
    ++j;
};
Block resetter = delegate {
    i = 0;
    j = 0;
}

あんまりうまくいかないところ #2:Xceedのライセンス

ReSharperは修飾子をできる限り短くしようとする。変な状況にはまってしまうと可読性が悪くなることもある。以下がそんな例だ。僕らの回避策(けっこううまくいったと思う)も載せておく。

僕らはXceed社のコンポーネントを使っている。Xceedで何よりイライラするのはライセンスの許諾方法だ。配布されるライセンスキーはアホほど長い英数字で、実行するためには、初期化コードでこの文字列を静的プロパティに突っ込まないといけない。こんな感じだ。

Xceed.Grid.Licenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
Xceed.Editors.Licenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

そう。Xceedのアセンブリごとにライセンスキーをセットしないといけないんだ。そうしないと、実行時に文句を言われることがある(言われないこともあるから意味が分からん。でもとにかくライセンスキーはセットするようにしている。念のためにね)。

変なのは、複数のアセンブリに含まれているLisenceKeyというクラスについてだ。ReSharperはこんな感じで短くしようとする。

using Xceed;
using Xceed.Grid;
...
Licenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
Editors.Licenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

ぎゃぼー。回避策はこんな感じ。こう書けばReSharperはそのままにしておいてくれる。

using GridLicenser = Xceed.Grid.Licenser;
using EditorLicenser = Xceed.Editors.Licenser;
...
GridLicenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
EditorLicenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

ツールの制限を避けるためではあるけど、こっちの方が読みやすいんじゃないかな。


31日間ReSharper一周 インデックスへ戻る