Is there a way to find unused event handlers in Delphi?

Finding dead code in Delphi is usually very simple: just compile and then scan the routines, skipping their blue dots. A smart linker tracks them very well, most of the time.

The problem is that this does not work for event handlers, because they publish methods that (theoretically) can be called through RTTI in some way, although this almost never happens in real practice.

I try to clean most of the VCL form that has been bent, folded, twisted and crippled once throughout its history. It would be nice if I had a way to find event handlers that the DFM form does not actually reference and delete them. Is there an easy way to do this? For example, a plug-in IDE expert?

+6
event-handling delphi vcl dead-code
source share
7 answers

I do not think that this is possible from an automatic point of view. event handlers are activated when a specific event occurs inside an object. The fact that it does not even start in this launch does not mean that there is no execution path for it.

it is also possible to dynamically assign handlers at run time, so use in one situation fails.

eg.

button.onclick: = DefaultClickHandler;

button.onClick: = SpecialClickHandler;

Assuming click handlers match the signature of the onclick event, but you would not get compilation if the signature was incorrect.


however, you can probably find all the abandoned handlers by looking for all the methods that detect the method signature (Sender: TObject) and comparing its methods with the methods in .dfm (make sure you save it as text if you are working with an older version delphi), an antia not automatically linked will be suspicious in my book.

-

If you do not want to go along the cygwin path, you can load src and dfm into two TStirngLists and pull out the name / idents from each and generate a list with several loops and some string manipulations. my guess is about 20 minutes of work to get what you can live with.

+2
source share

This is a little ugly (well, it's very ugly), but for one device it is close to reliable and does not require additional tools:

  • Make sure the current version of the form is validated in the original control!
  • Go to the beginning of the class interface where the event handlers are located. Remove all event handler method interfaces.
  • Take a look at Code Explorer / Insight. Methods that have implementations, but not interfaces, will be highlighted. Remove the implementations.
  • Now save the device. Delphi, one at a time, complained about the missing event handler for each event that is actually being processed. Record them when errors occur.
  • Check the original version of the form and remove the event handlers for anything other than your list.
+6
source share

Use the Rename Method refactoring to rename each event handler. Check the box next to "View links before refactoring."

Check the Refactoring window. If an event handler is associated with a control, the VCL Designer Updates section indicates which controls are associated with this method.

It will also show if the method is called from any other units or assigned programmatically.

Note: this is for D2006, may vary slightly in later versions.

+5
source share

There is no solution that is guaranteed to give the correct answer in the most general case (based on, as you noticed, the ability to call them through RTTI).

One solution would be to do code coverage tests and look closely at handlers that have never been reached.

+2
source share

I do not know about the existence of a pre-existing application or plugin, but this should not be difficult for the script.

Assuming you are not using RTTI or manually assigning event handlers: (I am a C ++ Builder user, not a Delphi, so the following may not be entirely correct.)

  • Make a list of all published methods in your code.
    • The right way to do this is to read *.pas . Find every text block that starts with a class declaration or published directive and ends with end , private or public . Within each of these text blocks, print each procedure .
    • An easy way to do this is to list the types of handlers for common events and assume that they are published.
  • Once you have this list, print everything from a list that is not found in your DFM file.

Itโ€™s more convenient for me to use Cygwin or Linux scripting tools. Here's a bash script that works in Cygwin and should do what you want.

 #!/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 

To use this if you are not familiar with Cygwin:

  • Download and install Cygwin. I think the default installation should provide you with all the tools that I used, but I'm not sure.
  • Save the script to the source directory cleanup.sh .
  • Run the Cygwin command prompt.
  • If your source is in the c: \ MyApp directory, enter cd /cygdrive/c/myapp
  • Type ./cleanup.sh and press Enter.
+2
source share

Itโ€™s much easier than Craigโ€™s.

Go to the suspicious event handler. Rename it sequentially - I do this by putting x in front of the name, go to the implementation and do the same. See what the compiler thinks about it.

If you don't like it, you just change the names.

You can use the same approach to eliminate data items that do nothing else.

+2
source share

ModelMaker Code Explorer contains the so-called event handler view . It also shows event handlers that are not associated with any component.

+1
source share

All Articles