2014-12-08 8 views
69

Sto costruendo un set di diagnostica del codice utilizzando Roslyn (in Anteprima VS2015). Idealmente, mi piacerebbe che tutti gli errori che producevano agissero come errori persistenti, proprio come se stessi violando una normale regola del linguaggio.Come posso fare in modo che l'azione del nodo di sintassi diagnostica del mio codice funzioni su file chiusi?

Ci sono un sacco di opzioni, ma sto facendo fatica a farle funzionare in modo coerente. Sono riuscito a realizzare un rudimentale azione nodo di sintassi, vale a dire uno registrato con

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression); 

nel metodo della mia classe diagnostica Initialize. Ed ecco, quando apro un file che viola questa diagnostica (durante l'esecuzione del progetto di VSIX), VS2015 mostra un errore:

  • rosso scarabocchio sotto la giusta porzione di codice
  • blocco rosso nel margine
  • Problemi con la lista degli errori

Tuttavia, l'errore va via quando chiudo il file.

Ho provato con context.RegisterCompilationEndAction pure, ma questo ha due problemi:

  • Sembra di sparare in modo incoerente. Solitamente quando apro la soluzione, si spara, ma non sempre. Non sparerà su un clean/rebuild, il che sembra strano.
  • Anche se la diagnostica creati direttamente nel metodo di analisi del fuoco, al fine di attuare la diagnostica che sto usando un visitatore, come questo - che può essere inetta:

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

    So che la diagnostica sono in fase di creazione - un punto di interruzione sulla linea ReportDiagnostic viene colpito più volte, ma non vedo nulla nell'elenco degli errori. (Considerando che un simile ReportDiagnostic chiamata all'inizio del metodo, o uno per ogni albero di sintassi con il percorso del file, fa ottenere mostrato.)

Che cosa sto facendo male qui? Il primo approccio (un'azione del nodo di sintassi) sarebbe ideale se possibile: mi fornisce esattamente il contesto di cui ho bisogno. C'è qualche impostazione nelle proprietà del progetto che ho bisogno di far usare al compilatore per la compilazione del "progetto completo" e solo per la gestione interattiva "in IDE"? Questo forse è solo un po 'dell'integrazione di Roslyn, che non è ancora del tutto finita?

(posso includere il codice completo per la classe se sarebbe utile -. In questo caso ho il sospetto che sarebbe stato più rumore di segnale però)

+1

Da quello che ho capito in un discorso "RegisterCompilationEndAction' è davvero quello che ti serve e il fatto che si accenda in modo incoerente è un bug. Spedirò l'oratore e chiederò. –

risposta

43

Per i problemi di file chiusi, è il nostro intento che tutti la diagnostica verrà segnalata, da file aperti o chiusi. È disponibile un'opzione utente nell'anteprima in Strumenti \ Opzioni \ Editor di testo \ C# \ Avanzato che è possibile alternare per includere la diagnostica nei file chiusi. Speriamo di rendere questo predefinito prima che VS 2015 sia rilasciato. Tuttavia, si noti che l'opzione si applica solo all'analisi all'interno di VS. Se l'analizzatore viene passato al compilatore (aggiungendo un analizzatore in Esplora soluzioni o aggiungendo un riferimento a un pacchetto NuGet con un analizzatore, invece di installare un VSIX in Visual Studio), il compilatore segnalerà diagnostics quando l'utente costruisce, indipendentemente dal fatto che i file siano aperti o meno.

Per il secondo problema con RegisterCompilationEndedAnalyzer, non è chiamato in modo affidabile all'interno di Visual Studio in VS 2015 Preview. Questo perché eseguiamo alcune ottimizzazioni per evitare di ri-analizzare tutto per modifiche "locali" all'interno dei corpi dei metodi. Per ragioni analoghe, al momento non segnaliamo gli errori segnalati con le posizioni nei corpi dei metodi. Di recente abbiamo modificato questo aspetto in modo che VS possa avviare una nuova analisi completa dopo un ritardo più lungo, pertanto RegisterCompilationEndedAnalyzer deve essere richiamato in modo affidabile nelle versioni future e verranno segnalati errori indipendentemente dalla posizione.

Tuttavia, per il tuo caso la cosa corretta da fare è stare con un SyntaxNodeAnalyzer, cambiare l'opzione VS per abilitare la diagnostica in file chiusi e allegare la tua diagnostica alle opzioni di compilazione del progetto.

Spero che questo aiuti!

+2

Aha: la parte della posizione spiegherebbe sicuramente le stranezze che stavo vedendo. Il mio sistema di diagnostica "basta controllare che riesca a far funzionare qualcosa" non aveva una posizione, quindi quelli mostrati ... e l'opzione per la diagnostica in file chiusi ha funzionato perfettamente. Grazie! Torna a fare la diagnostica stessa fare la cosa giusta ora :) –

+0

Hai visto la nota sull'utilizzo della diagnostica allegata al progetto per farli anche costruire in riga di comando? –

+0

Sì. Finché sono sulla strada giusta per farlo più tardi, posso scommetterci per ora :) –

Problemi correlati