Skip to content

[Question] How do I get all the INamedTypeSymbols in a given compilation? #6138

Closed
@JoshVarty

Description

@JoshVarty

I've been trying this for about 45 minutes now, but I can't seem to figure out how to get a list of all of the INamedTypeSymbol available in a given compilation. I tried digging through the Compilation.GetTypeByMetadataName stuff, but couldn't figure it out.

I tried using Compilation.GlobalNamespace.GetTypeMembers() and it seems to give me all the IModuleSymbols that are referenced by the current project. (I see mscorlib, System.Core etc.) I then tried getting the type members inside these modules, but they were either empty or contained PrivateImplementation stuff.

Is there an API to get access to all the INamedTypeSymbols available in a compilation?

Activity

SLaks

SLaks commented on Oct 19, 2015

@SLaks
Contributor

You need to recurse through all of the namespaces in the global namespace

daveaglick

daveaglick commented on Oct 19, 2015

@daveaglick
Contributor

Yep - I've found the easiest way to do the recursion is with a SymbolVisitor:

// Main code
CSharpCompilation compilation = CSharpCompilation.Create(...);
GetAllSymbolsVisitor visitor = new GetAllSymbolsVisitor();
visitor.Visit(compilation.Assembly.GlobalNamespace);

// Visitor
public class GetAllSymbolsVisitor : SymbolVisitor
{
    public override void VisitNamespace(INamespaceSymbol symbol)
    {
        Parallel.ForEach(symbol.GetMembers(), s => s.Accept(this));
    }

    public override void VisitNamedType(INamedTypeSymbol symbol)
    {
        // Do what you need to here (add to collection, etc.)
    }
}
SLaks

SLaks commented on Oct 19, 2015

@SLaks
Contributor

@daveaglick You can syntax-highlight that code by wrapping it in

```C#
SLaks

SLaks commented on Oct 19, 2015

@SLaks
Contributor
daveaglick

daveaglick commented on Oct 19, 2015

@daveaglick
Contributor

@SLaks Holy cow - I had no idea I could force language highlighting. One of those simple little things I never picked up...thanks!

SLaks

SLaks commented on Oct 19, 2015

@SLaks
Contributor

Also, your visitor won't catch nested types.

daveaglick

daveaglick commented on Oct 19, 2015

@daveaglick
Contributor

Yeah, just left that out - there's actually a pretty full example here that does:
https://github.com/Wyamio/Wyam/blob/develop/Wyam.Modules.CodeAnalysis/AnalyzeSymbolVisitor.cs

added
Concept-APIThis issue involves adding, removing, clarification, or modification of an API.
on Oct 19, 2015
JoshVarty

JoshVarty commented on Oct 19, 2015

@JoshVarty
ContributorAuthor

Thanks guys, that should be more than enough to get me started. :)

drewnoakes

drewnoakes commented on Sep 19, 2016

@drewnoakes
Member
daveaglick

daveaglick commented on Sep 19, 2016

@daveaglick
Contributor

@drewnoakes Indeed it is! A casualty of refactoring, thanks for updating it.

aodl

aodl commented on Jun 25, 2019

@aodl
daveaglick

daveaglick commented on Jun 25, 2019

@daveaglick
Contributor

...and that link will probably break soon too! Here’s one that’s pegged to a specific commit so it should be evergreen:

https://github.com/statiqdev/Framework/blob/76e2d2bda014353478ae65ef179f55180b432b94/src/extensions/Statiq.CodeAnalysis/Analysis/AnalyzeSymbolVisitor.cs

kentcb

kentcb commented on May 10, 2020

@kentcb
Contributor

Hmm, maybe I'm missing something, but I did this:

        private static IEnumerable<INamedTypeSymbol> GetNamedTypeSymbols(Compilation compilation)
        {
            var stack = new Stack<INamespaceSymbol>();
            stack.Push(compilation.GlobalNamespace);

            while (stack.Count > 0)
            {
                var @namespace = stack.Pop();

                foreach (var member in @namespace.GetMembers())
                {
                    if (member is INamespaceSymbol memberAsNamespace)
                    {
                        stack.Push(memberAsNamespace);
                    }
                    else if (member is INamedTypeSymbol memberAsNamedTypeSymbol)
                    {
                        yield return memberAsNamedTypeSymbol;
                    }
                }
            }
        }

Now trying to evaluate whether a visitor is cleaner/better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Concept-APIThis issue involves adding, removing, clarification, or modification of an API.QuestionResolution-AnsweredThe question has been answered

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Pilchie@SLaks@drewnoakes@daveaglick@JoshVarty

        Issue actions

          [Question] How do I get all the INamedTypeSymbols in a given compilation? · Issue #6138 · dotnet/roslyn