これは Delphi Advent Calendar 2019 の 7 日目の記事です
次の課題が現れた
「リファクタリングメニューの詳細な動き」というお題
まず、メニューの中身を見てみよう
メニューの中身
- 移動
- インターフェースの抽出
- スーパークラスの抽出
- メンバのプルアップ
- メンバのプッシュダウン
- 安全な削除
- 変数のインライン化
- フィールドの導入
- 変数の導入
- 名前の変更
- 変数の宣言
- フィールドの宣言
- メソッドの抽出
- リソース文字列の抽出
- パラメータの変更
- ユニットの検索
とある
それぞれどんな時に使うのか、どんな事ができるのかを確認してみた
移動
あ、このクラス作ったけど、他のユニット (名前空間) に移動したいというときに便利
例えば、VCL アプリケーションを作るじゃろ
クラスを定義するじゃろ
プロジェクトにユニットを追加するじゃろ
移動を実行するじゃろ
作ったクラスが追加したユニット側に移動するのじゃ
この例では、Unit3 に定義した THoge クラスが Unit4 側に移動します
インターフェースの抽出
選択した 1 つ以上のクラスから新しいインターフェイスを作成します
選択したクラスには、生成されたインターフェースが追加されます
THoge = class の箇所にカーソルを置き(ナビゲーションツールバーの型の欄に該当するクラスが表示されている状態)で、メニューから [リファクタリング|インターフェースの抽出] を選択します
インターフェース名や、名前空間などを設定するダイアログが表示されます
[OK] ボタンを押すと、インターフェース (Ihoge) が生成され、選択したクラスにはインターフェースが追加されています
ちょっと残念なのは生成されたインターフェースが後ろに来てしまうので、エラーインサイトで未定義の識別子として検出されてしまう点
クラスとインターフェイスの関係は、ドキュメントの「インターフェイスの使用」を参照のこと
スーパークラスの抽出
選択したクラスから上位クラス( スーパークラス )を作成します。
インターフェースの抽出の時と同様に、THoge = class の箇所にカーソルを置き(ナビゲーションツールバーの型の欄に該当するクラスが表示されている状態)で、メニューから [リファクタリング|スーパークラスの抽出] を選択します
同様にダイアログが表示されます
[OK] ボタンを押すと、スーパークラス (Shoge) が生成され、選択したクラス (Thoge) は、スーパークラスを継承する定義に変更されます
メンバのプルアップ
クラスのメンバ( フィールド、メソッド、プロパティ、イベント )を上位のスーパークラスに移動させます
仕様変更でクラスのメンバを上位クラスに移動させる時に使える
エラーインサイトにエラーがあると実行されないので注意
THoge クラスの hoge2 の
procedure Shoge.hoge2;
begin
end;
の箇所を選択して、メニューから [リファクタリング|メンバのプルアップ] を選択します
選択したメンバのプルアップを行うためのダイアログが表示されます
[OK]ボタンを押し実行すると、hoge2 は上位のスーパークラス Shoge に移動します
メンバのプッシュダウン
プルアップの反対で、クラスのメンバ( フィールド、メソッド、プロパティ、イベント )を継承先のクラスに移動させます
仕様変更でクラスのメンバを継承クラスへ移動させる時に使える
エラーインサイトにエラーがあると実行されないので注意
Shoge クラスの hoge2 の
procedure Shoge.hoge2;
begin
end;
の箇所を選択して、メニューから [リファクタリング|メンバのプルダウン] を選択します
選択したメンバのプルダウンを行うためのダイアログが表示されます
[OK]ボタンを押し実行すると、hoge2 は継承されたクラス THoge に移動します
安全な削除
削除したい要素がコードの中で使われていないかを検索して、削除を実行します
まず、削除をしたい要素を選択して、メニューから [リファクタリング|安全な削除] を選択します
安全な削除のダイアログが表示されます
この例では、他にこの要素を使用しているところはないので、このまま [削除] をクリックします
変数のインライン化
例えば以下の例
var
i: Integer;
begin
i := 10;
ShowMessage('変数のインライン化:' + IntToStr(i));
end;
のようなコードは、
begin
ShowMessage('変数のインライン化:' + IntToStr(10));
end;
と同じです。
変数のインライン化では、このような冗長なコードを検索し、更新することができます。
実際の手順ですが、ローカル変数の箇所を選択します
以下の例の場合は、変数 i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|変数のインライン化] を選択します
インライン化のダイアログが表示されます
[OK] ボタンを押すと、変数の宣言が削除され、コード側に変数の値が埋め込まれます
フィールドの導入
var で変数を定義したんだけど、他でも参照したいから クラスのフィールドとして定義して使用したいという時に使える機能
フィールドを導入した際のデータ型は、変数として定義されたときの型をそのまま使用します
ローカル変数の箇所を選択します
この例の場合は、変数 i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|フィールドの導入] を選択します
フィールドの導入のダイアログが表示されますので、フィールドとして定義する際の名前や可視性(private, publicなど)を設定します
また、初期値を設定したい場合は初期値を設定します
[OK] ボタンを押すと、フィールド定義が行われ、選択したブロックの変数は置き換わり(この例では定義が削除されます)
他のブロックで同じ名前の変数を使用している箇所は置き換わりません
(AI が搭載されていないので)それがフィールドなのか、変数で使用されるのかが判断できないからです
変数の導入
クラスのフィールドを使用しているんだけど、やっぱり変数で処理を行ないたいというときに使える機能
変数を導入した際のデータ型は、フィールドとして定義されたときの型をそのまま使用します
実際の手順ですが、以下のようなコードがあります
フィールドの箇所を選択します
以下の例の場合は、フィールド i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|変数の導入] を選択します
変数の導入のダイアログが表示されますので、変数として定義する際の名前を設定します
[OK] ボタンを押すと、変数の定義が行われ、選択したブロックのフィールドは、新しい変数を使用したものに置き換わります
名前の変更
たぶん一番使用するであろう機能
こちらは以前に説明しているので、Delphi IDE の便利な機能 - 名前のリファクタリング の記事をご覧ください
変数の宣言
コードは書いたけど変数として宣言しようか、フィールドとして宣言しようか....
うん、変数、君に決めた!
というときに使える機能
実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択して、IDE のメニューから [リファクタリング|変数の宣言] を選択します
新規変数の宣言のダイアログが表示されますので、変数として定義する際のデータ型を設定します
初期値の設定が必要な場合は、値の設定にチェックをつけて、初期値を入力します
同様に hoge2 も選択して、IDE のメニューから [リファクタリング|変数の宣言] を行います
フィールドの宣言
コードは書いたけど変数として宣言しようか、フィールドとして宣言しようか....
うん、フィールド、君に決めた!
というときに使える機能
実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択して、IDE のメニューから [リファクタリング|フィールドの宣言] を選択します
新規フィールドの宣言のダイアログが表示されますので、フィールドとして定義する際のデータ型を設定します
またアクセス制御 (private, public など) を設定します。
メソッドの抽出
コード内のココの部分、他のところでも使うからメソッドにしておくと便利かな?と思った時に使える機能
選択した箇所を新たなメソッドとして抽出して定義し、選択した箇所をそのメソッドで置き換えます
あくまで新たなメソッドとして抽出するだけなので、パラメータの定義は行われないことに注意
パラメータを渡す場合は、この後、リファクタリングのパラメータの変更で修正を行う必要があります
この例では hogehoge1 := 0; を他でも使用するからメソッドとして抽出しています
まず該当の hogehoge1 := 0; を選択して、メニューから [リファクタリング|メソッドの抽出] を選択します
メソッドの抽出ダイアログが現れます
デフォルトの ExtractedMethod の名前を newMethod に書き換えて [OK] をクリックします
リソース文字列の抽出
コード内に文字列リテラルを書くということはよくありますが、修正時にいちいちコードを探して修正するのはめんどくさい
これを使うと、文字列リテラルを抽出してリソース文字列として定義してくれる
以下の例は、ShowMessage に記述されている文字列リテラルを取り出して、自動的に resousestring にリソース文字列として定義するというものです
パラメータの変更
メソッドの抽出のところでちらっと出てきましたが、定義されているメソッドのパラメータを変更したいときに使用します
実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択、または hoge1 の直後にキャレットを置きます
IDE のメニューから [リファクタリング|パラメータの変更] を選択します
パラメータの変更のダイアログが表示されますので、新しいパラメータを追加するのであれば [追加] のボタンを押します
[OK] ボタンを押すと、パラメータが追加されます
更に追加するのであれば、再度 [追加] ボタンを、内容の編集を行うのであれば [編集] ボタンを、削除するのであれば [削除] ボタンをおして、定義するパラメータを編集します
編集が終わったら、[OK]ボタンを押します
宣言側、実装側、共に変更した内容が反映されます
ユニットの検索
コードで別ユニット内のクラスなどを使う場合には uses 句に宣言されているユニットを追加する必要がありますが、あれあれ?どのユニットだったっけ?というときに使える機能
実際の手順ですが、以下のようなコードがあります
コード内の Form2 を選択します
IDE のメニューから [リファクタリング|ユニットの検索] を選択します
ユニットの検索が行われ、候補が表示されます
該当する候補を選択して、インターフェースまたは実装として追加するかを選択します
[OK] ボタンを押すと、検索して見つかったユニットの参照定義が追加されます