-
Notifications
You must be signed in to change notification settings - Fork 440
[Macros] Rework the ExpressionMacro API based on pitch feedback #1104
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
Conversation
…text. Having the source location converter in the context exposes the entire contents of the source file containing the macro expansion to the implementation of the macro. While convenient for the macro author, this breaks Swift's incremental build model, because Swift assumes that (e.g.) changing the body of a function cannot affect the result of type-checking the body of an unrelated function. Drop the implementations of some "built-in" macros that are no longer expressible, such as `#filePath`, `#line`, and `#column`.
We're talking about these as macro "expansions" uniformly, now.
This matches the current proposal, and makes it possible for mutations to the context in the future.
Providing the macro expansion syntax node directly to the macro implementation allowed those implementations to chase its parent pointer, which indirectly exposed the full source code of the enclosing file to the macro implementation. "Disconnect" the syntax node from its parent so the syntax node is independent of all other source code in the file. Another sample macro implementation, `#function`, is now unusable---but this is a better model for incremental builds.
Per pitch feedback, eliminate MacroResult. Instead, macro implementations can produce diagnostics by calling `diagnose()` on the macro evaluation context.
"Expand" better describes what the macro implementation is doing.
static func apply( | ||
_ macro: MacroExpansionExprSyntax, in context: MacroEvaluationContext | ||
) -> MacroResult<ExprSyntax> | ||
static func expand( |
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.
IMO the method should start with a noun phrase to be in line with the API guidelines, e.g. expansion(for:in:)
, because the method is not meant to have side effects.
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.
A later commit introduces the potential for side effects in the macro evaluation context, e.g., for emitting diagnostics and creating new unique local names.
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 thought about this more, and you're totally right. PR to call it expansion(for:in:)
: #1112
@swift-ci please test |
Make a number of changes to the API for expression macros:
MacroEvaluationContext
gets renamed toMacroExpansionContext
MacroExpansionContext
, because one shouldn't have access to the whole source fileMacroExpansionContext
inoutMacroResult
; instead, allow diagnostics to be emitted via the macro expansion contextMacroExpansionContext.createUniqueLocalName()
ExpressionMacro.apply
toExpressionMacro.expand