Can a Macro generate code in file A, referencing declarations in file B?

Say I want to write a macro to re-declare all properties from a given type onto a new type, like so:

// Foo.swift
class Foo {
   var f: Int
   var oo: Int
}

// Bar.swift

@withProperties(of: Foo.self)
class Bar { }

I want this to expand Bar.swift into the following:

class Bar {
   var f: Int
   var oo: Int
}

I'm guessing this isn't possible. But, why not? Is this an an intentional design choice or a limitation of how SwiftSyntax works?

1 Like

You are right, this isn’t possible.

The reason is that macros in Swift are syntax-based, i.e. their implementation only sees the attributed type - nothing more around, especially not the Foo class. Without access to this type, though, the macro’s implementation is unable to know which fields to add to the attributed class.

This is a different story, however, if you’d use a peer macro on the Foo class that generates the Bar class as a peer of Foo. With that, you have full syntactic access to the Foo type so that you can copy its fields to Bar.