2015-04-06 14 views
5

Ho una soluzione C# che contiene alcuni file di classe. Con Roslyn sono in grado di analizzare una soluzione per ottenere un elenco di progetti all'interno della soluzione. Da lì, posso ottenere i documenti in ogni progetto. Quindi, posso ottenere un elenco di ogni ClassDeclarationSyntax. Questo è il punto di partenza.Roslyn: come ottenere lo spazio dei nomi di una dichiarazioneSintassi con Roslyn C#

 foreach (var v in _solution.Projects) 
     { 
      //Console.WriteLine(v.Name.ToString()); 
      foreach (var document in v.Documents) 
      { 
       SemanticModel model = document.GetSemanticModelAsync().Result; 
       var classes = document.GetSyntaxRootAsync().Result.DescendantNodes().OfType<ClassDeclarationSyntax>(); 
       foreach(var cl in classes) 
       { 
// Starting around this point... 
        ClassDiagramClass cls = new ClassDiagramClass(cl, model); 
        diagramClasses.Add(cls); 
       } 
      } 
     } 

Da questi oggetti che voglio essere in grado di ottenere lo spazio dei nomi delle variabili utilizzate all'interno di ogni classe. Vedi il file 1 ha un metodo "getBar()" che restituisce un oggetto di tipo B.Bar. Lo spazio dei nomi è importante perché ti dice quale tipo di Barra viene effettivamente restituito.

File1.cs

using B; 
namespace A { 
    public class foo(){ 
     public Bar getBar(){ return new Bar();} 
    } 
} 

File2.cs

namespace B { 
    public class Bar(){ 
    } 
} 

File3.cs

namespace C { 
    public class Bar(){ 
    } 
} 

Il problema è che io non sono sicuro h ow per ottenere il valore Namespace da dove sono nel codice in questo momento. Qualche idea?

+0

si dovrebbe essere 'await'ing quelle chiamate. – SLaks

+0

Attenzione ai tipi annidati. – SLaks

risposta

5

Lo spazio dei nomi è l'informazione semantica, quindi è necessario ottenere dal modello semantico:

model.GetTypeInfo(cl).Type.ContainingNamespace 
+0

Non sei sicuro di ciò che hai appena menzionato poiché sembra esserci un passaggio mancante tra TypeInfo e ContainingNamespace (Forse mi manca un'estensione?), Ma attualmente sto utilizzando questo codice per ottenere lo spazio dei nomi per la classe corrente. Il problema è che questo funziona solo per gli oggetti/classi definiti all'interno del documento da cui è stato derivato il SemanticModel. Quando si desidera ottenere lo spazio dei nomi per un oggetto che non è definito all'interno dell'istanza del documento corrente, diventa un po 'più complicato. – Pangamma

+0

Attendi, @Slaks. Ho una teoria su come risolvere questo. È un po 'hacky, ma dovrebbe funzionare. Se il Tipo ha spazi dei nomi inclusi nella sua stringa di denominazione, si supponga che lo spazio dei nomi sia accurato al 100%. Se la stringa del tipo non contiene punti, supponiamo che debba essere abbinata a uno spazio dei nomi. Esaminare ciascuna delle dichiarazioni "using" nella parte superiore del documento e provare a caricare ogni <"utilizzando" + typeNameString>. Se una di queste opzioni può essere caricata, puoi presumere di aver trovato una corrispondenza. Inserirò il codice in un po 'se funziona. – Pangamma

+0

@Taylor: Oops; che dovrebbe essere '.Type'. – SLaks