Commit Graph

102 Commits

Author SHA1 Message Date
Michael Spencer
b2640e15e4 [test] Rename all module.map files to module.modulemap
`module.map` as a module map name has been discouraged since 2014, and
Clang will soon warn on its usage. This patch renames all instances of
`module.map` in the Swift tests to `module.modulemap` in preparation
for this change to Clang.

rdar://106123303
2023-08-21 15:58:59 -07:00
Anthony Latsis
7f6d3bcd41 ASTPrinter: Turn on explicit any printing for everything and remove the option to disable it 2023-05-13 02:55:49 +03:00
Anthony Latsis
fa3a95e7b8 Gardening: Migrate test suite to GH issues: refactoring 2022-09-02 01:44:24 +03:00
Josh Soref
925a7b973c spelling: transform
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 15:53:30 -04:00
Josh Soref
c816df5fa8 spelling: separate
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 15:53:30 -04:00
Josh Soref
bb8674df51 spelling: optional
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 15:53:30 -04:00
Josh Soref
353e4f09ed spelling: multi
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 15:53:30 -04:00
Josh Soref
f7236bc2e9 spelling: handler
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 15:53:30 -04:00
Hamish Knight
97a1653863 Merge pull request #39159 from hamishknight/conditions-apply
[Async Refactoring] Drop bool flag parameter binding
2021-09-07 13:35:22 +01:00
Hamish Knight
72070b7d41 [Async Refactoring] Bind known bool param in fallback
Generalize the logic to handle different BlockKinds,
and add binding logic that lets us assign `true` or
`false` to the given bool success param in the
fallback case.
2021-09-06 21:25:09 +01:00
Hamish Knight
00977afc7b [Async Refactoring] Placeholder dropped params in fallback case
Make sure to convert any references to parameters
that get dropped in the fallback case to
placeholders.
2021-09-06 21:25:09 +01:00
Hamish Knight
1e34f31545 [Async Refactoring] Drop bool flag parameter binding
If we have a known bool flag parameter, drop it
from the success parameters being bound in a
refactored await call, as the async variant drops
it.

rdar://81896460
2021-09-06 21:25:08 +01:00
Hamish Knight
9b493970aa [Aync Refactoring] Better handle comment trailing whitespace
Use `getCommentRange` to trim off the comment's
trailing whitespace, avoiding outputting
extraneous empty lines.

rdar://82072147
2021-09-06 17:51:39 +01:00
Ben Barham
9b8d9e22ef Merge pull request #38981 from apple/skip-underscore
[Refactoring] Do not try to unique '_'
2021-08-24 11:33:15 +10:00
Ben Barham
afaa9e13e4 Merge pull request #38968 from apple/double-async-bad
[Refactoring] Do not add "async" if function is already async
2021-08-21 07:32:39 +10:00
Ben Barham
6a79964ad4 [Refactoring] Do not try to unique '_'
The async refactorings should not try to unique '_' when it's used as
the parameter name. Also skip adding a let binding to the `catch` if the
error parameter is '_'.

Resolves rdar://82158389
2021-08-21 07:30:53 +10:00
Ben Barham
86c47e45f0 [Refactoring] Do not add "async" if function is already async
Convert Function to Async is available on an async function. It could be
useful to run this refactoring still, as it would attempt to convert any
completion-handler functions to their async alternatives. Keep allowing
this, but make sure not to re-add "async" to the function declaration.

Resolves rdar://82156720
2021-08-20 15:24:17 +10:00
Hamish Knight
f58c62c02e [test] Use %refactor-check-compiles in more places
Update a bunch of async refactoring tests to use
%refactor-check-compiles in more cases.
2021-08-18 13:21:06 +01:00
Hamish Knight
1d2d15a52c Merge pull request #38857 from hamishknight/third-times-a-charm
[test] Re-enable convert_bool.swift
2021-08-17 11:33:32 +01:00
Hamish Knight
95ba42387c [test] Re-enable convert_bool.swift
`%build-clang-importer-objc-overlays` builds the
overlays for the current target rather than the
host, so update the `%refactor` invocations to
take the target as an argument.

rdar://81128571
2021-08-12 14:57:22 +01:00
Ben Barham
9fc758adc9 [Test] Update convert_function.swift refactoring tests to also compile
Update the async refactoring tests in `convert_function.swift` to
compile the refactored code (where possible) to check for errors. This
would have prevented the issue with the refactored `Result<Void, ...`>
handler producing erroneous code.
2021-08-12 21:13:20 +10:00
Ben Barham
5bd2d0b932 [Refactoring] Fix invalid legacy body for Result<Void, ...> handler
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
2021-08-12 21:04:18 +10:00
Ben Barham
f6a8dab93d [Refactoring] Use known alternative in async refactoring if one exists
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
2021-08-03 08:46:44 +10:00
Hamish Knight
813a721760 Merge pull request #38674 from hamishknight/following-the-trail 2021-07-29 17:36:10 +01:00
Ben Barham
e7e9b57051 Replace @completionHandlerAsync with @available(*, renamed:)
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
2021-07-29 09:14:44 +10:00
Alex Hoppen
1286bbedf1 Merge pull request #38665 from ahoppen/pr/async-refactoring-parens-around-result
[Async Refactoring] Handle parenthesis around params that no longer need to be unwrapped after refactoring
2021-07-28 21:54:29 +02:00
Hamish Knight
06908adb08 [Async Refactoring] Handle multiple trailing closures
Update the trailing closure handling logic to
handle multiple trailing closures, and adjust the
refactoring output to surround the call in
parentheses rather than adding '.self'. This allows
the parser to deal with the multiple trailing
closures and also silences a warning that would
previously occur.

rdar://81230908
2021-07-28 20:50:40 +01:00
Hamish Knight
91c9b189cf [test] Change a %refactor into %refactor-check-compiles 2021-07-28 20:50:39 +01:00
Alex Hoppen
3bea2b728c [Async Refactoring] Handle parenthesis around params that no longer need to be unwrapped after refactoring
Throw another `getSemanticsProvidingExpr` in the async refactoring code for better results.
2021-07-28 18:13:02 +02:00
Rintaro Ishizaki
a18e3e6244 [Test] Disable refactoring/ConvertAsync/convert_bool.swift
rdar://81128571
2021-07-26 14:46:36 -07:00
Ben Barham
fabb02100f [Test] Add @escaping to async refactoring tests
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.
2021-07-24 09:53:17 +10:00
Hamish Knight
1ebb1fd2f5 [Async Refactoring] Add parens around custom error cast
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
2021-07-22 23:20:24 +01:00
Hamish Knight
007b91cf7b [Async Refactoring] Update to use Task's init
Use the Task initializer instead of the top-level
`async` function to match the latest Concurrency
API.

rdar:80888385
2021-07-21 11:40:35 +01:00
Alex Hoppen
cd31fa0f73 [Async Refactoring] Improve fatalError message to unwrap result arguments in continuation
In the previous `fatalError` message `Expected non-nil result 'result' for nil error`, it wasn’t exactly clear wht the `error` referred to. In some cases, when the error was ignored, there wasn’t even an `error` variable in the refactored code.

The new `Expected non-nil result '...' in the non-error case` is a little more generic and also fits if an error is ignored.
2021-07-07 12:05:37 +02:00
Alex Hoppen
edc1393291 [Async Refactoring] Rename 'success param/argument' to 'result' in fatalError messages
The 'success param/argument' is a terminology we use internally in the refactoring and not one we want to present to the user. Just name it 'result' instead.
2021-07-07 11:54:11 +02:00
Alex Hoppen
06219cdfa2 [Async Refactoring] Remove assertions for nil result values in async wrapper
Since we aren’t checking that all result arguments are `nil` if there was an `error` in all the other refactorings, also remove the assertions in the async wrapper.
2021-07-07 11:54:11 +02:00
Alex Hoppen
6cbbb7cb1f [Async Refactoring] Split ambiguous (error + success) completion handler calls into success and error case
Previously, when a completion handler call had arguments for both the success and error parameters, we were always interpreting it as an error call. In case the error argument was an `Optional`, this could cause us to generate code that didn't compile, because we `throw`ed the `Error?` or passed it to `continuation.resume(throwing)`, both of which didn't work.

We now generate an `if let` statement that checks if the error is `nil`. If it is, the error is thrown. Otherwise, we interpret the call as a success call and return the result.

- Example 1 (convert to continuation)
-- Base Code
```swift
func test(completionHandler: (Int?, Error?) -> Void) {
  withoutAsyncAlternativeThrowing { (theValue, theError) in
    completionHandler(theValue, theError)
  }
}
```
-- Old Refactoring Result
```swift
func test() async throws -> Int {
  return try await withCheckedThrowingContinuation { continuation in
    withoutAsyncAlternativeThrowing { (theValue, theError) in
      continuation.resume(throwing: theError) // error: Argument type 'Error?' does not conform to expected type 'Error'
    }
  }
}
-- New Refactoring Result
```swift
func testThrowingContinuationRelayingErrorAndResult() async throws -> Int {
  return try await withCheckedThrowingContinuation { continuation in
    withoutAsyncAlternativeThrowing { (theValue, theError) in
      if let error = theError {
        continuation.resume(throwing: error)
      } else {
        guard let theValue = theValue else {
          fatalError("Expected non-nil success argument 'theValue' for nil error")
        }
        continuation.resume(returning: theValue)
      }
    }
  }
}
```

- Example 2 (convert to async/await)
-- Base Code
```swift
func test(completion: (String?, Error?) -> Void) {
  simpleErr() { (res, err) in
    completion(res, err)
  }
}
```
-- Old Refactoring Result
```swift
func test() async throws -> String {
  let res = try await simpleErr()
  throw <#err#>
}
```
-- New Refactoring Result
```swift
func test() async throws -> String {
  let res = try await simpleErr()
  return res
}
```
2021-07-07 11:54:11 +02:00
Alex Hoppen
c3e9676cb1 Merge pull request #38261 from ahoppen/pr/check-semantics-expr-for-completion-handler-call
[Async Refactoring] Get semantics providing expr to decide if call is to completion handler
2021-07-06 10:53:56 +02:00
Alex Hoppen
ec8957972a [Async Refactoring] Get semantics providing expr to decide if call is to completion handler
Resolves rdar://78011350
2021-07-05 17:41:39 +02:00
Alex Hoppen
3dcb08a369 [Async Refactoring] Cosmetic Improvements to "Add Async Wrapper" Refactoring
Two mostly-cosmetic change to the "Add Async Wrapper" refactoring
- Rename the continuation from `cont` to `continuation` and error from `err` to `error` to better match Swifts naming guidelines
- Add assertions that all result parameters are `nil` if an error is passed to the completion handler.

Resolves rdar://80172152
2021-07-05 13:34:27 +02:00
Alex Hoppen
54fcc90841 [Async Refactoring] Wrap code in a continuation if conversion doesn't yield reasonable results
If we are requested to convert a function to async, but the call in the function’s body that eventually calls the completion handler doesn’t have an async alternative, we are currently copying the call as-is, replacing any calls to the completion handler by placeholders.

For example,
```swift
func testDispatch(completionHandler: @escaping (Int) -> Void) {
  DispatchQueue.global.async {
     completionHandler(longSyncFunc())
  }
}
```
becomes
```swift
func testDispatch() async -> Int  {
  DispatchQueue.global.async {
     <#completionHandler#>(longSyncFunc())
  }
}
```

and

```swift
func testUrlSession(completionHandler: @escaping (Data) -> Void) {
  let task = URLSession.shared.dataTask(with: request) { data, response, error in
    completion(data!)
  }
  task.resume()
}
```
becomes
```swift
func testUrlSession() async -> Data {
  let task = URLSession.shared.dataTask(with: request) { data, response, error in
    <#completion#>(data!)
  }
  task.resume()
}
```

Both of these are better modelled using continuations. Thus, if we find an expression that contains a call to the completion handler and can’t be hoisted to an await statement, we are wrapping the rest of the current scope in a `withChecked(Throwing)Continuation`, producing the following results:

```swift
func testDispatch() async -> Int {
  return await withCheckedContinuation { (continuation: CheckedContinuation<Int, Never>) in
    DispatchQueue.global.async {
      continuation.resume(returning: syncComputation())
    }
  }
}
```

and

```swift
func testDataTask() async -> Int?
  return await withCheckedContinuation { (continuation: CheckedContinuation<Data, Never>) in
    let task = URLSession.shared.dataTask { data, response, error in
      continuation.resume(returning: data!)
    }
    task.resume()
  }
}
```

I think both are much closer to what the developer is actually expecting.

Resolves rdar://79304583
2021-07-02 15:48:41 +02:00
Alex Hoppen
7a68a1d834 Merge pull request #38191 from ahoppen/pr/implict-return-async-refactoring
[Async Refactoring] Add `return` keyword if wrapping `ReturnStmt` is implicit
2021-07-01 15:40:00 +02:00
Alex Hoppen
f7c7599a8c [Async Refactoring] Add return keyword if wrapping ReturnStmt is implicit
Previously, in the following case we were failing to add a `return` keyword inside `withImplicitReturn`.
```
func withImplicitReturn(completionHandler: (String) -> Void) {
  simple {
    completionHandler($0)
  }
}
```

This is because the call of `completionHandler($0)` is wrapped by an implicit `ReturnStmt` and thus we assumed that there was already a `return` keyword present.

Fix this issue by checking if the wrapping `ReturnStmt` is implicit and if it is, add the `return` keyword.

Fixes rdar://80009760
2021-07-01 10:21:46 +02:00
Hamish Knight
d05e79de9e Merge pull request #38139 from hamishknight/null-check 2021-06-29 13:41:52 +01:00
Hamish Knight
0ffc0ef3f8 [test] Re-enable convert_bool.swift
Make sure to build and include the mock overlays.

rdar://78879483
2021-06-28 17:27:43 +01:00
Hamish Knight
0d4eb978da [Async Refactoring] Add missing null type check
Don't crash if we have a boolean condition without
a type, as that may occur in invalid code.

rdar://79864182
2021-06-28 16:03:54 +01:00
Alex Hoppen
ffbbbaffca Merge pull request #38052 from ahoppen/pr/use-closure-label-for-async-return-type
[Refactoring] Use internal completion handler labels for async function's return type
2021-06-25 12:57:00 +02:00
Alex Hoppen
d944b8bd49 [Refactoring] Use internal completion handler labels for async function's return type
If a completion handler specifies internal parameter labels, we can use those to label the elements of the tuple returned by the async alternative.

For example
```swift
func foo(completion: (_ first: String, _ second: String) -> Void) { }
```
gets refactored to
```swift
func foo() async -> (first: String, second: String) { }
```

Resolves rdar://77268040
2021-06-24 08:00:28 +02:00
Hamish Knight
f5b00fcff3 [test] Fix a couple of RUN directives 2021-06-17 10:17:38 +01:00
Alex Hoppen
81b37fdb4c [Refactoring] Support refactoring for case let patterns
Previously we only supported `case` patterns that bound with a `let` inside the associated value like `case .success(let value)`. With this change, we also support `case let .success(value)`.

Fixes rdar://79279846 [SR-14772]
2021-06-14 12:31:01 +02:00