¿Cómo puedo hacer que mi acción de nodo de sintaxis de diagnóstico de código funcione en archivos cerrados?


Estoy construyendo un conjunto de diagnósticos de código usando Roslyn (en VS2015 Preview). Idealmente, me gustaría que los errores que producen actuaran como errores persistentes, como si estuviera violando una regla de lenguaje normal.

Hay un montón de opciones, pero estoy teniendo dificultades para conseguir que cualquiera de ellas funcione de manera consistente. He logrado implementar una acción de nodo de sintaxis rudimentaria, es decir, una registrada con

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);

En el método Initialize de mi clase de diagnóstico. He aquí, cuando abro un archivo que viola este diagnóstico (mientras ejecuta el proyecto VSIX), VS2015 muestra un error:

  • Garabato rojo bajo el bit correcto de código
  • bloque Rojo en el margen
  • Error en la lista de errores

Sin embargo, el error desaparece cuando cierro el archivo.

También he intentado usar context.RegisterCompilationEndAction, pero esto tiene dos problemas:

  • Parece disparar inconsistentemente. Normalmente cuando abro la solución se dispara, pero no siempre. No fuego en una limpieza / reconstrucción, que parece extraño.
  • Aunque los diagnósticos creados directamente en el método de análisis fuego, con el fin de implementar los diagnósticos estoy utilizando un visitante, como este-que puede ser inepto:

    private static void AnalyzeEndCompilation(CompilationEndAnalysisContext context)
    {
        foreach (var tree in context.Compilation.SyntaxTrees)
        {
            var visitor = new ReportingVisitor(context.Compilation.GetSemanticModel(tree));
            visitor.Visit(tree.GetRoot());
            foreach (var diagnostic in visitor.Diagnostics)
            {
                context.ReportDiagnostic(diagnostic);
            }
        }
    }
    

    Sé que se están creando los diagnósticos - un punto de interrupción en la línea ReportDiagnostic se golpea varias veces - pero no veo nada en la lista de errores. (Mientras que una llamada similar ReportDiagnostic al inicio del método, o una por árbol de sintaxis con la ruta del archivo, se muestra.)

¿Qué estoy haciendo mal aquí? El primer enfoque (una acción de nodo de sintaxis) sería ideal si fuera factible - me da exactamente el contexto que necesito. ¿Hay alguna configuración en las propiedades del proyecto que necesito para hacer que el compilador la use para la compilación "proyecto completo", así como para el manejo interactivo" en el IDE"? ¿Es esto quizás solo un poco de integración de Roslyn que aún no está terminada?

(Puedo incluir el código completo para la clase si fuera útil, en este caso sospecho que sería más ruido que señal.)

Author: Jon Skeet, 2014-12-08

1 answers

Para los problemas de archivo cerrado, nuestra intención es que todos los diagnósticos sean reportados, ya sea desde archivos abiertos o cerrados. Hay una opción de usuario para ello en la vista previa en Herramientas\Opciones\Editor de texto\C#\Avanzado que puede alternar para incluir diagnósticos en archivos cerrados. Esperamos que este sea el valor predeterminado antes de que se lance VS 2015. Sin embargo, tenga en cuenta que la opción solo se aplica al análisis dentro de VS. Si su analizador se pasa al compilador (agregando un analizador en el Explorador de soluciones o agregando una referencia de paquete NuGet a un paquete con un analizador, en lugar de instalar un VSIX en Visual Studio), entonces el compilador reportará todos los diagnósticos cuando el usuario compila, independientemente de si los archivos están abiertos o no.

Para el segundo problema con RegisterCompilationEndedAnalyzer, no se llama de forma fiable dentro de Visual Studio en la vista previa VS 2015. Esto se debe a que hacemos algunas optimizaciones para evitar volver a analizar todo para los cambios "locales" dentro de los cuerpos de los métodos. Por razones similares, nosotros actualmente no reporte errores que se reportan con ubicaciones en los cuerpos de los métodos. Recientemente hemos cambiado eso para que VS inicie un re-análisis completo después de un retraso más largo, por lo que RegisterCompilationEndedAnalyzer debería ser llamado de manera confiable en futuras compilaciones, y reportaremos errores independientemente de la ubicación.

Sin embargo, para su caso lo correcto es quedarse con un SyntaxNodeAnalyzer, cambiar la opción VS para habilitar diagnósticos en archivos cerrados y adjuntar su diagnóstico al proyecto opciones de compilación.

Espero que esto ayude!

 43
Author: Kevin Pilch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-08 20:37:28