2015-04-06 15 views
5

Mam rozwiązanie C#, które zawiera niektóre pliki klas. Dzięki Roslyn mogę przeanalizować rozwiązanie, aby uzyskać listę projektów w ramach rozwiązania. Stamtąd mogę uzyskać dokumenty w każdym projekcie. Następnie mogę uzyskać listę wszystkich ClassDeclarationSyntax. To jest punkt wyjścia.Roslyn: Jak uzyskać Przestrzeń Nazw DeklaracjiSyntax z 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); 
       } 
      } 
     } 

Z tych obiektów, które chcę, aby być w stanie uzyskać przestrzeń nazw zmiennych wykorzystywanych w każdej klasie. Zobacz plik 1 zawiera metodę "getBar()", która zwraca obiekt typu B.Bar. Przestrzeń nazw jest ważna, ponieważ informuje o tym, jaki rodzaj paska rzeczywiście jest zwracany.

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(){ 
    } 
} 

Kwestia jest taka, że ​​nie jestem pewien h ow, aby dostać się do wartości Namespace, skąd jestem teraz w kodzie. Jakieś pomysły?

+0

powinny być 'await'ing tych połączeń. – SLaks

+0

Uważaj na typy zagnieżdżone. – SLaks

Odpowiedz

5

Przestrzeń nazw jest semantyczny informacji, więc trzeba je zdobyć z semantycznego modelu

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

Nie jestem pewien, co właśnie wspomniałeś, ponieważ wydaje się, że brakuje kroku między TypeInfo i ContainingNamespace (może brakuje mi rozszerzenia?), Ale obecnie używam tego kodu, aby uzyskać przestrzeń nazw dla bieżącej klasy. Problem polega na tym, że działa to tylko dla obiektu/klas zdefiniowanych w dokumencie, z którego pochodzi SemanticModel. Jeśli chcesz uzyskać obszar nazw dla obiektu, który nie jest zdefiniowany w bieżącej instancji dokumentu, staje się nieco trudniejszy. – Pangamma

+0

Trzymaj się, @Slaks. Mam teorię, jak rozwiązać ten problem. To trochę hacky, ale powinno działać. Jeśli typ zawiera przestrzenie nazw zawarte w łańcuchu nazw, załóżmy, że przestrzeń nazw jest w 100% dokładna. Jeśli ciąg znaków nie zawiera żadnych kropek, należy założyć, że musi on być dopasowany do przestrzeni nazw. Iteruj przez każdą z deklaracji "using" na górze dokumentu i spróbuj załadować każdy <"using" + typeNameString>. Jeśli którakolwiek z tych opcji może zostać załadowana, możesz założyć, że znalazłeś dopasowanie. Opublikuję kod, jeśli zadziała. – Pangamma

+0

@Taylor: Ups; to powinno być '.Type'. – SLaks