2015-04-06 93 views
5

我有一个包含一些类文件的c#解决方案。借助Roslyn,我能够解析解决方案以获得解决方案中的项目列表。从那里,我可以在每个项目中获得文件。然后,我可以得到每个ClassDeclarationSyntax的列表。 这是出发点。Roslyn:如何使用Roslyn C获得DeclarationSyntax的命名空间#

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

从这些对象我希望能够让每个类中使用的变量的命名空间。见文件1有一个方法“getBar()”,它返回一个B.Bar类型的对象。命名空间很重要,因为它告诉你真正返回哪种类型的Bar。

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

的问题是,我不知道^ h从我现在在代码中的位置获取名称空间值。有任何想法吗?

+0

你应该是'await'ing这些电话。 – SLaks

+0

请注意嵌套类型。 – SLaks

回答

5

的命名空间是语义信息,所以你需要从语义模型得到它:

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

不知道你刚刚提到什么,因为在TypeInfo和ContainingNamespace之间似乎有一个缺失的步骤(也许我缺少一个扩展?),但我目前使用此代码来获取当前类的名称空间。 问题是,这只适用于派生SemanticModel的文档中定义的对象/类。当你想获得当前Document实例中没有定义的对象的命名空间时,它会变得有点棘手。 – Pangamma

+0

挂上@Slaks。我有一个关于如何解决这个问题的理论。这有点哈克,但它应该工作。如果Type的命名空间中包含命名空间,则假定命名空间100%准确。如果类型字符串中没有句点,则假定它需要与命名空间匹配。遍历文档顶部的每个“using”声明并尝试使用“+ typeNameString>加载每个<”。如果任何这些选项可以加载,你可以假设你找到了一个匹配。如果它有效,我会稍微发布代码。 – Pangamma

+0

@泰勒:哎呀;那应该是'.Type'。 – SLaks

相关问题