Johan Larsson Johan Larsson - 1 month ago 18
C# Question

Enumerate namespaces in assembly

I'm trying to enumerate all namespaces declared in an assembly.
Doing something like this feels very inelegant:

foreach (var syntaxTree in context.Compilation.SyntaxTrees)
{
foreach (var ns in syntaxTree.GetRoot(context.CancellationToken).DescendantNodes().OfType<NamespaceDeclarationSyntax>())
{
...
}
}


What is the nice way to do this?
A tree walker will be a bit nicer but asking before as I have a feeling this is already in the symbol API somewhere.

Answer

Calling compilation.Assembly.GlobalNamespace will give you the the merged root namespace that contains all namespaces defined in source. Calling compilation.GlobalNamespace will give you the root namespace that contains all namespaces and types defined in source code or in referenced metadata.

From there you would need to recursively call GetNamespaceMembers to get all the namespace symbols:

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