枚举程序集中的命名空间

4
我正在尝试枚举程序集中声明的所有命名空间。 像这样做感觉非常不优雅:
foreach (var syntaxTree in context.Compilation.SyntaxTrees)
{
    foreach (var ns in syntaxTree.GetRoot(context.CancellationToken).DescendantNodes().OfType<NamespaceDeclarationSyntax>())
    {
        ...         
    }
}

有什么好的方法可以做到这一点吗? 使用树遍历器可能会更好,但是在此之前先进行询问,因为我有一种感觉,这已经在符号API中某个地方存在。


那属于代码审查。 - Felix K.
9
不,这是关于Roslyn API的问题。 - Johan Larsson
2个回答

7

找到了一种使用 编译 的方法,但感觉像是一个hack。

var namespaceSymbols = context
    .Compilation
    .GetSymbolsWithName(x => !string.IsNullOrEmpty(x), SymbolFilter.Namespace)
    .Cast<INamespaceSymbol>();

7

调用 compilation.Assembly.GlobalNamespace 将会给你一个合并的根命名空间,其中包含在源代码中定义的所有命名空间。调用 compilation.GlobalNamespace 将会给你一个根命名空间,其中包含在源代码或引用的元数据中定义的所有命名空间和类型。

从那里开始,您需要递归调用 GetNamespaceMembers 以获取所有命名空间符号:

IEnumerable<INamespaceSymbol> GetAllNamespaces(INamespaceSymbol namespaceSymbol)
{
    foreach (INamespaceSymbol symbol in namespaceSymbol.GetNamespaceMembers())
    {
        yield return symbol;
        foreach (INamespaceSymbol childSymbol in GetAllNamespaces(symbol))
        {
            yield return symbol;
        }
    }
}

var allNamespaceNodes = new List<NamespaceDeclarationSyntax>();
foreach (INamespaceSymbol namespaceSymbol in GetAllNamespaces(compilation.GlobalNamespace))
{
    allNamespaceNodes.AddRange(from syntaxReference in namespaceSymbol.DeclaringSyntaxReferences
                                select syntaxReference.GetSyntax(cancellationToken) as NamespaceDeclarationSyntax);
}

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