Hoisting macro information to the top level

Currently, I'm using Sourcery for something, and was looking at if moving to a macro-based solution would be possible, but as far as I can tell the macro system is missing a key bit of functionality for my use case.

I need to be able to centrally collect the list of types that a macro has been applied to, and then process them as a group.

The alternative to this is making the user of the macro maintain a list of all instances manually, and this is the approach the macro library itself takes in the manual management of CompilerPlugin.providingMacros.

Another (since-solved) situation where this occurs was the linux test situation prior to swift 5.something. The information needed to run all the tests had to be manually listed in LinuxMain.swift. As far as I know, this was solved with compiler magic, but there's no reason why a test framework shouldn't be writable with macros.

So 2 questions:

  1. Am I just missing the bit of documentation that says how to do this?
  2. If not, could something to enable this capability be added to the macro system in the future?

Edit: A concrete example of what I'm looking for:
@attached(conformance)
public macro makeThing() = ...

protocol Thing {}

@makeThing
enum Foo {
    @makeThing
    struct Bar {}
}

@makeThing
struct Baz {}

// I want generated at the top level:
let allThings: [Thing.Type] = [
    Foo.self,
    Foo.Bar.self,
    Baz.self,
]
1 Like

SE-0385: Custom Reflection Metadata proposed a runtime solution.

3 Likes

Macros can't do this, and I do not expect we will ever extend them in this direction because such a macro would need to effectively run across all of the Swift code for the module, which is problematic for compile-time performance and incremental builds.

Doug

2 Likes