Skip to content

Commit 9fc3e6a

Browse files
authored
[5.5][Refactoring] Support refactoring calls to async if a variable or function is used as completion handler (#37381)
* [Refactoring] Merge `LegacyAlternativeBodyCreator` into `AsyncConverter` This will later allow us to reuse parts of `LegacyAlternativeBodyCreator` from `AsyncConverter` when refactoring calls to an async alternative if they pass a variable as the completion handler. * [Refactoring] Replace usage of constant strings with `tok::` wherever possible The code moved from `LegacyAlternativeBodyCreator` was using constant strings a lot. Use `tok::` instead to match the style of `AsyncConverter`. * [Refactoring] Support refactoring calls to async if a variable or function is used as completion handler Previously, we only supported refactoring a function to call the async alternative if a closure was used for the callback parameter. With this change, we also support calling a arbitrary function (or variable with function type) that is passed to the completion handler argument. The implementation basically re-uses the code we already have to create the legacy function’s body (which calls the newly created async version and then forwards the arguments to the legacy completion handler). To describe the completion handler that the result is being forwarded to, I’m also using `AsyncHandlerDesc`, but since the completion handler may be a variable, it doesn’t necessarily have an `Index` within a function decl that declares it. Because of this, I split the `AsyncHandlerDesc` up into a context-free `AsyncHandlerDesc` (without an `Index`) and `AsyncHandlerParamDesc` (which includes the `Index`). It turns out that `AsyncHandlerDesc` is sufficient in most places. Resolves rdar://77460524 * [Refactoring] Support creation of async legacy bodies even if a parameter is not optional If the parameter is not an `Optional`, add a placeholder instead that the user can fill with a sensible default value. * [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. * [Refactoring] Remove the `VARIABLE-COMPLETION-HANDLER` suffix from checks in `variable_as_callback.swift` These were a legacy from when the tests lived in `basic.swift`. They are no longer needed. * [Refactoring] Check that code compiles after refatorings in `variable_as_callback.swift`
1 parent d8b06ae commit 9fc3e6a

File tree

3 files changed

+817
-215
lines changed

3 files changed

+817
-215
lines changed

0 commit comments

Comments
 (0)