📄 PublicMembersCollector.cs
using System.Collections.Generic;
using Microsoft.CodeAnalysis;

namespace Reacher;

internal class PublicMembersCollector : SymbolVisitor
{
    private readonly HashSet<IMethodSymbol> publicMembers = [];

    public IEnumerable<IMethodSymbol> PublicMembers => publicMembers;

    public override void VisitAssembly(IAssemblySymbol symbol)
    {
        symbol.GlobalNamespace.Accept(this);
    }

    public override void VisitNamespace(INamespaceSymbol symbol)
    {
        foreach (var namespaceOrType in symbol.GetMembers())
        {
            namespaceOrType.Accept(this);
        }
    }

    public override void VisitNamedType(INamedTypeSymbol type)
    {
        if (type.DeclaredAccessibility is not Accessibility.Public)
        {
            return;
        }

        foreach (var member in type.GetMembers())
        {
            member.Accept(this);
        }

        foreach (var nestedType in type.GetTypeMembers())
        {
            nestedType.Accept(this);
        }
    }

    public override void VisitMethod(IMethodSymbol member)
    {
        if (member.DeclaredAccessibility is not Accessibility.Public)
        {
            return;
        }

        publicMembers.Add(member);
    }
}