mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Use `getCommentRange` to trim off the comment's trailing whitespace, avoiding outputting extraneous empty lines. rdar://82072147
680 lines
32 KiB
Swift
680 lines
32 KiB
Swift
// REQUIRES: concurrency
|
|
|
|
// RUN: %empty-directory(%t)
|
|
|
|
enum CustomError : Error {
|
|
case Bad
|
|
}
|
|
func run(block: () -> Bool) -> Bool { return false }
|
|
func makeOptionalError() -> Error? { return nil }
|
|
func makeOptionalString() -> String? { return nil }
|
|
|
|
func simple(_ completion: @escaping (String) -> Void) { }
|
|
func simple() async -> String { }
|
|
|
|
func simple2(arg: String, _ completion: @escaping (String) -> Void) { }
|
|
func simple2(arg: String) async -> String { }
|
|
|
|
func simpleErr(arg: String, _ completion: @escaping (String?, Error?) -> Void) { }
|
|
func simpleErr(arg: String) async throws -> String { }
|
|
|
|
func simpleRes(arg: String, _ completion: @escaping (Result<String, Error>) -> Void) { }
|
|
func simpleRes(arg: String) async throws -> String { }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ALREADY-ASYNC %s
|
|
func alreadyAsync() async {
|
|
simple {
|
|
print($0)
|
|
}
|
|
}
|
|
// ALREADY-ASYNC: func alreadyAsync() async {
|
|
// ALREADY-ASYNC-NEXT: let val0 = await simple()
|
|
// ALREADY-ASYNC-NEXT: print(val0)
|
|
// ALREADY-ASYNC-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NESTED %s
|
|
func nested() {
|
|
simple {
|
|
simple2(arg: $0) { str2 in
|
|
print(str2)
|
|
}
|
|
}
|
|
}
|
|
// NESTED: func nested() async {
|
|
// NESTED-NEXT: let val0 = await simple()
|
|
// NESTED-NEXT: let str2 = await simple2(arg: val0)
|
|
// NESTED-NEXT: print(str2)
|
|
// NESTED-NEXT: }
|
|
|
|
// Can't check for compilation since throws isn't added
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NO-THROWS %s
|
|
func noThrowsAdded() {
|
|
simpleErr(arg: "") { _, _ in }
|
|
}
|
|
// NO-THROWS: func noThrowsAdded() async {
|
|
// NO-THROWS-NEXT: let _ = try await simpleErr(arg: "")
|
|
// NO-THROWS-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+2):9 | %FileCheck -check-prefix=ATTRIBUTES %s
|
|
@available(*, deprecated, message: "Deprecated")
|
|
private func functionWithAttributes() {
|
|
simple { str in
|
|
print(str)
|
|
}
|
|
}
|
|
// ATTRIBUTES: convert_function.swift [[# @LINE-6]]:1 -> [[# @LINE-1]]:2
|
|
// ATTRIBUTES-NEXT: @available(*, deprecated, message: "Deprecated")
|
|
// ATTRIBUTES-NEXT: private func functionWithAttributes() async {
|
|
// ATTRIBUTES-NEXT: let str = await simple()
|
|
// ATTRIBUTES-NEXT: print(str)
|
|
// ATTRIBUTES-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MANY-NESTED %s
|
|
func manyNested() throws {
|
|
simple { str1 in
|
|
print("simple")
|
|
simple2(arg: str1) { str2 in
|
|
print("simple2")
|
|
simpleErr(arg: str2) { str3, err in
|
|
print("simpleErr")
|
|
guard let str3 = str3, err == nil else {
|
|
return
|
|
}
|
|
simpleRes(arg: str3) { res in
|
|
print("simpleRes")
|
|
if case .success(let str4) = res {
|
|
print("\(str1) \(str2) \(str3) \(str4)")
|
|
print("after")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// MANY-NESTED: func manyNested() async throws {
|
|
// MANY-NESTED-NEXT: let str1 = await simple()
|
|
// MANY-NESTED-NEXT: print("simple")
|
|
// MANY-NESTED-NEXT: let str2 = await simple2(arg: str1)
|
|
// MANY-NESTED-NEXT: print("simple2")
|
|
// MANY-NESTED-NEXT: let str3 = try await simpleErr(arg: str2)
|
|
// MANY-NESTED-NEXT: print("simpleErr")
|
|
// MANY-NESTED-NEXT: let str4 = try await simpleRes(arg: str3)
|
|
// MANY-NESTED-NEXT: print("simpleRes")
|
|
// MANY-NESTED-NEXT: print("\(str1) \(str2) \(str3) \(str4)")
|
|
// MANY-NESTED-NEXT: print("after")
|
|
// MANY-NESTED-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
|
func asyncParams(arg: String, _ completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: arg) { str, err in
|
|
print("simpleErr")
|
|
guard let str = str, err == nil else {
|
|
completion(nil, err!)
|
|
return
|
|
}
|
|
completion(str, nil)
|
|
print("after")
|
|
}
|
|
}
|
|
// ASYNC-SIMPLE: func {{[a-zA-Z_]+}}(arg: String) async throws -> String {
|
|
// ASYNC-SIMPLE-NEXT: let str = try await simpleErr(arg: arg)
|
|
// ASYNC-SIMPLE-NEXT: print("simpleErr")
|
|
// ASYNC-SIMPLE-NEXT: {{^}}return str{{$}}
|
|
// ASYNC-SIMPLE-NEXT: print("after")
|
|
// ASYNC-SIMPLE-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
|
func asyncResErrPassed(arg: String, _ completion: @escaping (Result<String, Error>) -> Void) {
|
|
simpleErr(arg: arg) { str, err in
|
|
print("simpleErr")
|
|
guard let str = str, err == nil else {
|
|
completion(.failure(err!))
|
|
return
|
|
}
|
|
completion(.success(str))
|
|
print("after")
|
|
}
|
|
}
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ASYNC-ERR %s
|
|
func asyncResNewErr(arg: String, _ completion: @escaping (Result<String, Error>) -> Void) {
|
|
simpleErr(arg: arg) { str, err in
|
|
print("simpleErr")
|
|
guard let str = str, err == nil else {
|
|
completion(.failure(CustomError.Bad))
|
|
return
|
|
}
|
|
completion(.success(str))
|
|
print("after")
|
|
}
|
|
}
|
|
// ASYNC-ERR: func asyncResNewErr(arg: String) async throws -> String {
|
|
// ASYNC-ERR-NEXT: do {
|
|
// ASYNC-ERR-NEXT: let str = try await simpleErr(arg: arg)
|
|
// ASYNC-ERR-NEXT: print("simpleErr")
|
|
// ASYNC-ERR-NEXT: {{^}}return str{{$}}
|
|
// ASYNC-ERR-NEXT: print("after")
|
|
// ASYNC-ERR-NEXT: } catch let err {
|
|
// ASYNC-ERR-NEXT: throw CustomError.Bad
|
|
// ASYNC-ERR-NEXT: }
|
|
// ASYNC-ERR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=CALL-NON-ASYNC-IN-ASYNC %s
|
|
func callNonAsyncInAsync(_ completion: @escaping (String) -> Void) {
|
|
simple { str in
|
|
let success = run {
|
|
completion(str)
|
|
return true
|
|
}
|
|
if !success {
|
|
completion("bad")
|
|
}
|
|
}
|
|
}
|
|
// CALL-NON-ASYNC-IN-ASYNC: func callNonAsyncInAsync() async -> String {
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: let str = await simple()
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: return await withCheckedContinuation { continuation in
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: let success = run {
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: continuation.resume(returning: str)
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: {{^}} return true{{$}}
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: if !success {
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: continuation.resume(returning: "bad")
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=CALL-NON-ASYNC-IN-ASYNC-COMMENT %s
|
|
func callNonAsyncInAsyncComment(_ completion: @escaping (String) -> Void) {
|
|
// a
|
|
simple { str in // b
|
|
// c
|
|
let success = run {
|
|
// d
|
|
completion(str)
|
|
// e
|
|
return true
|
|
// f
|
|
}
|
|
// g
|
|
if !success {
|
|
// h
|
|
completion("bad")
|
|
// i
|
|
}
|
|
// j
|
|
}
|
|
// k
|
|
}
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT: func callNonAsyncInAsyncComment() async -> String {
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // a
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: let str = await simple()
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // b
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // c
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: return await withCheckedContinuation { continuation in
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: let success = run {
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // d
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: continuation.resume(returning: str)
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // e
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: {{^}} return true{{$}}
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // f
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // g
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: if !success {
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // h
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: continuation.resume(returning: "bad")
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // i
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // j
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: // k
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: }
|
|
// CALL-NON-ASYNC-IN-ASYNC-COMMENT-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-AND-ERROR-HANDLER %s
|
|
func voidAndErrorCompletion(completion: @escaping (Void?, Error?) -> Void) {
|
|
if .random() {
|
|
completion((), nil) // Make sure we drop the ()
|
|
} else {
|
|
completion(nil, CustomError.Bad)
|
|
}
|
|
}
|
|
// VOID-AND-ERROR-HANDLER: func voidAndErrorCompletion() async throws {
|
|
// VOID-AND-ERROR-HANDLER-NEXT: if .random() {
|
|
// VOID-AND-ERROR-HANDLER-NEXT: return // Make sure we drop the ()
|
|
// VOID-AND-ERROR-HANDLER-NEXT: } else {
|
|
// VOID-AND-ERROR-HANDLER-NEXT: throw CustomError.Bad
|
|
// VOID-AND-ERROR-HANDLER-NEXT: }
|
|
// VOID-AND-ERROR-HANDLER-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix TOO-MUCH-VOID-AND-ERROR-HANDLER %s
|
|
func tooMuchVoidAndErrorCompletion(completion: @escaping (Void?, Void?, Error?) -> Void) {
|
|
if .random() {
|
|
completion((), (), nil) // Make sure we drop the ()s
|
|
} else {
|
|
completion(nil, nil, CustomError.Bad)
|
|
}
|
|
}
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER: func tooMuchVoidAndErrorCompletion() async throws {
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: if .random() {
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: return // Make sure we drop the ()s
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: } else {
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: throw CustomError.Bad
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: }
|
|
// TOO-MUCH-VOID-AND-ERROR-HANDLER-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-RESULT-HANDLER %s
|
|
func voidResultCompletion(completion: @escaping (Result<Void, Error>) -> Void) {
|
|
if .random() {
|
|
completion(.success(())) // Make sure we drop the .success(())
|
|
} else {
|
|
completion(.failure(CustomError.Bad))
|
|
}
|
|
}
|
|
// VOID-RESULT-HANDLER: func voidResultCompletion() async throws {
|
|
// VOID-RESULT-HANDLER-NEXT: if .random() {
|
|
// VOID-RESULT-HANDLER-NEXT: return // Make sure we drop the .success(())
|
|
// VOID-RESULT-HANDLER-NEXT: } else {
|
|
// VOID-RESULT-HANDLER-NEXT: throw CustomError.Bad
|
|
// VOID-RESULT-HANDLER-NEXT: }
|
|
// VOID-RESULT-HANDLER-NEXT: }
|
|
|
|
// rdar://77789360 Make sure we don't print a double return statement.
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING %s
|
|
func testReturnHandling(_ completion: @escaping (String?, Error?) -> Void) {
|
|
return completion("", nil)
|
|
}
|
|
// RETURN-HANDLING: func testReturnHandling() async throws -> String {
|
|
// RETURN-HANDLING-NEXT: {{^}} return ""{{$}}
|
|
// RETURN-HANDLING-NEXT: }
|
|
|
|
// rdar://77789360 Make sure we don't print a double return statement and don't
|
|
// completely drop completion(a).
|
|
// Note we cannot use refactor-check-compiles here, as the placeholders mean we
|
|
// don't form valid AST.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING2 %s
|
|
func testReturnHandling2(completion: @escaping (String) -> ()) {
|
|
simpleErr(arg: "") { x, err in
|
|
guard let _ = x else {
|
|
let a = ""
|
|
return completion(a)
|
|
}
|
|
let b = ""
|
|
return completion(b)
|
|
}
|
|
}
|
|
// RETURN-HANDLING2: func testReturnHandling2() async -> String {
|
|
// RETURN-HANDLING2-NEXT: do {
|
|
// RETURN-HANDLING2-NEXT: let x = try await simpleErr(arg: "")
|
|
// RETURN-HANDLING2-NEXT: let b = ""
|
|
// RETURN-HANDLING2-NEXT: {{^}}<#return#> b{{$}}
|
|
// RETURN-HANDLING2-NEXT: } catch let err {
|
|
// RETURN-HANDLING2-NEXT: let a = ""
|
|
// RETURN-HANDLING2-NEXT: {{^}}<#return#> a{{$}}
|
|
// RETURN-HANDLING2-NEXT: }
|
|
// RETURN-HANDLING2-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING3 %s
|
|
func testReturnHandling3(_ completion: @escaping (String?, Error?) -> Void) {
|
|
return (completion("", nil))
|
|
}
|
|
// RETURN-HANDLING3: func testReturnHandling3() async throws -> String {
|
|
// RETURN-HANDLING3-NEXT: {{^}} return ""{{$}}
|
|
// RETURN-HANDLING3-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING4 %s
|
|
func testReturnHandling4(_ completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "xxx") { str, err in
|
|
if str != nil {
|
|
completion(str, err)
|
|
return
|
|
}
|
|
print("some error stuff")
|
|
completion(str, err)
|
|
}
|
|
}
|
|
// RETURN-HANDLING4: func testReturnHandling4() async throws -> String {
|
|
// RETURN-HANDLING4-NEXT: do {
|
|
// RETURN-HANDLING4-NEXT: let str = try await simpleErr(arg: "xxx")
|
|
// RETURN-HANDLING4-NEXT: return str
|
|
// RETURN-HANDLING4-NEXT: } catch let err {
|
|
// RETURN-HANDLING4-NEXT: print("some error stuff")
|
|
// RETURN-HANDLING4-NEXT: throw err
|
|
// RETURN-HANDLING4-NEXT: }
|
|
// RETURN-HANDLING4-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RDAR78693050 %s
|
|
func rdar78693050(_ completion: @escaping () -> Void) {
|
|
simple { str in
|
|
print(str)
|
|
}
|
|
if .random() {
|
|
return completion()
|
|
}
|
|
completion()
|
|
}
|
|
|
|
// RDAR78693050: func rdar78693050() async {
|
|
// RDAR78693050-NEXT: let str = await simple()
|
|
// RDAR78693050-NEXT: print(str)
|
|
// RDAR78693050-NEXT: if .random() {
|
|
// RDAR78693050-NEXT: return
|
|
// RDAR78693050-NEXT: }
|
|
// RDAR78693050-NEXT: return
|
|
// RDAR78693050-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DISCARDABLE-RESULT %s
|
|
func withDefaultedCompletion(arg: String, completion: @escaping (String) -> Void = {_ in}) {
|
|
completion(arg)
|
|
}
|
|
|
|
// DISCARDABLE-RESULT: @discardableResult
|
|
// DISCARDABLE-RESULT-NEXT: func withDefaultedCompletion(arg: String) async -> String {
|
|
// DISCARDABLE-RESULT-NEXT: return arg
|
|
// DISCARDABLE-RESULT-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DEFAULT-ARG %s
|
|
func withDefaultArg(x: String = "") {
|
|
}
|
|
// DEFAULT-ARG: convert_function.swift [[# @LINE-2]]:1 -> [[# @LINE-1]]:2
|
|
// DEFAULT-ARG-NOT: @discardableResult
|
|
// DEFAULT-ARG-NEXT: {{^}}func withDefaultArg(x: String = "") async
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=IMPLICIT-RETURN %s
|
|
func withImplicitReturn(completionHandler: @escaping (String) -> Void) {
|
|
simple {
|
|
completionHandler($0)
|
|
}
|
|
}
|
|
// IMPLICIT-RETURN: func withImplicitReturn() async -> String {
|
|
// IMPLICIT-RETURN-NEXT: let val0 = await simple()
|
|
// IMPLICIT-RETURN-NEXT: return val0
|
|
// IMPLICIT-RETURN-NEXT: }
|
|
|
|
// This code doesn't compile after refactoring because we can't return `nil` from the async function.
|
|
// But there's not much else we can do here.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NIL-RESULT-AND-NIL-ERROR %s
|
|
func nilResultAndNilError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(nil, nil)
|
|
}
|
|
// NIL-RESULT-AND-NIL-ERROR: func nilResultAndNilError() async throws -> String {
|
|
// NIL-RESULT-AND-NIL-ERROR-NEXT: return nil
|
|
// NIL-RESULT-AND-NIL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NIL-RESULT-AND-OPTIONAL-RELAYED-ERROR %s
|
|
func nilResultAndOptionalRelayedError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(nil, err)
|
|
}
|
|
}
|
|
// NIL-RESULT-AND-OPTIONAL-RELAYED-ERROR: func nilResultAndOptionalRelayedError() async throws -> String {
|
|
// NIL-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// NIL-RESULT-AND-OPTIONAL-RELAYED-ERROR-EMPTY:
|
|
// NIL-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: }
|
|
|
|
// This code doesn't compile after refactoring because we can't throw an optional error returned from makeOptionalError().
|
|
// But it's not clear what the intended result should be either.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NIL-RESULT-AND-OPTIONAL-COMPLEX-ERROR %s
|
|
func nilResultAndOptionalComplexError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(nil, makeOptionalError())
|
|
}
|
|
// NIL-RESULT-AND-OPTIONAL-COMPLEX-ERROR: func nilResultAndOptionalComplexError() async throws -> String {
|
|
// NIL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: throw makeOptionalError()
|
|
// NIL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NIL-RESULT-AND-NON-OPTIONAL-ERROR %s
|
|
func nilResultAndNonOptionalError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(nil, CustomError.Bad)
|
|
}
|
|
// NIL-RESULT-AND-NON-OPTIONAL-ERROR: func nilResultAndNonOptionalError() async throws -> String {
|
|
// NIL-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: throw CustomError.Bad
|
|
// NIL-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: }
|
|
|
|
// In this case, we are previously ignoring the error returned from simpleErr but are rethrowing it in the refactored case.
|
|
// That's probably fine although it changes semantics.
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR %s
|
|
func optionalRelayedResultAndNilError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(res, nil)
|
|
}
|
|
}
|
|
// OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR: func optionalRelayedResultAndNilError() async throws -> String {
|
|
// OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: return res
|
|
// OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-RELAYED-ERROR %s
|
|
func optionalRelayedResultAndOptionalRelayedError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(res, err)
|
|
}
|
|
}
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-RELAYED-ERROR: func optionalRelayedResultAndOptionalRelayedError() async throws -> String {
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: return res
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR %s
|
|
func optionalRelayedResultAndOptionalComplexError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(res, makeOptionalError())
|
|
}
|
|
}
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR: func optionalRelayedResultAndOptionalComplexError() async throws -> String {
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: if let error = makeOptionalError() {
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: throw error
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: } else {
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: return res
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
// OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR %s
|
|
func optionalRelayedResultAndNonOptionalError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(res, CustomError.Bad)
|
|
}
|
|
}
|
|
// OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR: func optionalRelayedResultAndNonOptionalError() async throws -> String {
|
|
// OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: throw CustomError.Bad
|
|
// OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR %s
|
|
func nonOptionalRelayedResultAndNilError(completion: @escaping (String?, Error?) -> Void) {
|
|
simple { res in
|
|
completion(res, nil)
|
|
}
|
|
}
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR: func nonOptionalRelayedResultAndNilError() async throws -> String {
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: let res = await simple()
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: return res
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NIL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR %s
|
|
func nonOptionalRelayedResultAndOptionalComplexError(completion: @escaping (String?, Error?) -> Void) {
|
|
simple { res in
|
|
completion(res, makeOptionalError())
|
|
}
|
|
}
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR: func nonOptionalRelayedResultAndOptionalComplexError() async throws -> String {
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: let res = await simple()
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: if let error = makeOptionalError() {
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: throw error
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: } else {
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: return res
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR %s
|
|
func nonOptionalRelayedResultAndNonOptionalError(completion: @escaping (String?, Error?) -> Void) {
|
|
simple { res in
|
|
completion(res, CustomError.Bad)
|
|
}
|
|
}
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR: func nonOptionalRelayedResultAndNonOptionalError() async throws -> String {
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: let res = await simple()
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: throw CustomError.Bad
|
|
// NON-OPTIONAL-RELAYED-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: }
|
|
|
|
// The refactored code doesn't compile because we can't return an optional String from the async function.
|
|
// But it's not clear what the intended result should be either, because `error` is always `nil`.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-COMPLEX-RESULT-AND-NIL-ERROR %s
|
|
func optionalComplexResultAndNilError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(makeOptionalString(), nil)
|
|
}
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NIL-ERROR: func optionalComplexResultAndNilError() async throws -> String {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NIL-ERROR-NEXT: return makeOptionalString()
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NIL-ERROR-NEXT: }
|
|
|
|
// The refactored code doesn't compile because we can't return an optional
|
|
// String from the async function.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-RELAYED-ERROR %s
|
|
func optionalComplexResultAndOptionalRelayedError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(makeOptionalString(), err)
|
|
}
|
|
}
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-RELAYED-ERROR: func optionalComplexResultAndOptionalRelayedError() async throws -> String {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: return makeOptionalString()
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: }
|
|
|
|
// The refactored code doesn't compile because we can't return an optional
|
|
// String or throw an optional Error from the async function.
|
|
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR %s
|
|
func optionalComplexResultAndOptionalComplexError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(makeOptionalString(), makeOptionalError())
|
|
}
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR: func optionalComplexResultAndOptionalComplexError() async throws -> String {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: if let error = makeOptionalError() {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: throw error
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: } else {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: return makeOptionalString()
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
// OPTIONAL-COMPLEX-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=OPTIONAL-COMPLEX-RESULT-AND-NON-OPTIONAL-ERROR %s
|
|
func optionalComplexResultAndNonOptionalError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion(makeOptionalString(), CustomError.Bad)
|
|
}
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NON-OPTIONAL-ERROR: func optionalComplexResultAndNonOptionalError() async throws -> String {
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: throw CustomError.Bad
|
|
// OPTIONAL-COMPLEX-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RESULT-AND-NIL-ERROR %s
|
|
func nonOptionalResultAndNilError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion("abc", nil)
|
|
}
|
|
// NON-OPTIONAL-RESULT-AND-NIL-ERROR: func nonOptionalResultAndNilError() async throws -> String {
|
|
// NON-OPTIONAL-RESULT-AND-NIL-ERROR-NEXT: return "abc"
|
|
// NON-OPTIONAL-RESULT-AND-NIL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RESULT-AND-OPTIONAL-RELAYED-ERROR %s
|
|
func nonOptionalResultAndOptionalRelayedError(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion("abc", err)
|
|
}
|
|
}
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-RELAYED-ERROR: func nonOptionalResultAndOptionalRelayedError() async throws -> String {
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: let res = try await simpleErr(arg: "test")
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: return "abc"
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-RELAYED-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR %s
|
|
func nonOptionalResultAndOptionalComplexError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion("abc", makeOptionalError())
|
|
}
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR: func nonOptionalResultAndOptionalComplexError() async throws -> String {
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: if let error = makeOptionalError() {
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: throw error
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: } else {
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: return "abc"
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
// NON-OPTIONAL-RESULT-AND-OPTIONAL-COMPLEX-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-OPTIONAL-RESULT-AND-NON-OPTIONAL-ERROR %s
|
|
func nonOptionalResultAndNonOptionalError(completion: @escaping (String?, Error?) -> Void) {
|
|
completion("abc", CustomError.Bad)
|
|
}
|
|
// NON-OPTIONAL-RESULT-AND-NON-OPTIONAL-ERROR: func nonOptionalResultAndNonOptionalError() async throws -> String {
|
|
// NON-OPTIONAL-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: throw CustomError.Bad
|
|
// NON-OPTIONAL-RESULT-AND-NON-OPTIONAL-ERROR-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=WRAP-COMPLETION-CALL-IN-PARENS %s
|
|
func wrapCompletionCallInParenthesis(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
(completion(res, err))
|
|
}
|
|
}
|
|
// WRAP-COMPLETION-CALL-IN-PARENS: func wrapCompletionCallInParenthesis() async throws -> String {
|
|
// WRAP-COMPLETION-CALL-IN-PARENS-NEXT: let res = try await simpleErr(arg: "test")
|
|
// WRAP-COMPLETION-CALL-IN-PARENS-NEXT: return res
|
|
// WRAP-COMPLETION-CALL-IN-PARENS-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=WRAP-RESULT-IN-PARENS %s
|
|
func wrapResultInParenthesis(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion((res).self, err)
|
|
}
|
|
}
|
|
// WRAP-RESULT-IN-PARENS: func wrapResultInParenthesis() async throws -> String {
|
|
// WRAP-RESULT-IN-PARENS-NEXT: let res = try await simpleErr(arg: "test")
|
|
// WRAP-RESULT-IN-PARENS-NEXT: return res
|
|
// WRAP-RESULT-IN-PARENS-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=TWO-COMPLETION-HANDLER-CALLS %s
|
|
func twoCompletionHandlerCalls(completion: @escaping (String?, Error?) -> Void) {
|
|
simpleErr(arg: "test") { (res, err) in
|
|
completion(res, err)
|
|
completion(res, err)
|
|
}
|
|
}
|
|
// TWO-COMPLETION-HANDLER-CALLS: func twoCompletionHandlerCalls() async throws -> String {
|
|
// TWO-COMPLETION-HANDLER-CALLS-NEXT: let res = try await simpleErr(arg: "test")
|
|
// TWO-COMPLETION-HANDLER-CALLS-NEXT: return res
|
|
// TWO-COMPLETION-HANDLER-CALLS-NEXT: return res
|
|
// TWO-COMPLETION-HANDLER-CALLS-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NESTED-IGNORED %s
|
|
func nestedIgnored() throws {
|
|
simple { _ in
|
|
print("done")
|
|
simple { _ in
|
|
print("done")
|
|
}
|
|
}
|
|
}
|
|
// NESTED-IGNORED: func nestedIgnored() async throws {
|
|
// NESTED-IGNORED-NEXT: let _ = await simple()
|
|
// NESTED-IGNORED-NEXT: print("done")
|
|
// NESTED-IGNORED-NEXT: let _ = await simple()
|
|
// NESTED-IGNORED-NEXT: print("done")
|
|
// NESTED-IGNORED-NEXT: }
|
|
|
|
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=IGNORED-ERR %s
|
|
func nestedIgnoredErr() throws {
|
|
simpleErr(arg: "") { str, _ in
|
|
if str == nil {
|
|
print("error")
|
|
}
|
|
|
|
simpleErr(arg: "") { str, _ in
|
|
if str == nil {
|
|
print("error")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// IGNORED-ERR: func nestedIgnoredErr() async throws {
|
|
// IGNORED-ERR-NEXT: do {
|
|
// IGNORED-ERR-NEXT: let str = try await simpleErr(arg: "")
|
|
// IGNORED-ERR-NEXT: do {
|
|
// IGNORED-ERR-NEXT: let str1 = try await simpleErr(arg: "")
|
|
// IGNORED-ERR-NEXT: } catch {
|
|
// IGNORED-ERR-NEXT: print("error")
|
|
// IGNORED-ERR-NEXT: }
|
|
// IGNORED-ERR-NEXT: } catch {
|
|
// IGNORED-ERR-NEXT: print("error")
|
|
// IGNORED-ERR-NEXT: }
|
|
// IGNORED-ERR-NEXT: }
|