When adding an async alternative for a function with a
`(Result<Void, ...>) -> Void` completion handler, the legacy body was
adding a call to the handler with `.success(result)`. We don't assign to
`result` for `Void` handlers, so pass `()` instead.
Resolves rdar://81829392
Update the async refactorings to use the name from the async alternative
if one is known, rather than always assuming the name matches the
synchronous function.
Note that this could also be used to determine whether results remain
optional or not, but that has been left for a future patch.
Resolves rdar://80612521
Instead of a new attribute `@completionHandlerAsync`, allow the use of
the existing `renamed` parameter of `@available` to specify the
asynchronous alternative of a synchronous function.
No errors will be output from invalid names as `@completionHandlerAsync`
had, but if a function is correctly matched then it will be used to
output warnings when using the synchronous function in an asynchronous
context (as before).
Resolves rdar://80612731
The async refactorings ignore whether a completion handler had
`@escaping` or not. In preparation of fixing this, fix up all functions
to have `@escaping` for their completion handler parameter.
Also some small miscellaneous fixes in order to reduce the number of
warnings output on test failures and also the addition of `REQUIRES:
concurrency` on all tests.
When passing a forwarded error to a CustomError?
completion handler parameter, wrap the cast in a
set of parentheses to silence a warning in the
refactored code.
rdar://80409905
We were trying to retrieve the name of all function calls in the body using `getBaseIdentifier`. But calls to `init` don’t have a base identifier, just a `DeclBaseName` (which is special). Work with the `DeclBaseName` internally to prevent the crash.
Fixes rdar://78024731 [SR-14637]
Previously we would drop comments between nodes in
a BraceStmt, as we printed each node out individually.
To remedy this, always make sure we scan backwards
to find any preceding comments attached to a node,
and also keep track of any SourceLocs which we
don't print, but may have comments attached which
we want to preserve.
rdar://77401810
When converting a call or function, rename declarations such that
redeclaration errors and shadowing are avoided. In some cases this will
be overly conservative, but since any renamed variable can be fixed with
edit all in scope, this is preferred over causing redeclaration errors
or possible shadowing.
Resolves rdar://73973517
Instead of leaving two copies of the same implementation, rewrite the old method with the completion handler to call the newly added `async` method.
Resolves rdar://74464833
Convert function to async currently only adds "async" to the function and runs the convert call refactoring on the body.
This was intentional, but it turns out to be somewhat confusing. Instead, run the same refactoring as the add async alternative refactoring but just replace rather than add.
Resolves rdar://77103049
When converting a function with a completion handler
that has a Void success parameter, e.g
`(Void?, Error?) -> Void`, or more likely a
`Result<Void, Error>` parameter, make sure to omit
the `-> Void` from the resulting async function
conversion.
In addition, strip any Void bindings from an async
function call, and any explicit Void return values
from inside the async function.
Resolves rdar://75189289
We already have special logic to extrac the closure for closures with capture lists, add the same kind of logic for closures that are marked `@convention(block)` etc.
Resolves rdar://75301524 [SR-14328]
When a function declaration has no body (e.g. because it’s a protocol requirement), we construct the range to replace by the `async` keyword as follows:
- Start: One character after the closing `)` (or potentially the `throws` keyword if it exists)
- End: Last token in the function declaration
Since the last token in the function declaration is the `)`, we end up with a range that has `End < Start`, which crashes when trying to print the range.
If the function has no body, we should just use the range’s start location as the end location to construct an empty range.
Fixes rdar://76677035
Default arguments were still being visited when converting the call,
adding extra commas to the converted call. Skip over them.
Resolves rdar://74248990
Still convert the call if it was requested directly - only check the name
when converting a whole function. Once we have an attribute, we should
use that instead.
Adds three refactorings intended to help users migrate their existing
code to use the new async language features:
1. Convert call to use async alternative
2. Convert function to async
3. Add async alternative function
A function is considered to have an async alternative if it has a void
return type and has a void returning closure as its last parameter. A
method to explicitly mark functions as having an async alternative may
be added to make this more accurate in the future (required for eg.
a warning about a call to the non-async version of a function in an
async context).
(1) converts a call to use the new `await` async language syntax. If the
async alternative throws, it will also add `try`. The closure itself is
hoisted out of the call, see the comments on
`AsyncConversionStringBuilder` for specifics.
(2) converts a whole function to `async`, using (1) to convert any calls
in the function to their async alternatives. (3) is similar to (2), but
instead *adds* a function and replaces calls to its
completion/handler/callback closure parameter with `return` or `throws`.
Resolves rdar://68254700