Skip to content

Commit 32ceb24

Browse files
committed
[Refactoring] Promote call to refactored completion handlers to return
When a function’s completion handler is being passed to another function and the function that the completion handler is being declared in is converted to async, replace the call to the completion handler by a `return` statement. For example: ```swift func foo(completion: (String) -> Void) { bar(completion) } ``` becomes ```swift func foo() async -> String { return await bar() } ``` Previously, we were calling the completion handler, which no longer exists in the newly created `async` function.
1 parent 921443e commit 32ceb24

File tree

2 files changed

+176
-3
lines changed

2 files changed

+176
-3
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4367,6 +4367,11 @@ struct AsyncHandlerParamDesc : public AsyncHandlerDesc {
43674367
return AsyncHandlerParamDesc(AsyncHandlerDesc::get(Param, ignoreName),
43684368
Index);
43694369
}
4370+
4371+
bool operator==(const AsyncHandlerParamDesc &Other) const {
4372+
return Handler == Other.Handler && Type == Other.Type &&
4373+
HasError == Other.HasError && Index == Other.Index;
4374+
}
43704375
};
43714376

43724377
enum class ConditionType { INVALID, NIL, NOT_NIL };
@@ -4944,6 +4949,7 @@ class AsyncConverter : private SourceEntityWalker {
49444949
OS << "await ";
49454950
addCallToAsyncMethod(FD, TopHandler);
49464951
});
4952+
OS << "\n";
49474953
OS << tok::r_brace << "\n"; // end 'async'
49484954
OS << tok::r_brace << "\n"; // end function body
49494955
return true;
@@ -5292,6 +5298,22 @@ class AsyncConverter : private SourceEntityWalker {
52925298
return;
52935299
}
52945300
if (auto CallbackDecl = getReferencedDecl(CallbackArg)) {
5301+
if (CallbackDecl == TopHandler.getHandler()) {
5302+
// We are refactoring the function that declared the completion handler
5303+
// that would be called here. We can't call the completion handler
5304+
// anymore because it will be removed. But since the function that
5305+
// declared it is being refactored to async, we can just return the
5306+
// values.
5307+
if (!HandlerDesc.willAsyncReturnVoid()) {
5308+
OS << tok::kw_return << " ";
5309+
}
5310+
addAwaitCall(CE, ArgList.ref(), ClassifiedBlock(), {}, HandlerDesc,
5311+
/*AddDeclarations=*/false);
5312+
return;
5313+
}
5314+
// We are not removing the completion handler, so we can call it once the
5315+
// async function returns.
5316+
52955317
// The completion handler that is called as part of the \p CE call.
52965318
// This will be called once the async function returns.
52975319
auto CompletionHandler = AsyncHandlerDesc::get(CallbackDecl,
@@ -5448,7 +5470,7 @@ class AsyncConverter : private SourceEntityWalker {
54485470
OS << "\n";
54495471
OS << tok::r_brace << " " << tok::kw_catch << " " << tok::l_brace << "\n";
54505472
addCallToCompletionHandler(/*HasResult=*/false, HandlerDesc, HandlerName);
5451-
OS << "\n" << tok::r_brace << "\n"; // end catch
5473+
OS << "\n" << tok::r_brace; // end catch
54525474
} else {
54535475
if (!HandlerDesc.willAsyncReturnVoid()) {
54545476
OS << tok::kw_let << " result";
@@ -5458,7 +5480,6 @@ class AsyncConverter : private SourceEntityWalker {
54585480
AddAwaitCall();
54595481
OS << "\n";
54605482
addCallToCompletionHandler(/*HasResult=*/true, HandlerDesc, HandlerName);
5461-
OS << "\n";
54625483
}
54635484
}
54645485

0 commit comments

Comments
 (0)