在Delphi中查找死代码通常很简单:只需编译然后扫描缺少蓝点的例程。在大多数情况下,智能链接器非常适合跟踪它们。
问题是,这对事件处理程序不起作用,因为它们是已发布的方法,(理论上)可以通过RTTI以某种方式调用,即使这在实际操作中几乎不会发生。
我正在努力清理一个大型的VCL表格单元,它在整个历史中经过多次弯曲,折叠,旋转和切割。如果我有某种方法可以找到表单的DFM实际上没有引用的事件处理程序并删除它们,那肯定会很好。有没有简单的方法来做到这一点?插件IDE专家,例如?
答案 0 :(得分:6)
这有点难看(好吧,它很多丑陋),但对于一个单位来说,它几乎是万无一失的,并且不需要额外的工具:
答案 1 :(得分:5)
使用“重命名方法”重构来重命名每个事件处理程序。选中“重构前查看参考”复选框。
检查“重构”窗口。如果事件处理程序链接到控件,则会有一个“VCL设计器更新”部分显示哪些控件链接到该方法。
这也将显示该方法是从任何其他单元调用,还是以编程方式分配。
注意:这是针对D2006的,在以后的版本中可能略有不同。
答案 2 :(得分:2)
在最一般的情况下,没有任何解决方案可以保证给出正确答案(正如您所说,基于通过RTTI调用它们的可能性)。
一种解决方案是进行代码覆盖率测试,并仔细查看从未到过的处理程序。
答案 3 :(得分:2)
我不知道有一个预先存在的应用程序或插件来执行此操作,但编写脚本应该不难。
假设您没有使用RTTI或手动分配事件处理程序:(我是C ++ Builder用户而不是Delphi,因此以下内容可能不太正确。)
*.pas
。查找以class
声明或published
指令开头且以end
,private
或public
结尾的每个文本块。在每个文本块中,提取每个procedure
。我最习惯使用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:
cleanup.sh
。cd /cygdrive/c/myapp
./cleanup.sh
,然后按Enter键。答案 4 :(得分:2)
我不认为从自动角度来看这是可能的。当对象内部发生特定事件时,将激活事件处理程序。在给定的运行中没有触发偶数并不意味着没有执行途径来导致它。
你也可以在运行时动态分配处理程序,这样就不会在一种情况下使用。
e.g。
button.onclick:= DefaultClickHandler;
button.onClick:= SpecialClickHandler;
假设点击处理程序与onclick事件签名匹配,但如果签名不正确,则无法进行编译。
然而,您可以通过查找找到具有(Sender:TObject)方法签名的所有方法并将其方法与.dfm中的方法进行比较来找到所有已废弃的处理程序(请确保将其保存为文本如果你正在使用旧版本的delphi),我的书中可能会怀疑没有自动连接的antyhing。
-
如果您不想沿着cygwin路径前进,可以将src和dfm加载到两个TStirngLists中,并从每个TStirngLists中删除名称/ idents,并生成一个包含几个循环和一些字符串操作的列表。我的猜测是大约20分钟的工作来获得你可以忍受的东西。
答案 5 :(得分:2)
比克雷格更容易实现。
转到可疑事件处理程序。以一致的方式重命名 - 我通过在名称前放置一个x来执行此操作,转到实现并执行相同的操作。看看编译器对它的看法。
如果不满意你只需更改名称。
您可以使用相同的方法来消除不再执行任何操作的数据元素。
答案 6 :(得分:2)
ModelMaker Code Explorer包含所谓的Event handler view。它还显示未连接到任何组件的事件处理程序。