2009-03-26 2 views
6

Delphi에서 데드 코드를 찾는 것은 대개 간단합니다. 단지 파란색 점이없는 루틴을 컴파일하고 스캔하십시오. 똑똑한 링커는 대부분 시간을 추적하는 것이 좋습니다.델파이에서 사용되지 않는 이벤트 핸들러를 찾는 방법이 있습니까?

문제는 실제 메서드에서는 거의 발생하지 않지만 RTTI를 통해 (이론적으로) 호출 될 수있는 게시 된 메서드이기 때문에 이벤트 처리기에서 작동하지 않습니다.

나는 구부러지고, 접혀지고, 스핀들 딩되고, 역사적으로 여러 번 절단 된 대형 VCL 폼 유닛을 정리하려고합니다. 실제로 양식의 DFM에 의해 참조되지 않고 삭제되는 이벤트 처리기를 찾을 수있는 방법이 있다면 좋을 것입니다. 이 작업을 수행하는 쉬운 방법이 있습니까? 플러그인 IDE 전문가, 예를 들면?

+1

실제로 RTTI를 통한로드는 실제로 모든 시간에 발생합니다. DFM 리소스를로드 할 때마다 메소드 주소를 RTTI로 이름별로 가져옵니다. 이것이 이벤트 핸들러가 처음부터 가시성을 게시 한 이유입니다. 링커는 DFM 내용을 해석하지 않습니다. 컴파일러도 마찬가지입니다. –

+0

그 모든 것을 알고 있습니다. 제발 과격하지 마세요. 내가 말한 것은 RTTI를 통해 코드의 다른 부분에서 참조하는 것이 었습니다. (수동으로, 달리 말하면.) 그리고 RPC 기술을 사용하지 않는다면 아주 드물게 일어난다. –

답변

2

나는 이것이 자동적 인 관점에서 가능하다고 생각하지 않습니다. 이벤트 핸들러는 특정 이벤트가 오브젝트 내부에서 발생할 때 활성화됩니다. 주어진 실행에서 트리거되지 않은 것이 실행 경로가 없다는 것을 의미하지 않습니다.

또한 런타임에 동적으로 처리기를 할당 할 수 있으므로 한 상황에서 사용되는 처리기가 부담스럽지 않습니다.

button.onclick : = DefaultClickHandler;

button.onClick : = SpecialClickHandler;

클릭 핸들러가 onclick 이벤트 서명과 일치한다고 가정하지만 서명이 올바르지 않으면 컴파일되지 않습니다. 메서드 서명과 그의 .DFM에 그 (에 방법의 것은 확실히 당신을 것을 비교 :


그러나, 당신은 아마 (TObject의 보낸 사람)가 찾을 수있는 모든 방법을 찾는 모든 버려진 처리기를 찾을 수 있습니다 이전 버전의 델파이로 작업하는 경우 텍스트로 저장), 자동으로 유선 처리되지 않은 내 책은 내 책에서 용의주 할 수 있습니다.

-

당신은 Cygwin에서 경로를 아래로 가고 싶지 않는 경우에, 당신은이 TStirngLists으로 SRC와 DFM을로드하고 이름을 찢어/각에서 idents 및 루프의 부부와 함께 목록을 생성 할 수 있습니다 일부 문자열 조작. 내 추측은 당신이 살 수있는 무언가를 얻는 데 약 20 분이 걸린다.

+0

고맙습니다.하지만 MarkusQ에 말씀 드렸듯이 여기서는 가장 일반적인 경우를 찾고 있습니다. 예외는 아닙니다. 모든 경우에 오판 (false positive)이없는 모든 데드 코드 이벤트 핸들러를 찾는 확실한 방법은 없다는 것을 잘 알고 있습니다. 그렇다고해서 약간의 자동화가 검색 범위를 좁히는 데 유용하지 않다는 것을 의미하지는 않습니다. –

+0

내 개정 노트보기 avove – MikeJ

2

가장 일반적인 경우에 올바른 답을 제공하는 솔루션은 없습니다 (RTTI를 통해 호출 할 가능성에 근거하여).

한 가지 해결 방법은 코드 커버리지 테스트를 수행하고 절대로 도달하지 못한 처리기를주의 깊게 살펴 보는 것입니다. 이것은 조금 못생긴

+0

나는 "가장 일반적인 경우"를 찾고 있지 않다. 가장 일반적인 경우를 찾고 있습니다 : DFM에서 참조 된 핸들러에 대해 PAS 파일의 양식 선언 맨 위 섹션에 선언 된 이벤트 핸들러 목록을 확인하고 모든 고아를보고하십시오. –

6

(OK, 그것은 추한 많은에게 입니다)하지만, 하나 개의 단위 것이 절대 안전한에 가까운, 그리고 별도의 도구가 필요하지 않습니다 :

  1. 것은 확인을 그의 현재 버전 양식은 소스 컨트롤에 체크!
  2. 이벤트 처리기가있는 클래스의 인터페이스 맨 위로 이동하십시오. 모든 이벤트 핸들러 메소드 인터페이스를 삭제하십시오.
  3. 코드 탐색기/오류 인사이트를 확인하십시오. 구현은 있지만 인터페이스는없는 메소드가 강조 표시됩니다. 구현을 삭제하십시오.
  4. 이제 장치를 저장하십시오. Delphi는 실제로 처리되는 각 이벤트에 대해 누락 된 이벤트 핸들러에 대해 한 번에 하나씩 불만을 제기합니다. 오류가 발생하면이를 기록하십시오.
  5. 양식의 원래 버전을 확인하고 목록에없는 이벤트 처리기를 제거하십시오.
+0

코드를 통해 호출되었으므로 누락 된 부분에 대해 컴파일하고 볼 수있는 단계를 추가합니다. –

+0

리팩토링 방법을 사용하는 것보다 더 좋은 방법은 무엇입니까? 코드 및 dfm에서 한번에 모두 참조를 얻습니다. –

+0

리팩토링보다 삭제가 쉽지만 개인적인 선택의 문제입니다. –

2

기존 앱이나 플러그인을 인식하지 못해도 스크립트를 작성하기가 어렵지 않습니다. 당신을 가정

는 RTTI를 사용하거나 수동으로 이벤트 처리기를 할당하지 않는 : (I 델파이가 아닌 C++ 빌더 사용자를, 그래서 다음은 아주 정확하지 않을 수 있습니다.)

  1. 이 목록을 확인 코드에 게시 된 모든 메서드
    • 올바른 방법은 *.pas입니다. class 선언 또는 published 지시문으로 시작하고 end, private 또는 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에서 설치합니다. I 기본 설치는 내가 사용한 모든 도구를 제공해야한다고 생각하지만 긍정적이지는 않습니다.
  • 스크립트를 원본 디렉터리에 cleanup.sh으로 저장합니다.
  • Cygwin 명령 프롬프트를 시작하십시오.
  • 소스가 c : \ MyApp 인 경우 cd /cygdrive/c/myapp
  • 유형 ./cleanup.sh을 입력하고 Enter 키를 누릅니다.
+0

+1을 처리하는 올바른 방법은 다음과 같습니다.이를 수행 할 수있는 짧은 스크립트를 작성합니다. 그러나 egrep을 사용하여 이벤트 처리기를 찾는 방법은 잘못되었습니다. 필자는 awk이 그것을하기에 더 잘 갖추어져 있어야한다고 생각하고, 모든 것을 위해 파이썬을 사용하는 것이 여전히 훨씬 더 적합 할 것이다. – mghie

+0

컴파일러의 --doc 옵션을 사용하고 결과 XML 파일로 시작하는 것은 양식의 게시 된 메소드 목록을 얻는 데 도움이됩니다. – mghie

+0

이 egrep 사용은 어떻게 나쁜가? (나는 그것이 빠른 해킹 인 것을 안다, 나는 단지 그것이 가지고있는 특별한 단점을 궁금해하고있다.) –

2

Craig 's보다 훨씬 쉬운 접근법이 있습니다.

의심스러운 이벤트 핸들러로 이동하십시오. 일관된 방식으로 이름을 바꿉니다. - 이름 앞에 x를 붙이고 구현에 들어가서 같은 작업을 수행합니다. 컴파일러가 생각하는 것을보십시오.

행복하지 않다면 이름을 다시 변경하십시오.

동일한 방법을 사용하여 더 이상 수행하지 않는 데이터 요소를 제거 할 수 있습니다.

5

"이름 바꾸기 방법"리팩터링을 사용하여 각 이벤트 처리기의 이름을 바꿉니다.리팩토링 전에 참조보기 확인란을 선택하십시오.

리팩토링 창을 확인하십시오. 이벤트 처리기가 컨트롤에 연결되어 있으면 "VCL 디자이너 업데이트"섹션에 해당 컨트롤에 연결된 컨트롤이 표시됩니다.

이 방법은 다른 단위에서 호출되거나 프로그래밍 방식으로 할당 된 경우에도 표시됩니다.

참고 : 이것은 D2006 용이며 이후 버전에서 약간 다를 수 있습니다.

관련 문제