2009-03-26 10 views
6

Encontrar un código muerto en Delphi suele ser muy simple: simplemente compile y luego busque rutinas que no tengan sus puntos azules. El enlazador inteligente es muy bueno para rastrearlos, la mayoría de las veces.¿Hay alguna forma de localizar controladores de eventos no utilizados en Delphi?

El problema es que esto no funciona para los controladores de eventos porque son métodos publicados, que (en teoría) podrían invocarse mediante RTTI de alguna manera, aunque esto casi nunca sucede en la práctica real.

que estoy tratando de limpiar una gran unidad de forma VCL que ha sido doblado, plegado, fusiformes y mutilado diversas ocasiones a lo largo de su historia. Sería bueno si tuviera alguna forma de encontrar manejadores de eventos a los que realmente no hace referencia el DFM del formulario y eliminarlos. ¿Hay alguna manera fácil de hacer esto? ¿Un experto en IDE enchufable, por ejemplo?

+1

En realidad, la carga a través de RTTI ocurre TODO el tiempo en la práctica real. Cada vez que carga un recurso DFM, obtiene las direcciones de los métodos por nombre con RTTI. Es por eso que los controladores de eventos han publicado la visibilidad en primer lugar. El enlazador no interpreta los contenidos DFM; tampoco lo hace el compilador. –

+0

Sé todo sobre eso. Por favor no seas pedante. Lo que quise decir es hacer referencia a través de RTTI desde otro lugar en su código. (Haciéndolo manualmente, en otras palabras.) Y * que * muy raramente ocurre, a menos que esté haciendo algún tipo de técnica RPC. –

Respuesta

2

no creo que esto es posible desde un punto de vista automática. los manejadores de eventos se activan cuando ocurre un evento particular dentro de un objeto. Que el par no se active en una ejecución dada no significa que no haya una vía de ejecución para conducirlo.

También puede asignar dinámicamente los controladores en tiempo de ejecución por lo cuál se utiliza en una situación no se garuanteed.

p. Ej.

button.onclick: = DefaultClickHandler;

button.onClick: = SpecialClickHandler;

Suponiendo que los manejadores de clic coinciden con la firma del evento onclick, pero no obtendría una compilación si la firma fuera incorrecta. Sin embargo


, es probable que pueda encontrar todos los controladores abandonados mediante la búsqueda de todos los métodos que encontrar un (Sender: TObject) firma del método y la comparación de que su de los métodos a los de la .dfm (asegúrese de que guárdelo como texto si está trabajando con una versión anterior de delphi), antyhing no cableado automáticamente sería sospechoso en mi libro.

-

si no quieres ir por el camino cygwin, se puede cargar el src y DFM en dos TStirngLists y rasgar el nombre/identificativos de cada uno y generar una lista con un par de bucles y algunas manipulaciones de cuerdas. mi suposición es aproximadamente 20 minutos de trabajo para obtener algo con lo que puedas vivir.

+0

Gracias, pero como le dije a MarkusQ, estoy viendo el caso más común aquí, no las excepciones. Soy muy consciente de que no hay una forma infalible de encontrar todos los controladores de eventos de código muerto sin falsos positivos en todos los casos. Eso no significa que un poco de automatización no pueda ser útil para reducir su búsqueda. –

+0

ver mi nota revisada evitar – MikeJ

2

no hay una solución que está garantizado para dar una respuesta correcta en el caso más general (basa, como se nota, sobre la posibilidad de llamar a ellos a través de RTTI).

Una solución sería hacer pruebas de cobertura de código y observar cuidadosamente a los controladores que nunca se alcanzaron.

+0

No estoy buscando "el caso más general"; Estoy buscando el caso más común: compruebe la lista de controladores de eventos declarados en la sección superior de la declaración de formulario en el archivo PAS contra los controladores a los que se hace referencia en el DFM, e informe a los huérfanos. –

6

Esto es un poco feo (OK, es mucho feo), pero para una unidad que está cerca de toda prueba, y no requiere herramientas adicionales:

  1. Asegúrese de que la versión actual de la ¡la forma se comprueba en el control de la fuente!
  2. Vaya a la parte superior de la interfaz de la clase donde están los controladores de eventos. Eliminar todas las interfaces de métodos del controlador de eventos.
  3. Mire Code Explorer/Error Insight. Se resaltarán los métodos que tienen implementaciones pero no interfaces. Eliminar las implementaciones.
  4. Ahora guarde la unidad. Delphi, uno a la vez, se quejó del controlador de eventos faltantes para cada evento que realmente se maneja. Anótelos a medida que surgen los errores.
  5. Consulte la versión original del formulario y elimine los controladores de eventos para cualquier cosa que no esté en su lista.
+0

Agregaría otro paso para compilar y ver cuáles faltan porque se llaman por código. –

+0

¿Cómo es mejor que usar el método de refactorización? Obtiene las referencias en código y en dfm de una sola vez ... –

+0

Encuentro que borrar es más fácil que refactorizar, pero es una cuestión de elección personal, supongo. –

2

No conozco una aplicación o un complemento preexistente para hacer esto, pero no debería ser difícil crear una secuencia de comandos.

Suponiendo que no se esté usando RTTI o asignar manualmente los controladores de eventos: (yo soy un usuario C++ Builder en lugar de Delphi, por lo que el siguiente puede que no sea del todo correcto.)

  1. Haga una lista de todos los métodos publicados en tu código.
    • La forma correcta de hacerlo es leer *.pas. Encuentra cada bloque de texto que comienza con una declaración class o una directiva published y termina con una end, private, o public. Dentro de cada uno de estos bloques de texto, extraiga cada procedure.
    • La manera más fácil de hacerlo es hacer una lista de los tipos de controladores de eventos comunes y asumir que están publicados.
  2. Una vez que tenga esta lista, imprima todo de la lista que no se encuentra en su archivo DFM.

Me siento más cómodo usando las herramientas de Cygwin o Linux para scripting. Aquí hay un script bash que funciona en Cygwin y debe hacer lo que quiera.

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

utilizar realmente esto, si usted no está familiarizado con Cygwin:

  • descargar e instalar Cygwin. Creo que la instalación predeterminada debería darle todas las herramientas que utilicé, pero no estoy seguro.
  • Guarde la secuencia de comandos en su directorio de origen como cleanup.sh.
  • Inicie un indicador de comando de Cygwin.
  • Si su fuente está en c: \ MyApp, escriba cd /cygdrive/c/myapp
  • Escriba ./cleanup.sh y presione Entrar.
+0

+1 para la forma correcta de manejar esto: escribiré un breve guión que pueda hacerlo. Sin embargo, la forma resumida de encontrar controladores de eventos usando egrep es mala. Asumo que awk debería estar mejor equipado para hacerlo, y usar python para todo sería mucho mejor. – mghie

+0

Usar la opción --doc del compilador y comenzar con el archivo XML resultante también debería ayudar a obtener la lista de métodos publicados del formulario. – mghie

+0

¿Cómo es este uso de egrep malo? (Sé que es un truco rápido, solo me pregunto qué deficiencias particulares tiene) –

2

Hay un enfoque mucho más fácil que el de Craig.

Vaya a un controlador de eventos sospechoso. Cambie el nombre de una manera consistente: hago esto colocando una x en frente del nombre, voy a la implementación y hago lo mismo. Mira lo que el compilador piensa de eso.

Si no está contento, solo cambia los nombres.

Usted puede utilizar el mismo método para eliminar elementos de datos que ya no hacen nada.

5

Usar la refactorización "Cambiar el nombre de método" para cambiar el nombre de cada controlador de eventos.Marque la casilla "Ver referencias antes de refactorizar".

Compruebe la ventana Refactorización. Si el controlador de eventos está vinculado a un control, habrá una sección de "Actualizaciones de VCL Designer" que muestra qué controles están vinculados al método.

Esto también mostrará si el método se llama desde cualquier otra unidad, o se asigna mediante programación.

Nota: esto es para D2006, puede ser ligeramente diferente en versiones posteriores.

Cuestiones relacionadas