2015-09-14 11 views
6

Sto provando a programmare un analizzatore di codici che cerca tipi non referenziati da nessun altro tipo nella soluzione di Visual Studio 2015.Analizzatore di codice di Visual Studio: ricerca di tipi con riferimenti zero

Il mio problema è che non riesco a capire come trovare l'elenco dei tipi non referenziati.

Ho provato attraverso il DOM come potete vedere dal codice sottostante, ma non so dove navigare e il codice attuale sembra già lento.

using Microsoft.CodeAnalysis; 
using Microsoft.CodeAnalysis.CSharp; 
using Microsoft.CodeAnalysis.CSharp.Syntax; 
using Microsoft.CodeAnalysis.Diagnostics; 
using System.Collections.Immutable; 
using System.Linq; 

namespace AlphaSolutions.CodeAnalysis 
{ 
    [DiagnosticAnalyzer(LanguageNames.CSharp)] 
    public class ZeroReferencesDiagnosticAnalyzer : DiagnosticAnalyzer 
    { 
     public const string DiagnosticId = "ZeroReferences"; 

     private static DiagnosticDescriptor rule = new DiagnosticDescriptor(
      DiagnosticId, 
      title: "Type has zero code references", 
      messageFormat: "Type '{0}' is not referenced within the solution", 
      category: "Naming", 
      defaultSeverity: DiagnosticSeverity.Warning, 
      isEnabledByDefault: true, 
      description: "Type should have references." 
      ); 

     public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics 
     { 
      get 
      { 
       return ImmutableArray.Create(rule); 
      } 
     } 

     public override void Initialize(AnalysisContext context) 
     { 
      context.RegisterSyntaxNodeAction(this.AnalyzeSyntaxNode, SyntaxKind.ClassDeclaration); 
     } 

     private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext obj) 
     { 
      var classDeclaration = obj.Node as ClassDeclarationSyntax; 
      if(classDeclaration == null) 
      { 
       return; 
      } 

      var identifierNameSyntaxes = classDeclaration 
       .DescendantNodes() 
       .OfType<IdentifierNameSyntax>() 
       .ToArray() 
       ; 
      if (identifierNameSyntaxes.Length == 0) 
      { 
       return; 
      } 

      //SymbolFinder.FindReferencesAsync(namedTypeSymbol, solution); 
     } 
    } 
} 

ho anche provato SymbolFinder.FindReferencesAsync(namedTypeSymbol, solution) ma non riesco a capire come ottenere un riferimento a Solution.

Una risposta su Microsoft Answers suggerisce anche l'utilizzo del metodo FindReferences dall'assembly Roslyn.Services. Ma sembra che l'assemblaggio sia deprecato.

Conosco CodeLens Contando i riferimenti, ottenere l'accesso a quel contatore potrebbe essere una soluzione ancora migliore ma suppongo che sia impossibile.

Prima che qualcuno suggerisca un post duplicato, questo post NON è un duplicato di this, this o this. Il mio post è specifico per gli analizzatori per il compilatore di Roslyn.

risposta

5

Gli analizzatori diagnostici Roslyn attualmente non consentono di eseguire analisi a livello di soluzione (ad esempio cross-project), motivo per cui non forniamo un oggetto Solution. Ciò era parzialmente dovuto alle considerazioni sulle prestazioni: se si tentasse di chiamare FindReferencesAsync ovunque la tua CPU sarebbe stata pesantemente ancorata. Per CodeLens c'era una grande quantità di feedback su quanta CPU stavamo usando, non volevamo che 10 diagnostici consumassero tutta la stessa quantità di CPU. (Immagina la tua povera batteria del portatile ...)

Se stai bene con questo essere più limitato, ad esempio trovare i tipi interni che non sono utilizzati nel progetto in cui si trovano, dai un'occhiata a this analyzer we wrote awhile back.

+0

Il codice dell'analizzatore che hai collegato sembra molto interessante anche se non sono sicuro di quale tipo di ambito interno ti riferisci. Sono accessibilità al codice, progetti, assembly larghi, non referenziati e progetti di condivisione non condivisi? –

+0

Contrassegna solo i tipi che possono essere determinati inutilizzati in un singolo progetto. Quindi contrassegna i tipi o i membri privati ​​o interni. I tipi pubblici non verranno contrassegnati, poiché non possono trovare riferimenti in un progetto diverso. –

+0

E per Roslyn la nostra definizione di "progetto" è in realtà "invocazione del compilatore". Per i progetti condivisi, quelli funzionano contribuendo con i file in due o più progetti "reali" che compilano effettivamente le cose. Quindi sta analizzando quei progetti "reali", con i file condivisi inclusi. –

Problemi correlati