2014-12-08 11 views
69

Ich baue eine Reihe von Codediagnosen mit Roslyn (in VS2015 Preview). Idealerweise möchte ich, dass alle Fehler, die sie erzeugen, als persistente Fehler auftreten, so als ob ich gegen eine normale Sprachregel verstoßen würde.Wie kann ich meine Code-Diagnose-Syntax-Node-Aktion an geschlossenen Dateien arbeiten lassen?

Es gibt eine Reihe von Optionen, aber ich habe es schwer, eine von ihnen konsequent zu arbeiten. Ich habe es geschafft, eine rudimentäre Syntax Knoten Aktion, das heißt ein mit

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression); 

im Initialize Methode meiner Diagnoseklasse registriert zu implementieren. Und siehe da, wenn ich eine Datei öffnen, das diese Diagnose verletzt (während des VSIX Projekt läuft), VS2015 zeigt einen Fehler:

  • Red Kringel unter dem rechten Stück Code
  • Red Block am Rande
  • Fehler in der Fehlerliste

Allerdings geht der Fehler weg, wenn ich die Datei schließen.

Ich habe versucht, context.RegisterCompilationEndAction auch verwenden, aber dies hat zwei Probleme:

  • Es inkonsequent zu schießen scheint. Normalerweise wenn ich die Lösung öffne es feuert, aber nicht immer. Es feuert nicht auf eine saubere/Wiederherstellung, die seltsam scheint.
  • Obwohl Diagnose erstellt direkt in der Analysemethode Feuer, um die Diagnose zu implementieren ich einen Besucher bin mit, wie diese - die unfähigen sein kann:

    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); 
         } 
        } 
    } 
    

    Ich weiß, dass die Diagnostik erstellt werden - ein Breakpoint auf der ReportDiagnostic Zeile wird mehrmals getroffen - aber ich sehe nichts in der Fehlerliste. (Während eines ähnlichen ReportDiagnostic Anrufs zu Beginn des Verfahrens oder eines pro Syntaxbaum mit dem Dateipfad, tut gezeigt zu bekommen.)

Was mache ich falsch hier? Der erste Ansatz (eine Syntax-Node-Aktion) wäre ideal, wenn möglich - er gibt mir genau den Kontext, den ich brauche. Gibt es eine Einstellung in den Projekteigenschaften, die ich brauche, damit der Compiler das Kompilieren des vollständigen Projekts und nur das interaktive Handling in der IDE verwendet? Ist das vielleicht nur ein bisschen Roslyn-Integration, die noch nicht ganz fertig ist?

(Ich kann den vollständigen Code für die Klasse enthalten, wenn es sinnvoll wäre -. In diesem Fall vermute ich, es würde als Signal mehr Lärm aber sein)

+1

Von was ich bei einem Vortrag 'RegisterCompilationEndAction' verstanden habe, ist in der Tat, was Sie brauchen und die Tatsache, dass es inkonsistent löscht, ist ein Fehler. Ich maile dem Sprecher und frage. –

Antwort

43

Für die geschlossene Datei Probleme, dann ist es unsere Absicht, dass alle Die Diagnose wird aus offenen oder geschlossenen Dateien gemeldet. Es gibt eine Benutzeroption in der Vorschau unter Extras \ Optionen \ Texteditor \ C# \ Erweitert, die Sie umschließen können, um die Diagnose in geschlossene Dateien einzuschließen. Wir hoffen, dass dies zum Standard wird, bevor VS 2015 veröffentlicht wird. Beachten Sie jedoch, dass die Option nur für die Analyse in VS gilt. Wenn der Analysator an den Compiler übergeben wird (durch Hinzufügen eines Analysators im Projektmappen-Explorer oder Hinzufügen eines NuGet-Paketverweises zu einem Paket mit einem Analysator im Gegensatz zum Installieren eines VSIX in Visual Studio), meldet der Compiler alle Diagnosen wenn der Benutzer erstellt, unabhängig davon, ob die Dateien geöffnet sind oder nicht.

Für das zweite Problem mit RegisterCompilationEndedAnalyzer wird es nicht zuverlässig in Visual Studio in der VS 2015 Preview aufgerufen. Das liegt daran, dass wir einige Optimierungen vornehmen, um zu vermeiden, dass alles für "lokale" Änderungen in Methodenkörpern neu analysiert wird. Aus ähnlichen Gründen melden wir derzeit keine Fehler, die mit Standorten in Methodenkörper gemeldet werden. Wir haben das kürzlich geändert, sodass VS nach einer längeren Verzögerung eine vollständige Neuanalyse starten wird. Daher sollte RegisterCompilationEndedAnalyzer in zukünftigen Builds zuverlässig aufgerufen werden, und wir werden Fehler unabhängig vom Standort melden.

In Ihrem Fall ist es jedoch die richtige Sache, mit einem SyntaxNodeAnalyzer zu bleiben, die Option VS zu wechseln, um die Diagnose in geschlossenen Dateien zu aktivieren und Ihre Diagnose an die Projektkompilierungsoptionen anzuhängen.

Hoffe, das hilft!

+2

Aha - der Ort Teil würde definitiv die Kuriositäten erklären, die ich sah. Meine "nur überprüfen, dass ich etwas arbeiten kann" Diagnose hatte keinen Speicherort, so dass diese angezeigt wurden ... und die Option für die Diagnose in geschlossenen Dateien funktionierte perfekt. Vielen Dank! Zurück zum Machen der Diagnose selbst mach das richtige Ding :) –

+0

Hast du den Hinweis über die Verwendung der Projekt angehängten Diagnose gelesen, um sie in die Befehlszeile zu bringen? –

+0

Ja. Solange ich auf dem richtigen Weg bin, um das später zu tun, kann ich es jetzt noch tun :) –

Verwandte Themen