matarillo.com

The best days are ahead of us.

31日間ReSharper一周 Day 18: Alt+Enterでいろいろ追加

2012-12-30 18:17:12

元記事

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

昨日は赤い電球のことと、それを使ってChange Allを実行する方法について話した。今日は、赤い電球のメニューにあるいくつかの応急処置について話そう。前に書いたとおり、赤い電球があるときには、Alt+Enterを押せばメニューがドロップダウン表示される。

コンテキスト感度

未定義の(赤い)シンボルがあれば、ReSharperはシンボルを定義するための選択肢を表示する。どの選択肢が表示されるかは賢く決まる。

  • シンボルが大文字で始まるなら、「プロパティの作成」(本当は「読み取り専用プロパティの作成」であるべきなんだが。実行されるのはそっちなんだから)が表示される。
  • 「get/setのプロパティ作成」もあるけど、どっちを割り当てるかはここの使用法だけできまってしまう。(全ての使用法を見た上でどっちを割り当てるべきか判断するほどはすごくない。追記: この件に関する要求が多かったので、ReSharperの次バージョンで実装することがすでに決まっている。)
  • シンボルが小文字で始まるなら、「フィールドの作成」と「局所変数の作成」が表示される。
  • シンボルの後に開き括弧が続くならば、(プロパティ/フィールド/変数ではなく)「メソッドの作成」が表示される。
  • 関連しているのは「セットアクセサの作成」で、読み取り専用プロパティに値をセットしようとしているコードでAlt+Enterを押すと表示される。実はこれは、赤いシンボルじゃなくて赤波線に基づいた動作だ。

これらも全部賢いんだけど、Change Allのように無気味なくらい賢いってわけじゃない。

以下を入力して…… 「局所変数の作成」をすると
if (a) bool a;
ArrayList.Adapter(b) IList b;
c.PixelOffsetMode = PixelOffsetMode.Half; object c;

「局所変数の作成」が「Change All」と同じくらい賢いなら、上の3行目では単なるプレーンなobjectではなく、Graphics c;が生成されているだろう。(違いの理由はこんなところじゃないかと思う。Change Allでは既存のシンボルのどれが使用法に合致するかを知らなければならない。だから、見ないといけない変数とプロパティはたぶん2~3ダースだ。「局所変数の作成」の場合は出発点がフィルタリングされているという利点がないから、同じことをするには.Net Frameworkの何十万ものクラスをすべて見なければならないし、それはかなり遅い。でももしそうだったならとてもすごかっただろうに。追記: サポートが同意した。機能要請は追加されており、ReSharperの次のバージョンに入ると言ってた!)

型に関する賢さ

ReSharperがAlt+Enterメニューを作成しているとき、シンボルがどう使われているのかは見ていない。でも一度選択肢を選んだ後からは見る。

もしこんな風にシンボルを1箇所で使うだけならば、

ReSharper は、変数をそのものずばりの型で、この場合はBitmapとして宣言するだけだ。(でもカーソルは、一時的なコードテンプレートを伴って、新しく宣言された変数の所にくる。だから、別の型がよければそこに入力できる。)

でも、もしこんな風に基底型を期待する場所でもシンボルを使っているなら(DrawImageは第一引数にBitmapの親である型(Image)を期待する)、

それなら、「局所変数の作成」ではどの型を使いたいかという選択肢が表示され、デフォルトは基底型になる。

プロパティのための選択肢

プロパティを作成するとき、ReSharperは再び一時的なコードテンプレートを作る。最初は戻り値の型から始まり、受け入れるか変えるかすることができる。そしてTabを入力すると、ゲッター/セッターコードをどのように生成するかの選択肢が表示される。

Alt+Enterで「プロパティの作成」をした後のReSharper。裏づけフィールドかデフォルトボディテンプレートのどちらかを使う選択肢を表示。

  • 裏付けフィールドは、名前から連想されることをする。それは適切な型と(ReSharper Optionsで設定した命名規約設定に基づく)名前でフィールドを宣言し、ゲッターではフィールドを返し、(適用できるならば)セッターではフィールドにセットする。フィールドがすでに存在するなら二度と追加されない。
  • デフォルトボディテンプレートは、例外を投げるコードをゲッターとセッターに置く。

メソッドのための選択肢

メソッドを作成するためにAlt+Enterを使うと、一時的なコードテンプレートで戻り値の型、引数の型、引数名が指定できる。大して驚くようなことはない。

でもすごいのは、ReSharperの変数名提案が始まることだ。もし呼び出し元が変数かプロパティを渡しているなら、ReSharperは同じ変数名を引数名のデフォルトに使う。さらに、型名に基づいた通常の提案も行われる。

Tabキーを押して複数の名前が提案された引数に移動すると、補完用ドロップダウンボックスが表示される。もちろん、一覧にない名前を入力することもいつでもできる。

Alt+Enterで「メソッドの作成」をした後のReSharper。引数名の提案を表示。

接頭辞(例えば、"first")を入力してからCtrl+Spaceを押して残りの名前を提案させることだってできる。(残念なことに、これは呼び出し元の変数名で補完できず、型名に基づいて提案することしかできない。たとえば、上記のコードでfirstと入力してCtrl+Spaceを押すと、firstIntは提案されるが、firstCountはされない。)

制限:復帰

これらのコマンドのどれかを使うと、ReSharperは新しい宣言の中にカーソルを入れ、そして一時的なコードテンプレートを使って型やコードを変更できる。しかし、それが終わったときは、元いたところに戻る方法を分かっていないといけない。

ReSharperには「最後に編集した場所に移動」というコマンドがあって、Ctrl+Shift+Backspaceでアクセスできる。これで出発地点に戻ることができるようだ……少なくとも時々は。最初に押したときは何も動作しないだろうけど、ツイていれば2回目にはかつて赤かったシンボルに戻れるだろう。(でも、その後何か他のものをAlt+Enterで補完して、また戻ろうとすると、期待する動作はしないだろう。)

制限:命名規約を心得てない

これらの機能は、ReSharper Optionsにおける「命名規約」ページにちゃんと従うほど賢くはない。フィールドは_から始まるという半標準を指定すれば、すでに_ から始まっているシンボルには局所変数を作成する選択肢は出ないことが期待されるし、さらに、_のないシンボルには「フィールドの作成」オプションは表示されず、フィールドを作成するときに_を加えないことが期待される。ReSharperは、これらのどれもやらない。「フィールドの作成」と「局所変数の作成」はどちらも命名規約設定に全く気づいていない。(僕はこれを機能要求に入れておいた。)


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