Escritura de un conector de analizador de errores

El trabajo de un analizador de errores consiste en reconocer avisos, errores y otros mensajes importantes en la salida del compilador, para crear objetos de "marcador de problema" para ellos. Eclipse visualizará marcadores de problemas con un icono de error o aviso en las vistas de Explorador de proyectos y Problemas, así como en el editor.

Marcadores de problemas generados por un analizador de errores

Es posible que IBM Rational Developer para Power Systems Software no puedan reconocer errores de compilación si utiliza una herramienta de compilación que no soporte actualmente. Si éste es el caso, quizás quiera considerar la escritura de un conector analizador de errores propio que le permita tener una mejor integración con la herramienta de compilación.

El primer paso consiste en configurar un entorno para la escritura de conectores. Esto se explica en la sección sobre Ampliación con conectores. Una vez haya configurado el entorno, puede continuar con la siguiente guía de aprendizaje en la que se explica cómo se crea un analizador de errores.


Crear un nuevo proyecto de conector

Seleccione Archivo > Nuevo > Proyecto y se abrirá el diálogo de selección de asistente Nuevo proyecto. En este diálogo seleccione Proyecto de conector y pulse Siguiente.

Diálogo de selección de asistente Nuevo proyecto

Dé un nombre al proyecto; los nombres de conector habitualmente siguen un convenio de denominación similar al de los paquetes de java.

En la sección Plataforma de destino asegúrese de que se selecciona Eclipse versión 3.4. Es la versión de Eclipse en la que actualmente se basa IBM Rational Developer para Power Systems Software y una versión superior no funcionaría.

Asistente Nuevo proyecto de conector - Página 1

Pulse Siguiente para proceder con la segunda página del asistente.

En la segunda página del asistente, desmarque el recuadro de selección que reza "este conector hará contribuciones a la UI". En esta guía de aprendizaje no vamos a desarrollar ningún componente de interfaz de usuario.

Considere dejar marcado el recuadro de selección que indica "generar un activador". De este modo se generará una clase de activador que se utilizará para responder a los sucesos de ciclo de vida del conector. Para esta guía de aprendizaje en realidad no necesitaremos responder a estos sucesos, no obstante, la mayoría de conectores no triviales generalmente sí necesitarán responder a estos sucesos, por lo que es mejor generar la clase ahora aunque no sea necesaria en este punto.

Asistente Nuevo proyecto de conector - Página 2

Pulse Finalizar.


Configurar dependencias

En el Explorador de proyectos vaya al proyecto recién creado, abra la carpeta META-INF y efectúe una doble pulsación en el archivo MANIFEST.MF.

Explorador de paquetes mostrando MANIFEST.MF

Se abrirá el Editor de manifiesto de conector que se utiliza para configurar los metadatos del conector. En la parte inferior del editor, pulse la ficha Dependencias.

Editor de dependencias

Deberá añadir dos dependencias de conector para poder tener acceso a las APIs necesarias para escribir un analizador de errores. Comience pulsando el botón Añadir en Conectores necesarios; se abrirá el diálogo Selección de conector. Escriba org.eclipse.cdt.core en el recuadro de filtro, seleccione dicho conector y pulse Aceptar. Ahora repita el proceso una vez más y añada el conector org.eclipse.core.resources.

Selector de conector

Los conectores necesarios deben tener un aspecto similar al siguiente. Guarde los cambios.

Editor de dependencias


Crear la clase del analizador de errores

Ahora es el momento de crear una clase Java que contendrá el código del analizador de errores. Expanda la carpeta src en el Explorador de paquetes. Habrá un paquete Java creado automáticamente. Pulse con el botón derecho del ratón en el paquete y seleccione Nuevo > Clase.

Crear una clase nueva

Se abrirá el Asistente nueva clase Java. Dé un nombre a la clase, por ejemplo "MyErrorParser".

Asistente nueva clase Java

Pulse el botón Añadir situado junto a la sección de interfaz: se abrirá el Diálogo Selección de interfaces implementadas. Escriba "IErrorParser" en el recuadro de filtro y elija la interfaz IErrorParser.

Diálogo de selección de interfaces implementadas

Pulse Finalizar: se creará una nueva clase para el analizador de errores con una implementación de apéndice del método processLine().

Apéndice de analizador de errores


Registrar el analizador de errores

Antes de escribir código debemos asegurarnos de que nuestro nuevo analizador de errores lo reconoce IBM Rational Developer para Power Systems Software. Vuelva a abrir el editor de manifiestos de conector y pulse la ficha Ampliaciones en la parte inferior.

Ampliaciones

Pulse el botón Añadir para abrir el diálogo Nueva ampliación. Elija el punto de ampliación org.eclipse.cdt.core.ErrorParser y pulse Finalizar.

Diálogo nueva ampliación

La ampliación org.eclipse.cdt.core.ErrorParser debe aparecer en la sección Todas las ampliaciones.

Ampliaciones

Pulse la ficha plugin.xml en la parte inferior para abrir el archivo plugin.xml en el editor. Edite el archivo para que el cuerpo del archivo tenga un aspecto similar al siguiente.

<plugin>
   <extension
         id="org.mycompany.errorparser.MyErrorParser"
         name="Test Error Parser"
         point="org.eclipse.cdt.core.ErrorParser">
      <errorparser
          class="org.mycompany.errorparser.MyErrorParser">
      </errorparser>
   </extension>
</plugin>

El atributo de clase del elemento <errorparser> debe contener el nombre completo de una clase que implemente la interfaz IErrorParser.

En este punto es una buena idea probar que IBM Rational Developer para Power Systems Software puede reconocer el nuevo analizador de errores. Inicie IBM Rational Developer para Power Systems Software utilizando la configuración de ejecución creada en la sección correspondiente a Ampliación con conectores. En IBM Rational Developer para Power Systems Software, pase a la perspectiva C/C++ remoto. Si aún no tiene un proyecto en el espacio de trabajo, cree uno.

Pulse con el botón derecho del ratón en un proyecto y abra las propiedades del proyecto. Desplácese hasta Compilación C/C++ > Valores. En la ficha Analizadores de errores debe ver el nuevo analizador de errores en la lista. Pulse el recuadro de selección situado junto a él para habilitarlo y súbalo hasta la parte superior para que tenga precedencia respecto a los demás analizadores de errores. También puede ser una buena idea inhabilitar todos los demás analizadores de errores mientras efectúa el desarrollo. Pulse Aceptar.

Página de propiedades de valores


Escribir el código de análisis

Ahora es el momento de empezar a escribir realmente el código del analizador de errores.

Siempre que se produzca una compilación, la salida del mandato de compilación se envía al analizador de errores de una en una línea en secuencia. Se llamará al método processLine() una vez por cada línea de salida y se le pasarán dos argumentos, una String que contiene la línea de salida y una referencia a ErrorParserManager. El objeto gestor tiene algunos métodos de simplificación que ayudan a crear objetos de marcador de problema.

El patrón normal es intentar reconocer cada línea como mensaje de aviso o error de compilador. Una buena forma de hacerlo es comparar la línea con una expresión regular y utilizar la captura de regiones para extraer las partes de la línea que son de interés, tales como el nombre de archivo, el número de línea y el mensaje de error.

El modo en que escriba el analizador de errores depende realmente de la herramienta de compilación que vaya a utilizar. A continuación se proporciona un ejemplo de implementación que reconoce mensajes de error del compilador XLC de IBM.


package org.mycompany.errorparser;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IErrorParser;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.core.resources.IResource;


public class MyErrorParser implements IErrorParser {

    static String regexp = "\"((?:\\w|\\.)+)\", line (\\d+)\\.\\d+: (.*)";
    static Pattern errorPattern = Pattern.compile(regexp);

    public boolean processLine(String line, ErrorParserManager manager) {
        Matcher matcher = errorPattern.matcher(line);
        if(!matcher.matches())
            return false;
		
        String fileName = matcher.group(1);
        int lineNumber  = Integer.parseInt(matcher.group(2));
        String message  = matcher.group(3);
		
        IResource resource = manager.findFileName(fileName);
        if(resource == null)
            resource = manager.findFilePath(fileName);
        if(resource == null)
            resource = manager.getProject(); // archivo no encontrado en el espacio de trabajo, adjuntar problema al proyecto

        // crear un marcador de problema que se mostrará en la vista de problemas
        int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
        manager.generateMarker(resource, lineNumber, message, severity, null);
        return true;
    }
}

En primer lugar, la línea se compara con la expresión regular, si no coincide se devuelve false. Esto indica a ErrorParserManager que este analizador de errores no ha reconocido la línea. Cuando esto suceda, ErrorParserManager enviará la línea al siguiente analizador de errores de la secuencia.

Si la línea coincide, entonces es tarea del analizador de errores crear un "marcador de problema" que Eclipse mostrará al usuario. En este ejemplo se utiliza la captura de grupos para extraer la información de la línea. Consulte en los javadocs la clase java.util.regex.Pattern para obtener una descripción detallada de las expresiones regulares y la captura de grupos. También, si no desea utilizar expresiones regulares, la clase String contiene varios métodos útiles para el análisis de Strings, así como la clase java.util.StringTokenizer.

El siguiente paso consiste en encontrar un IResource que coincida con el nombre de archivo del mensaje de error. Un objeto IResource representa un archivo o un directorio en el espacio de trabajo de Eclipse. (Para obtener más información, consulte en los javadocs la interfaz org.eclipse.core.resources.IResource). ErrorParserManager tiene algunos métodos útiles para convertir nombres de archivo en objetos IResource. Si no se puede encontrar un IResource que coincida con el nombre de archivo, podemos tomar como valor predeterminado el propio proyecto en sí.

Una vez se ha calculado esta información, se utiliza el método generateMarker() para crear un objeto de marcador de problema. La interfaz org.eclipse.cdt.core.IMargerGenerator contiene constantes para los distintos niveles de gravedad. En este ejemplo, el analizador de errores sólo genera marcadores con una gravedad de error; no obstante, un analizador de errores real probablemente también generaría marcadores de aviso y de información.

Cuando desarrollo un analizador de errores personalizado real, probablemente encontrará muy conveniente ejecutar IBM Rational Developer para Power Systems Software en el depurador de Eclipse. El depurador de Eclipse es capaz de "intercambiar en caliente" archivos de clase. Esto significa que puede efectuar cambios en el código del analizador de errores y no es necesario reiniciar el depurador para que dicho cambio entre en vigor. Cuando efectúe un cambio y guarde el archivo, Eclipse recompilará automáticamente el código y cargará la nueva versión de la clase en la instancia en ejecución de IBM Rational Developer para Power Systems Software.

Si el analizador de errores genera correctamente marcadores de problemas, los verá aparecer en el Explorador de proyectos, la Vista Problemas y en el editor.

Marcadores de problemas generados por un analizador de errores


Desplegar el conector

Una vez esté completado el analizador de errores, es el momento de compilar y distribuir el conector. Este proceso es en realidad muy sencillo. Pulse con el botón derecho del ratón el proyecto y seleccione Exportar. A continuación, en el asistente Exportar, seleccione Desarrollo de conectores > Conectores y fragmentos desplegables y pulse Siguiente.

Asistente Exportar

En la segunda página del asistente, simplemente seleccione el conector, seleccione un destino de exportación y pulse Finalizar.

Asistente Exportar

En la ubicación que ha seleccionado encontrará una carpeta llamada plugins y en dicha carpeta encontrará un archivo jar que contiene el conector. Simplemente copie este archivo en la carpeta plugins de la carpeta SDPShared de su instalación de IBM Rational Developer para Power Systems Software e inícielo como de costumbre. El último paso consiste en habilitar el analizador de errores en las propiedades del proyecto.

Página de propiedades de analizadores de problemas

IBM Rational Developer para Power Systems Software reconocerá la salida de la herramienta de compilación personalizada.