mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #79980 from hborla/closure-body-macro
[Macros] Implement support for function body macros on closures.
This commit is contained in:
@@ -1150,7 +1150,7 @@ public:
|
||||
|
||||
ASTContext &getASTContext() const { return Ctx; }
|
||||
|
||||
bool walkToClosureExprPre(ClosureExpr *expr);
|
||||
bool walkToClosureExprPre(ClosureExpr *expr, ParentTy &parent);
|
||||
|
||||
MacroWalking getMacroWalkingBehavior() const override {
|
||||
return MacroWalking::Arguments;
|
||||
@@ -1252,7 +1252,7 @@ public:
|
||||
// but do not walk into the body. That will be type-checked after
|
||||
// we've determine the complete function type.
|
||||
if (auto closure = dyn_cast<ClosureExpr>(expr))
|
||||
return finish(walkToClosureExprPre(closure), expr);
|
||||
return finish(walkToClosureExprPre(closure, Parent), expr);
|
||||
|
||||
if (auto *unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr))
|
||||
return finish(true, TypeChecker::resolveDeclRefExpr(unresolved, DC));
|
||||
@@ -1537,7 +1537,27 @@ public:
|
||||
|
||||
/// Perform prechecking of a ClosureExpr before we dive into it. This returns
|
||||
/// true when we want the body to be considered part of this larger expression.
|
||||
bool PreCheckTarget::walkToClosureExprPre(ClosureExpr *closure) {
|
||||
bool PreCheckTarget::walkToClosureExprPre(ClosureExpr *closure,
|
||||
ParentTy &parent) {
|
||||
if (auto *expandedBody = closure->getExpandedBody()) {
|
||||
if (Parent.getAsExpr()) {
|
||||
// We cannot simply replace the body when closure i.e. is passed
|
||||
// as an argument to a call or is a source of an assignment
|
||||
// because the source range of the argument list would cross
|
||||
// buffer boundaries. One way to avoid that is to inject
|
||||
// elements into a new implicit brace statement with the original
|
||||
// source locations. Brace statement has to be implicit because its
|
||||
// elements are in a different buffer.
|
||||
auto sourceRange = closure->getSourceRange();
|
||||
closure->setBody(BraceStmt::create(getASTContext(), sourceRange.Start,
|
||||
expandedBody->getElements(),
|
||||
sourceRange.End,
|
||||
/*implicit=*/true));
|
||||
} else {
|
||||
closure->setBody(expandedBody);
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-check the closure body.
|
||||
(void)evaluateOrDefault(Ctx.evaluator, PreCheckClosureBodyRequest{closure},
|
||||
nullptr);
|
||||
|
||||
Reference in New Issue
Block a user