6

Delphiでデッドコードを見つけるのは通常、非常に簡単です。コンパイルしてから、青い点がないルーチンをスキャンするだけです。スマートリンカーは、ほとんどの場合、それらを追跡するのに非常に優れています。

問題は、これはイベントハンドラーでは機能しないことです。これは、公開されたメソッドであり、実際にはほとんど発生しない場合でも、(理論的には)RTTIを介して呼び出すことができるためです。

私は、その歴史の中で何度も曲げられ、折り畳まれ、紡錘形にされ、切断された大きなVCLフォームユニットをクリーンアップしようとしています。フォームのDFMによって実際に参照されていないイベントハンドラーを見つけて削除する方法があれば、きっといいでしょう。これを行う簡単な方法はありますか?たとえば、プラグインIDEエキスパート?

4

7 に答える 7

6

これは少し見にくいですが (OK、かなり見にくいです)、1 つのユニットの場合はほぼ確実に実行でき、追加のツールは必要ありません。

  1. フォームの現在のバージョンがソース管理にチェックインされていることを確認してください!
  2. イベント ハンドラーがあるクラスのインターフェイスの先頭に移動します。イベント ハンドラー メソッド インターフェイスをすべて削除します。
  3. Code Explorer/Error Insight を見てください。実装はあるがインターフェイスがないメソッドが強調表示されます。実装を削除します。
  4. ユニットを保存します。Delphi は、一度に 1 つずつ、実際に処理される各イベントの欠落しているイベント ハンドラについて不平を言います。エラーが発生したら、これらを書き留めます。
  5. フォームの元のバージョンを確認し、リストにないイベント ハンドラーを削除します。
于 2009-03-26T21:32:39.713 に答える
6

「メソッドの名前変更」リファクタリングを使用して、各イベント ハンドラーの名前を変更します。「リファクタリング前に参照を表示」チェックボックスをオンにします。

[リファクタリング] ウィンドウを確認します。イベント ハンドラーがコントロールにリンクされている場合、どのコントロールがメソッドにリンクされているかを示す [VCL Designer Updates] セクションが表示されます。

これは、メソッドが他のユニットから呼び出された場合、またはプログラムによって割り当てられた場合にも表示されます。

注: これは D2006 用であり、それ以降のバージョンでは若干異なる場合があります。

于 2009-03-26T22:47:56.803 に答える
3

ModelMaker コード エクスプローラには、いわゆるイベント ハンドラ ビューが含まれています。また、どのコンポーネントにも接続されていないイベント ハンドラーも表示されます。

于 2011-09-13T19:39:56.407 に答える
2

最も一般的なケースで正しい答えを与えることが保証されている解決策はありません(ご存知のように、RTTIを介してそれらを呼び出す可能性に基づいています)。

1つの解決策は、コードカバレッジテストを実行し、到達しなかったハンドラーを注意深く調べることです。

于 2009-03-26T21:21:57.243 に答える
2

これは自動の観点からは可能だとは思いません。オブジェクト内で特定のイベントが発生すると、イベント ハンドラーがアクティブになります。特定の実行でイベントがトリガーされないということは、それにつながる実行経路がないことを意味するわけではありません。

また、実行時にハンドラーを動的に割り当てることができるため、ある状況で使用されるものは保証されません。

例えば

button.onclick := DefaultClickHandler;

button.onClick:= SpecialClickHandler;

クリック ハンドラーが onclick イベント シグネチャと一致すると仮定しますが、シグネチャが正しくない場合はコンパイルされません。


ただし、(Sender: TObject) メソッド シグネチャを持つすべてのメソッドを検索し、そのメソッドを .dfm 内のメソッドと比較することで、すべての放棄されたハンドラを見つけることができます (必要な場合は、必ずテキストとして保存してください)。古いバージョンの Delphi を使用している場合)、自動的に配線されていないアンチヒーリングは、私の本では疑わしいでしょう。

--

cygwin パスをたどりたくない場合は、src と dfm を 2 つの TStirngList にロードし、それぞれから名前/ID を取り出して、いくつかのループといくつかの文字列操作でリストを生成できます。私の推測では、生活できるものを手に入れるのに約 20 分の作業が必要です。

于 2009-03-26T21:43:59.467 に答える
2

Craig の方法よりもはるかに簡単な方法があります。

疑わしいイベント ハンドラーに移動します。一貫した方法で名前を変更します。名前の前に x を付けてこれを行い、実装に移動して同じことを行います。コンパイラがそれについてどう考えるかを見てください。

満足できない場合は、名前を元に戻すだけです。

同じアプローチを使用して、もはや何もしないデータ要素を削除できます。

于 2009-03-26T22:16:51.073 に答える
2

これを行うための既存のアプリやプラグインについては知りませんが、スクリプトを作成するのは難しくありません。

RTTI を使用していないか、イベント ハンドラを手動で割り当てていないと仮定します (私は Delphi ではなく C++Builder を使用しているため、以下は正しくない可能性があります)。

  1. コードで公開されているすべてのメソッドのリストを作成します。
    • これを行う適切な方法は、 を読むこと*.pasです。class宣言またはpublishedディレクティブで始まり、、、またはで終わるendprivateテキストブロックを見つけますpublic。これらの各テキスト ブロック内で、それぞれを抽出しますprocedure
    • これを行う簡単な方法は、一般的なイベント ハンドラー タイプのリストを作成し、それらが公開されていると想定することです。
  2. このリストを取得したら、リストから DFM ファイルにないものをすべて印刷します。

スクリプト作成には、Cygwin または Linux ツールを使用するのが最も快適です。これは、Cygwin で動作し、必要な処理を実行する bash スクリプトです。

#!/bin/bash

for file in `find -name *.pas`; do
    echo $file:

    # Get a list of common event handling procedures.
    # Add more types between the | symbols.
    egrep '^[[:space:]]+procedure.*(Click|FormCreate|FormClose|Change|Execute)\(' $file | 
    awk '{print $2}' | cut -f 1 -d '(' > published.txt

    # Get a list of used event procedures.
    egrep '^[[:space:]]+On.* =' ${file%.pas}.dfm | awk '{print $3}' > used.txt

    # Compare the two.
    # Files listed in the left column are published but not used, so you can delete them.
    # Files in the right column were not by our crude search for published event 
    # handlers, so you can update the first egrep command to find them.
    comm -3 published.txt used.txt

    echo

done

# Clean up.
rm published.txt used.txt

これを実際に使用するには、Cygwin に慣れていない場合:

  • Cygwin をダウンロードしてインストールします。デフォルトのインストールでは、使用したすべてのツールが提供されるはずですが、肯定的ではありません。
  • スクリプトをソース ディレクトリに として保存しますcleanup.sh
  • Cygwin コマンド プロンプトを起動します。
  • ソースが c:\MyApp にある場合は、次のように入力します。cd /cygdrive/c/myapp
  • 入力してEnter./cleanup.shキーを押します。
于 2009-03-26T21:36:44.150 に答える