Commit Graph

13 Commits

Author SHA1 Message Date
Hamish Knight
e97c781ca1 [Async Refactoring] Add @discardableResult for defaulted completion
If the completion handler parameter has a default
argument, mark the resulting async function as
`@discardableResult`, as the caller may not care
about the result.

rdar://79190170
2021-06-11 11:39:16 +01:00
Hamish Knight
4197bc2325 [Async Refactoring] Fix crash on recursive AST walk
The async refactoring may perform recursive AST
walks in cases such as transforming the body of
a hoisted closure. Make sure this can be handled
by the logic tracking the ASTWalker in the
SourceEntityWalker, such that we don't crash when
later converting the call to a completion callback.

rdar://78693050
2021-05-31 21:47:31 +01:00
Hamish Knight
87703a0716 [test] Add test for async completion handler call in parens
We don't currently handle this, but arguably we
should be able to.
2021-05-14 11:17:59 +01:00
Hamish Knight
7ab5915750 [Refactoring] Don't drop returns with expressions
Previously we were unconditionally dropping a
return statement if it was the last node, which
could cause us to inadvertently drop the result
expression as well. Instead, only drop bare
'return' statements.

rdar://77789360
2021-05-14 11:17:59 +01:00
Hamish Knight
aa189f2fe9 [Refactoring] Avoid duplicating return statements
It's possible the user has already written an
explicit return for the call to the completion
handler. In that case, avoid adding another return.

rdar://77789360
2021-05-14 11:17:59 +01:00
Hamish Knight
8cb319b640 [Refactoring] Preserve comments in async transform
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
2021-05-13 14:16:27 +01:00
Hamish Knight
2d750747c2 [Refactoring] [test] Use more strict matching on returns and breaks
Make sure we match against an exact return or
break in these cases, rather than a placeholder.
2021-05-04 14:30:24 +01:00
Alex Hoppen
b2378a401e [Refactoring] Convert completion handler when converting function to async
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
2021-04-30 12:53:22 +02:00
Hamish Knight
c1e4dc3d82 [Refactoring] Improve Void handling for async conversion
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
2021-04-30 01:09:04 +01:00
Ben Barham
9cddf498de [Refactoring] Replace attributes when converting to an async function
The replacement range was `FunctionDecl::getRange`, which does not
include attributes. This would cause attributes to be duplicated when
converting a function to async. Override the start with the attribute
start instead so that they are replaced as well.

Resolves rdar://74063741
2021-02-12 07:43:57 +10:00
Ben Barham
783c177956 [Refactoring] Fix stack use after free in new async refactorings
Resolves rdar://73984220
2021-02-05 15:32:35 +10:00
Rintaro Ishizaki
f67b5d9917 [Tests] Disable refactoring/ConvertAsync in ASAN
ASAN detected stack-use-after-scope errors. Disable tests while fixing.

rdar://problem/73984220
2021-02-04 10:17:49 -08:00
Ben Barham
a9073b0922 [Refactoring] Add async refactorings
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
2021-02-03 15:54:46 +10:00