2009-03-26 8 views
6

Tìm mã chết trong Delphi thường thực sự đơn giản: chỉ cần biên dịch và sau đó quét cho các thường trình thiếu dấu chấm màu xanh của chúng. Các nhà liên kết thông minh rất tốt về việc theo dõi chúng xuống, hầu hết thời gian.Có cách nào để xác định vị trí xử lý sự kiện không sử dụng trong Delphi?

Vấn đề là, điều này không có tác dụng đối với trình xử lý sự kiện vì chúng là các phương thức được xuất bản, theo lý thuyết có thể được gọi thông qua RTTI bằng cách nào đó, mặc dù điều này hầu như không bao giờ xảy ra trong thực tế thực tế.

Tôi đang cố gắng dọn dẹp một đơn vị VCL lớn bị uốn cong, gấp lại, bị bẻ cong và cắt xén nhiều lần trong suốt lịch sử của nó. Nó chắc chắn sẽ được tốt đẹp nếu tôi đã có một số cách để tìm xử lý sự kiện mà không thực sự tham chiếu bởi DFM của biểu mẫu và xóa chúng. Có cách nào dễ dàng để làm điều này? Ví dụ như một chuyên gia về trình cắm thêm IDE?

+1

Thực tế, tải qua RTTI xảy ra TẤT CẢ thời gian trong thực tế thực tế. Mỗi khi bạn nạp một tài nguyên DFM, bạn lấy các địa chỉ phương thức theo tên với RTTI. Đó là lý do tại sao xử lý sự kiện đã xuất bản khả năng hiển thị ở nơi đầu tiên. Trình liên kết không giải thích nội dung DFM; cũng không phải trình biên dịch. –

+0

Tôi biết tất cả về điều đó. Xin vui lòng không được pedantic. Những gì tôi có nghĩa là đã tham khảo thông qua RTTI từ những nơi khác trong mã của bạn. (Làm theo cách thủ công, nói cách khác.) Và * điều đó * rất hiếm khi xảy ra, trừ khi bạn đang thực hiện một số kỹ thuật RPC. –

Trả lời

2

Tôi không nghĩ rằng điều này là có thể từ quan điểm tự động. xử lý sự kiện được kích hoạt khi một sự kiện cụ thể xảy ra bên trong một đối tượng. Điều đó thậm chí không được kích hoạt trong một chạy nhất định không có nghĩa là không có một đường dẫn thực hiện để dẫn đến nó.

bạn cũng có thể gán trình xử lý động theo thời gian để những gì được sử dụng trong một tình huống không phải là thu nhập.

ví dụ:

button.onclick: = DefaultClickHandler;

button.onClick: = SpecialClickHandler;

Giả sử rằng trình xử lý nhấp khớp với chữ ký sự kiện onclick, nhưng bạn sẽ không nhận được biên dịch nếu chữ ký không chính xác.


tuy nhiên, bạn có thể tìm thấy tất cả các bộ xử lý bị bỏ rơi bằng cách tìm kiếm tất cả các phương pháp mà tìm có một (Sender: TObject) chữ ký phương pháp và so sánh rằng mình phương pháp để những người trong .dfm (chắc chắn rằng bạn lưu nó dưới dạng văn bản nếu bạn đang làm việc với một phiên bản cũ hơn của delphi), chống thư rác không được kết nối tự động sẽ là nghi ngờ trong cuốn sách của tôi.

-

nếu bạn không muốn đi xuống con đường Cygwin, bạn có thể tải các src và dfm thành hai TStirngLists và rip ra tên/idents từ mỗi và tạo ra một danh sách với một vài vòng và một số thao tác chuỗi. tôi đoán là khoảng 20 phút làm việc để có được thứ bạn có thể sống cùng.

+0

Cảm ơn bạn, nhưng như tôi đã nói với MarkusQ, tôi đang xem xét trường hợp phổ biến nhất ở đây, không phải ngoại lệ. Tôi nhận thức rõ rằng không có cách nào để tìm kiếm tất cả các trình xử lý sự kiện mã chết mà không có sai tích cực trong mọi trường hợp. Điều đó không có nghĩa là một chút tự động hóa không thể hữu ích trong việc thu hẹp tìm kiếm của bạn. –

+0

xem phần ghi chú đã sửa đổi của tôi – MikeJ

2

Không có giải pháp nào được đảm bảo đưa ra câu trả lời đúng trong trường hợp chung nhất (dựa trên, như bạn lưu ý, về khả năng gọi chúng qua RTTI).

Một giải pháp là thực hiện kiểm tra phạm vi mã và xem xét cẩn thận các trình xử lý chưa bao giờ đạt được.

+0

Tôi không tìm kiếm "trường hợp chung nhất"; Tôi đang tìm trường hợp phổ biến nhất: Kiểm tra danh sách các trình xử lý sự kiện được khai báo trong phần trên cùng của khai báo biểu mẫu trong tệp PAS đối với các trình xử lý được tham chiếu trong DFM và báo cáo mọi trẻ mồ côi. –

6

Đây là một chút xấu xí (OK, nó rất nhiều xấu xí), nhưng đối với một đơn vị đó là gần hết sức rõ ràng, và không cần công cụ bổ sung:

  1. Hãy chắc chắn rằng phiên bản hiện tại của biểu mẫu được kiểm tra vào kiểm soát nguồn!
  2. Chuyển đến đầu giao diện của lớp nơi trình xử lý sự kiện. Xóa tất cả các giao diện phương thức xử lý sự kiện.
  3. Nhìn vào Trình khám phá mã/Lỗi thông tin chi tiết. Các phương thức có triển khai nhưng không có giao diện nào được tô sáng. Xóa các triển khai.
  4. Bây giờ hãy lưu đơn vị. Delphi sẽ, từng người một, phàn nàn về việc xử lý sự kiện mất tích cho mỗi sự kiện đó là thực sự xử lý. Viết xuống khi các lỗi xuất hiện.
  5. Kiểm tra phiên bản gốc của biểu mẫu và xóa trình xử lý sự kiện cho mọi thứ không có trong danh sách của bạn.
+0

Tôi sẽ thêm một bước khác để biên dịch và xem những bước mà nó phàn nàn về việc thiếu bởi vì chúng được gọi qua mã. –

+0

Làm thế nào là nó tốt hơn so với sử dụng phương pháp refactor? Nó được các tài liệu tham khảo trong mã và trong dfm tất cả cùng một lúc ... –

+0

Tôi tìm thấy xóa dễ dàng hơn refactoring, nhưng đó là một vấn đề của sự lựa chọn cá nhân, tôi đoán. –

2

Tôi không biết ứng dụng hoặc plugin có từ trước để thực hiện việc này, nhưng không khó để viết kịch bản.

Giả sử bạn không sử dụng RTTI hoặc bằng tay gán xử lý sự kiện: (Tôi là một người dùng C++ Builder hơn là Delphi, vì vậy sau đây có thể không hoàn toàn chính xác.)

  1. Lập một danh sách của tất cả các phương pháp được xuất bản trong mã của bạn.
    • Cách thích hợp để thực hiện việc này là đọc *.pas. Tìm từng khối văn bản bắt đầu bằng tuyên bố class hoặc chỉ thị published và kết thúc bằng một số end, private hoặc public. Trong mỗi khối văn bản này, trích xuất mỗi procedure.
    • Cách dễ dàng để thực hiện việc này là tạo danh sách các loại trình xử lý sự kiện phổ biến và giả sử chúng được xuất bản.
  2. Khi bạn có danh sách này, hãy in mọi thứ từ danh sách không được tìm thấy trong tệp DFM của bạn.

Tôi cảm thấy thoải mái nhất khi sử dụng các công cụ Cygwin hoặc Linux để tạo tập lệnh. Đây là một tập lệnh bash hoạt động trong Cygwin và nên làm những gì bạn muốn.

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

Để thực sự sử dụng này, nếu bạn không quen thuộc với Cygwin:

  • Tải về và cài đặt Cygwin. Tôi nghĩ rằng cài đặt mặc định sẽ cung cấp cho bạn tất cả các công cụ tôi đã sử dụng, nhưng tôi không tích cực.
  • Lưu tập lệnh vào thư mục nguồn của bạn là cleanup.sh.
  • Bắt đầu lời nhắc lệnh Cygwin.
  • Nếu nguồn của bạn nằm trong c: \ MyApp, sau đó nhập cd /cygdrive/c/myapp
  • Nhập ./cleanup.sh và nhấn Enter.
+0

+1 cho cách thích hợp để xử lý việc này: Tôi sẽ viết một tập lệnh ngắn có thể thực hiện. Tuy nhiên, cách được vạch ra để tìm trình xử lý sự kiện bằng cách sử dụng egrep là xấu. Tôi cho rằng awk nên được trang bị tốt hơn để làm điều đó, và sử dụng python cho tất cả mọi thứ sẽ là một phù hợp hơn nhiều vẫn còn. – mghie

+0

Sử dụng tùy chọn --doc của trình biên dịch và bắt đầu với tệp XML kết quả cũng sẽ giúp lấy danh sách các phương thức được xuất bản của biểu mẫu. – mghie

+0

Làm thế nào là egrep này sử dụng xấu? (Tôi biết nó là một hack nhanh chóng, tôi chỉ tự hỏi những thiếu sót cụ thể nó có.) –

2

Có cách tiếp cận dễ dàng hơn nhiều so với Craig.

Chuyển đến trình xử lý sự kiện đáng ngờ. Đổi tên nó theo một cách nhất quán - tôi làm điều này bằng cách đặt một x ở phía trước của tên, đi xuống để thực hiện và làm điều tương tự. Xem những gì trình biên dịch nghĩ về nó.

Nếu không vui, bạn chỉ cần đổi tên lại.

Bạn có thể sử dụng cùng một phương pháp để loại bỏ các yếu tố dữ liệu không còn làm bất cứ điều gì nữa.

5

Sử dụng quy trình tái cấu trúc "Đổi tên phương thức" để đổi tên từng trình xử lý sự kiện.Chọn hộp kiểm "Xem tham chiếu trước khi tái cấu trúc".

Kiểm tra cửa sổ Tái cấu trúc. Nếu trình xử lý sự kiện được liên kết với một điều khiển, sẽ có phần "Cập nhật thiết kế VCL" hiển thị (các) điều khiển nào được liên kết với phương thức.

Điều này cũng sẽ hiển thị nếu phương thức được gọi từ bất kỳ đơn vị nào khác hoặc được chỉ định theo chương trình.

Lưu ý: đây là dành cho D2006, có thể hơi khác trong các phiên bản sau.