New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attached macros #1932
Attached macros #1932
Conversation
* Split peer/member/accessor macro implementations into separate protocols and attribute spellings, so the compiler can query them in a more fine-grained manner. * Removed function-body macros... for the moment. We'll come back to them. * Add example showing composition of different macro roles for the same macro to effect property-wrappers behavior.
proposals/nnnn-attached-macros.md
Outdated
|
||
```swift | ||
/// Create the necessary members to turn a struct into an option set. | ||
@attached(member, names: names(rawValue), arbitrary]) macro optionSetMembers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an open square bracket missing here, I believe after names:
?
Also, according to the freestanding proposal, should this be expressed as named("rawValue")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right on both counts, thank you!
proposals/nnnn-attached-macros.md
Outdated
@attached(peer, names: overloaded) macro addCompletionHandler() | ||
``` | ||
|
||
This macro uses the `@attached` attribute to indicate that it is an attached peer attribute. The `names` argument specifies that how the names of the peer declarations are created, using an extended form of the scheme introduced with [freestanding macros](https://github.com/DougGregor/swift-evolution/blob/freestanding-macros/proposals/nnnn-freestanding-macros.md#up-front-declarations-of-newly-introduced-names). In this case, `overloaded` means that this macro will produce a peer that is overloaded with the declaration to which it is attached, i.e., it has the same base name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, if we start this review before freestanding macros, I wonder if we should move the linked content for the naming scheme into a section of this proposal. Alternatively, it could go into the vision and both proposals could link to it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pulled in all of the linked content so this proposal is... freestanding. Also, added more detail
proposals/nnnn-attached-macros.md
Outdated
@attached(peer, names: overloaded) macro addCompletionHandler() | ||
``` | ||
|
||
This macro uses the `@attached` attribute to indicate that it is an attached peer attribute. The `names` argument specifies that how the names of the peer declarations are created, using an extended form of the scheme introduced with [freestanding macros](https://github.com/DougGregor/swift-evolution/blob/freestanding-macros/proposals/nnnn-freestanding-macros.md#up-front-declarations-of-newly-introduced-names). In this case, `overloaded` means that this macro will produce a peer that is overloaded with the declaration to which it is attached, i.e., it has the same base name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since functions can be distinguished by their full decl name with argument labels, what is the significance of telling the compiler that the peer declaration has the same base name? Can you expand on what the compiler does with this information?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler tends to ignore the labels when it does name lookup. I've added some more text about how this information is used.
proposals/nnnn-attached-macros.md
Outdated
|
||
The implementation of the `dictionaryStorage` macro would create the accessor declarations shown above, using either the `key` argument (if present) or deriving the key name from the property name. The effect of this macro isn't something that can be done with a property wrapper, because the property wrapper wouldn't have access to `self.storage`. | ||
|
||
The presence of an accessor macro on a stored property removes the initializer. It's up to the implementation of the accessor macro to either diagnose the presence of the initializer (if it cannot be used) or incorporate it in the result. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could use a little more clarity (maybe an example). Are you saying that if someone writes the following:
@dictionaryStorage
var name: String = "defaultName"
Then the compiler will "prune" the = "defaultName"
and it's entirely up to the macro to fetch it from the syntax tree and decide how they want to use it?
If so, would this prevent macros that only want to attach willSet
/didSet
accessors, since the macro's return value is an array of AccessorDecl
s and thus there would be no place to reattach the initializer clause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, good catch. This was a hole in the design; I've updated the proposal to address this.
proposals/nnnn-attached-macros.md
Outdated
As with freestanding macros, attached declaration macros are declared with `macro`, and have [type-checked macro arguments](https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#type-checked-macro-arguments-and-results) that allow their behavior to be customized. Attached macros are identified with the `@attached` attribute, which also provides the specific role as well as [any names they introduce](https://github.com/DougGregor/swift-evolution/blob/freestanding-macros/proposals/nnnn-freestanding-macros.md#up-front-declarations-of-newly-introduced-names). For example, the aforemented macro emulating property wrappers could be declared as follows: | ||
|
||
```swift | ||
@attached(peer, names: prefixed(_)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other parts of the proposal, the syntax used here involves a string literal: prefixed("_")
. Can you update these so that they're consistent throughout (whichever one happens to be correct)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thank you!
…es into computed properties.
…roperty vs. turning it into a computed property.
…anding macros proposal here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'm going to start the review momentarily.
No description provided.