Есть ли способ найти неиспользуемые обработчики событий в Delphi? - PullRequest
6 голосов
/ 27 марта 2009

Поиск мертвого кода в Delphi обычно очень прост: просто скомпилируйте, а затем сканируйте подпрограммы, пропускающие их синие точки. Умный линкер очень хорошо умеет выслеживать их большую часть времени.

Проблема в том, что это не работает для обработчиков событий, потому что они являются опубликованными методами, которые (теоретически) могут быть вызваны каким-либо образом через RTTI, даже если это практически никогда не происходит на практике.

Я пытаюсь вычистить большую единицу формы VCL, которая была изогнута, сложена, обмотана и изуродована несколько раз на протяжении всей своей истории. Было бы неплохо, если бы у меня был какой-то способ найти обработчики событий, на которые фактически не ссылается DFM формы, и удалить их. Есть ли простой способ сделать это? Плагин IDE Expert, например?

Ответы [ 7 ]

6 голосов
/ 27 марта 2009

Это немного некрасиво (ОК, это много некрасиво), но для одной единицы это близко к защите от дурака и не требует дополнительных инструментов:

  1. Убедитесь, что текущая версия формы включена в систему контроля версий!
  2. Перейти к началу интерфейса класса, где находятся обработчики событий. Удалите все интерфейсы методов обработчика событий.
  3. Посмотрите на Code Explorer / Error Insight. Методы, которые имеют реализации, но не имеют интерфейсов, будут выделены. Удалить реализации.
  4. Теперь сохраните устройство. Delphi по очереди будет жаловаться на отсутствующий обработчик событий для каждого события, которое фактически обрабатывается. Запишите их по мере появления ошибок.
  5. Проверьте исходную версию формы и удалите обработчики событий для всего, чего нет в вашем списке.
5 голосов
/ 27 марта 2009

Используйте рефакторинг «Метод переименования», чтобы переименовать каждый обработчик событий. Установите флажок «Просмотр ссылок перед рефакторингом».

Проверьте окно рефакторинга. Если обработчик событий связан с элементом управления, в разделе «VCL Designer Updates» будет показано, какие элементы управления связаны с методом.

Это также покажет, вызван ли метод из каких-либо других модулей или назначен программно.

Примечание: это для D2006, в более поздних версиях может немного отличаться.

2 голосов
/ 13 сентября 2011

ModelMaker Code Explorer содержит так называемое представление обработчика событий . Также отображаются обработчики событий, не подключенные ни к одному компоненту.

2 голосов
/ 27 марта 2009

Есть гораздо более простой подход, чем у Крейга.

Перейти к обработчику подозрительных событий. Переименуйте его непротиворечивым способом - я делаю это, помещая перед именем знак x, перехожу к реализации и делаю то же самое. Посмотрите, что об этом думает компилятор.

Если вас это не устраивает, просто поменяйте имена обратно.

Вы можете использовать тот же подход, чтобы исключить элементы данных, которые больше ничего не делают.

2 голосов
/ 27 марта 2009

Я не думаю, что это возможно с автоматической точки зрения. обработчики событий активируются, когда конкретное событие происходит внутри объекта. То, что даже четность не запускается в данном прогоне, не означает, что нет пути выполнения, который бы приводил к нему.

также вы можете динамически назначать обработчики во время выполнения, поэтому то, что используется в одной ситуации, не гарантируется.

, например

button.onclick: = DefaultClickHandler;

button.onClick: = SpecialClickHandler;

Предполагая, что обработчики кликов соответствуют сигнатуре события onclick, но вы не получите компиляцию, если сигнатура неверна.


однако вы, вероятно, можете найти все заброшенные обработчики, найдя все методы, которые имеют сигнатуру (Sender: TObject), и сравнив его методы с методами в .dfm (убедитесь, что вы сохранили его как текст если вы работаете с более старой версией Delphi), в моей книге может быть подозрение на автоматическое соединение с антивирусом.

-

если вы не хотите идти по пути cygwin, вы можете загрузить src и dfm в два TStirngLists и вырвать имена / идентификаторы из каждого и сгенерировать список с парой циклов и некоторыми строковыми манипуляциями. я думаю, что около 20 минут работы, чтобы получить то, с чем вы можете жить.

2 голосов
/ 27 марта 2009

Мне неизвестно о существующем приложении или плагине для этого, но это не должно быть сложно в сценарии.

Предполагается, что вы не используете RTTI или вручную назначаете обработчики событий: (я пользователь C ++ Builder, а не Delphi, поэтому следующее может быть не совсем правильным.)

  1. Составьте список всех опубликованных методов в вашем коде.
    • Правильный способ сделать это - прочитать *.pas. Найдите каждый текстовый блок, который начинается с объявления class или директивы published и заканчивается end, private или public. В каждом из этих текстовых блоков извлеките каждый procedure.
    • Самый простой способ сделать это - составить список распространенных типов обработчиков событий и предположить, что они опубликованы.
  2. Получив этот список, распечатайте все из списка, которого нет в вашем файле DFM.

Мне удобнее всего использовать инструменты Cygwin или Linux для сценариев. Вот скрипт bash, который работает в Cygwin и должен делать то, что вы хотите.

#!/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
  • Введите ./cleanup.sh и нажмите Enter.
2 голосов
/ 27 марта 2009

Не существует решения, которое гарантированно даст правильный ответ в самом общем случае (как вы заметили, на основе возможности вызова их через RTTI).

Одним из решений было бы провести тесты покрытия кода и внимательно посмотреть на обработчики, которые никогда не были достигнуты.

...