Roslyn:如何使用Roslyn C#获取DeclarationSyntax的命名空间

8
我有一个包含一些类文件的C#解决方案。使用Roslyn,我能够解析解决方案以获取解决方案内项目的列表。从那里,我可以获取每个项目中的文档。然后,我可以获取每个ClassDeclarationSyntax的列表。这是起点。
        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(){
    }
}

问题在于我不确定如何从当前代码中获取命名空间的值。有什么想法吗?

你应该使用 await 等待这些调用。 - SLaks
注意嵌套类型。 - SLaks
1个回答

10

命名空间是语义信息,因此您需要从语义模型中获取它:

model.GetTypeInfo(cl).Type.ContainingNamespace

我不确定你刚才提到的内容,因为TypeInfo和ContainingNamespace之间似乎缺少一步(也许是我漏掉了一个扩展?),但我目前正在使用此代码获取当前类的命名空间。问题在于,这仅适用于在SemanticModel派生自的文档中定义的对象/类。当您想要获取并非在当前Document实例中定义的对象的命名空间时,它会变得有点棘手。 - Pangamma
@Taylor:糟糕,应该是.Type - SLaks
1
@Taylor:SemanticModel 应该为文档中的每个符号提供完整的类型信息。如果您的符号来自其他地方,还有其他 API 可以使用。您不需要进行任何骚操作。 - SLaks
可能会接受您的答案,因为您肯定是在这方面最有帮助的人。我的解决方案确实有效,但我仍然对您提到的其他API感到好奇。我很想使用已建立的API,而不是自己的解决方案,因为当查找对System....Exception类的引用时,我的解决方案无法正常工作。您还记得那些API的名称或链接吗? - Pangamma
1
@Taylor:你要找的是Compilation.GetTypeByMetadataName。http://source.roslyn.io/#Microsoft.CodeAnalysis/Compilation/Compilation.cs,836 - SLaks
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接