Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate namespaces in assembly

Tags:

c#

roslyn

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.

like image 775
Johan Larsson Avatar asked Dec 08 '22 20:12

Johan Larsson


1 Answers

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);
}
like image 116
Jonathon Marolf Avatar answered Dec 26 '22 12:12

Jonathon Marolf