2009-11-05 12 views
5

Estoy buscando escribir un analizador estático para una clase universitaria. Para proporcionar más potencia a la herramienta, me gustaría poder buscar la jerarquía de llamadas (como lo hace Ctrl + Alt + H en Eclipse). Esto también tendría que ser una operación rápida, por lo que la búsqueda probablemente tendría que hacerse contra un índice en lugar de escaneo de código byte.¿Es posible desacoplar las capacidades de indexación de código de Eclipse?

Sin embargo, escribir un plugin de Eclipse sería demasiado ambicioso, espero. En cambio, prefiero desacoplar las partes de Eclipse que crean el índice de código, y usar una biblioteca para hacer búsquedas. La interfaz para el usuario estaría en la línea de comando, para simplificar la implementación.

He leído que Eclipse usa Lucene para hacer la indexación [1], sin embargo, debe haber una cantidad significativa de trabajo sobre Lucene para las capacidades que permite Eclipse.

La pregunta es, ¿es posible desacoplar las capacidades de indexación de Eclipse para su reutilización? Si no, ¿hay otras bibliotecas disponibles disponibles que puedan hacer el tipo de procesamiento que he discutido?

[1] Lucene En Acción (IIRC)


EDITAR

creo que ha habido un malentendido. No estoy buscando inspeccionar la jerarquía de clases, quiero inspeccionar llamar a la jerarquía. Es por eso que la búsqueda y la indexación (de algún tipo, aunque tal vez ese no sea el término correcto) entran en discusión. Inspeccionar la jerarquía de clases es probablemente mucho menos costoso que inspeccionar la jerarquía de llamadas.

En cuanto a escribir un plugin de Eclipse, sí, me encantaría, pero dado que esta tarea es en un plazo muy corto, es probable que no lo logre. Pero es información útil que algunos de ustedes sienten que esto no es tan difícil como creo que será.

Quizás he puesto demasiado énfasis en Eclipse, se me ocurrió que realmente estoy buscando cualquier herramienta que proporcione una API para inspeccionar un gráfico de llamadas a través del bytecode.

¡Gracias por sus respuestas hasta ahora!

+0

- Una cosa importante que debe saber acerca de cómo Eclipse funciona tan rápido, es que crea el índice general una vez, y luego únicamente lo actualiza cuando cambia la clase. Así que supongo que hay poco que desacoplar de esta función de Eclipse. No veo cómo puede evitar un análisis inicial de código de bytes completo, que construirá la tabla de jerarquía de llamadas (que se puede guardar para evitar tener que escanear cada tipo para buscar una jerarquía de llamadas). Para ser sincero, excepto en una base de código realmente grande, un escaneo completo es realmente rápido con ASM, el tiempo que pasará escribiendo un "indexador delta" no valdrá la pena, imo. – Olivier

+0

Un escaneo inicial inicial está bien. Lo que más me preocupa es encontrar una API que simplemente lo haga (ya que está fuera del alcance de mi clase). Si el escaneo completo inicial es con ASM, está bien, solo quiero evitar escribir ese bit ;-) – Grundlefleck

Respuesta

1

La operación que busca no es exactamente la indexación. La indexación se realiza para proporcionar una búsqueda de texto completo. Encontrar la superclase de una clase dada es difícilmente buscar texto.

Desea escribir un plugin de Eclipse (bastante simple, puede ser solo un par de clases) que utiliza JDT. Tendrá que escribir un visitante AST (Árbol de sintaxis abstracta) que se utilizará para analizar su código. Luego podrá resolver tipos y atravesar fácilmente la jerarquía de clases utilizando las instalaciones de JDT.

Consulte my answer to this question.

+0

Consulte mi edición. No estoy buscando resolver la superclase, sino gráficos de llamada para un método en particular. Aclamaciones. – Grundlefleck

+0

Supongamos que ahora está inspeccionando el método foo, ¿está buscando todos los métodos invocados por foo o invocando foo? Hay una gran diferencia. – zvikico

+0

Invocando a foo. Invocando un constructor específicamente. – Grundlefleck

0

Los plugins de Eclipse realmente no son tan difíciles; tardan un poco en acostumbrarse, pero no demasiado tiempo.

Piense en agregar la funcionalidad que desee al eclipse IDE. Puede aprovechar otras funcionalidades de complementos (como JDT, que incluye la funcionalidad de búsqueda que está buscando).

Luego, puede proporcionar sus complementos para que los usen todos los eclipses, en lugar de desarrollar otra herramienta independiente.

1

Me gustaría una solución basada en ASM, hará el trabajo duro, resolviendo la jerarquía. Aquí es un analizador simple, que PRINTLN la jerarquía de llamada de la clase dada:

public class Analyzer { 
    public static void main(String[] args) throws IOException { 
     ClassReader classReader; 
     ClassNode classNode; 
     String fullyQualifiedClassName = args[0]; 
     String callHierarchy = ""; 
     while (null != fullyQualifiedClassName) { 
      callHierarchy = " > " + fullyQualifiedClassName + callHierarchy; 
      classReader = new ClassReader(fullyQualifiedClassName); 
      classNode = new ClassNode(); 
      classReader.accept(classNode, 0); 
      if (null != classNode.superName) { 
       fullyQualifiedClassName = classNode.superName.replace('/', '.'); 
      } else { 
       fullyQualifiedClassName = null; 
      } 
     } 
     System.out.println(callHierarchy); 
    } 
} 

Dada java.util.TreeMap como argumento, imprime

> java.lang.Object > java.util.AbstractMap > java.util.TreeMap 

Sé que esto es el análisis de código de bytes, pero para ser honesto, ASM es muy rápido y si todo lo que necesitas es Call Hierarchy, el escaneo no llevará mucho tiempo (nada notable).

Esperanza esta ayuda :)

+0

Su ejemplo demuestra la "jerarquía de tipos", estoy buscando la "Jerarquía de llamadas". Como en, si el método A llama al método B y busco la jerarquía de llamadas de B, muestra el método A. Esto es más complicado que la jerarquía de tipos, y creo que requiere escanear toda la base de códigos. Es por eso que estaba buscando una solución indexada. A menos que haya entendido mal algo ... – Grundlefleck

4

Caminando el código de bytes no es difícil en absoluto y no es lento tampoco. Hemos realizado un análisis estático de grandes proyectos de código Java a velocidades interactivas. Como no tienes mucho tiempo, te sugiero que modifiques algo como un plugin de visor de gráficos de llamadas [1] en eclipse. Además, el código de Eclipse es difícil de comprender, es mejor que escribas tu propio complemento que utiliza la mayor cantidad de API indocumentadas de Eclipse como sea posible.

[1] http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-1326.html

+0

+1 el enlace ofrece algo interesante para explorar. – Grundlefleck

+1

Me encanta esta propuesta: "use la mayor cantidad posible de API indocumentadas de Eclipse". ¿En serio? –

+0

Lo hice. Es lento, pero con persistencia puede hacerlo. – mansu

1

Tenga una mirada en el marco de IBM WALA. Entre otras cosas, puede generar el Call Graph (CG) para su código base. De hecho, casi todo en WALA comienza con la construcción del CG. Puede modificar sus ejemplos y reemplazar los datos de prueba con los suyos.

1

Ignoraría a Eclipse por completo: solo lo distraerá.

Si está realizando un análisis estático, seguramente querrá analizar bytecode. Para encontrar la jerarquía de llamada, usted busca el invokeinstance, invokestatic y invokespecial bytecodes (véase la JVM spec). Éstos hacen referencia a una clase/nombre-método completamente calificado, y usted puede construir su jerarquía de llamadas usando un Map<FuncRef,Set<FuncRef>>, donde FuncRef es una clase que usted define para contener la información de la llamada al método.

BCEL puede ayudarle con el escaneo de códigos de bytes.

Sin embargo, vas a tener que hacer más trabajo que eso, particularmente con invokeinstance, ya que no sabes cuál podría ser la instancia real. A veces puede mirar hacia atrás en el código para encontrar una tarea, pero es más probable que adivine: este es el talón de Aquiles del análisis estático.

0

sospecho que usted encontrará que es más fácil escribir el plugin - para el que Eclipse está diseñado y documentado - que para extraer los bits que están destinados a ser internos y construir algo más de ellos.

Cuestiones relacionadas