Ich erstelle eine Reihe von Codediagnosen mit Roslyn (in der VS2015-Vorschau). Im Idealfall möchte ich, dass alle Fehler, die sie erzeugen, als dauerhafte Fehler wirken, als würde ich gegen eine normale Sprachregel verstoßen.
Es gibt eine Reihe von Optionen, aber es fällt mir schwer, eine davon konsequent zum Laufen zu bringen. Ich habe es geschafft, eine rudimentäre Syntaxknotenaktion zu implementieren, dh eine, bei der registriert ist
context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);
in der Initialize
Methode meiner diagnostischen Klasse. Siehe da, wenn ich eine Datei öffne, die gegen diese Diagnose verstößt (während das VSIX-Projekt ausgeführt wird), zeigt VS2015 einen Fehler an:
- Rotes Kringel unter dem rechten Code
- Roter Block am Rand
- Fehler in der Fehlerliste
Der Fehler verschwindet jedoch, wenn ich die Datei schließe.
Ich habe es auch versucht context.RegisterCompilationEndAction
, aber das hat zwei Probleme:
- Es scheint uneinheitlich zu feuern. Wenn ich die Lösung öffne, wird sie normalerweise ausgelöst, aber nicht immer. Es wird nicht bei einem Clean / Rebuild ausgelöst, was seltsam erscheint.
Obwohl die direkt in der Analysemethode erstellte Diagnose ausgelöst wird, verwende ich zur Implementierung der Diagnose einen Besucher wie diesen - was möglicherweise unpassend ist:
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 Diagnose erstellt wird - ein Haltepunkt in der
ReportDiagnostic
Zeile wird mehrmals getroffen -, aber ich sehe nichts in der Fehlerliste. (Während eines ähnlichenReportDiagnostic
Anrufs zu Beginn des Verfahrens oder eines pro Syntaxbaum mit der Pfaddatei, nicht gezeigt bekommen.)
Was mache ich hier falsch? Der erste Ansatz (eine Syntaxknotenaktion) wäre ideal, wenn er machbar wäre - er gibt mir genau den Kontext, den ich brauche. Gibt es in den Projekteigenschaften einige Einstellungen, die der Compiler für die Kompilierung des "vollständigen Projekts" sowie für die interaktive Verarbeitung "in der IDE" verwenden muss? Ist das vielleicht nur ein bisschen Roslyn-Integration, die noch nicht ganz fertig ist?
(Ich kann den vollständigen Code für die Klasse einfügen, wenn dies nützlich wäre. In diesem Fall vermute ich jedoch, dass es mehr Rauschen als Signal ist.)
RegisterCompilationEndAction
ist es in der Tat das, was Sie brauchen, und die Tatsache, dass es uneinheitlich ausgelöst wird, ist ein Fehler. Ich werde dem Sprecher eine E-Mail senden und fragen.