mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -149,6 +149,9 @@ namespace swift {
|
||||
/// Should potential unavailability on enum cases be downgraded to a warning?
|
||||
bool WarnOnPotentiallyUnavailableEnumCase = false;
|
||||
|
||||
/// Should the editor placeholder error be downgraded to a warning?
|
||||
bool WarnOnEditorPlaceholder = false;
|
||||
|
||||
/// Maximum number of typo corrections we are allowed to perform.
|
||||
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
|
||||
unsigned TypoCorrectionLimit = 0;
|
||||
|
||||
@@ -462,6 +462,10 @@ def warn_on_potentially_unavailable_enum_case : Flag<["-"],
|
||||
"warn-on-potentially-unavailable-enum-case">,
|
||||
HelpText<"Downgrade potential unavailability of enum case to a warning">;
|
||||
|
||||
def warn_on_editor_placeholder : Flag<["-"],
|
||||
"warn-on-editor-placeholder">,
|
||||
HelpText<"Downgrade the editor placeholder error to a warning">;
|
||||
|
||||
def report_errors_to_debugger : Flag<["-"], "report-errors-to-debugger">,
|
||||
HelpText<"Deprecated, will be removed in future versions.">;
|
||||
|
||||
|
||||
@@ -467,6 +467,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
|
||||
Opts.WarnOnPotentiallyUnavailableEnumCase |=
|
||||
Args.hasArg(OPT_warn_on_potentially_unavailable_enum_case);
|
||||
Opts.WarnOnEditorPlaceholder |= Args.hasArg(OPT_warn_on_editor_placeholder);
|
||||
|
||||
if (auto A = Args.getLastArg(OPT_enable_access_control,
|
||||
OPT_disable_access_control)) {
|
||||
Opts.EnableAccessControl
|
||||
|
||||
@@ -2145,9 +2145,10 @@ void Lexer::tryLexEditorPlaceholder() {
|
||||
if (Ptr[0] == '<' && Ptr[1] == '#')
|
||||
break;
|
||||
if (Ptr[0] == '#' && Ptr[1] == '>') {
|
||||
// Found it. Flag it as error (or warning, if in playground mode) for the
|
||||
// rest of the compiler pipeline and lex it as an identifier.
|
||||
if (LangOpts.Playground) {
|
||||
// Found it. Flag it as error (or warning, if in playground mode or we've
|
||||
// been asked to warn) for the rest of the compiler pipeline and lex it
|
||||
// as an identifier.
|
||||
if (LangOpts.Playground || LangOpts.WarnOnEditorPlaceholder) {
|
||||
diagnose(TokStart, diag::lex_editor_placeholder_in_playground);
|
||||
} else {
|
||||
diagnose(TokStart, diag::lex_editor_placeholder);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library %import-libdispatch) | %FileCheck %s
|
||||
|
||||
// REQUIRES: rdar82092187
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: concurrency
|
||||
// REQUIRES: libdispatch
|
||||
|
||||
@@ -14,9 +14,9 @@ typealias NestedAliasCallback = SomeCallback
|
||||
// 1. Check various functions for having/not having async alternatives
|
||||
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+4):1 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+3):6 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):12 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):20 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+3):6 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):12 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):20 | %FileCheck -check-prefix=ASYNC-SIMPLE %s
|
||||
func simple(/*cs*/ completion: @escaping (String) -> Void /*ce*/) { }
|
||||
// ASYNC-SIMPLE: basic.swift [[# @LINE-1]]:1 -> [[# @LINE-1]]:1
|
||||
// ASYNC-SIMPLE-NEXT: @available(*, renamed: "simple()")
|
||||
@@ -113,7 +113,7 @@ func errorOnly(completion: @escaping (Error?) -> Void) { }
|
||||
// ASYNC-ERRORONLY-NEXT: }
|
||||
// ASYNC-ERRORONLY: func errorOnly() async throws { }
|
||||
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ASYNC-ERRORNONOPTIONALRESULT %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ASYNC-ERRORNONOPTIONALRESULT %s
|
||||
func errorNonOptionalResult(completion: @escaping (String, Error?) -> Void) { }
|
||||
// ASYNC-ERRORNONOPTIONALRESULT: {
|
||||
// ASYNC-ERRORNONOPTIONALRESULT-NEXT: Task {
|
||||
@@ -253,7 +253,7 @@ func mixed(_ completion: @escaping (String?, Int) -> Void) { }
|
||||
// MIXED-NEXT: }
|
||||
// MIXED: func mixed() async -> (String?, Int) { }
|
||||
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MIXED-OPTIONAL-ERROR %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MIXED-OPTIONAL-ERROR %s
|
||||
func mixedOptionalError(_ completion: @escaping (String?, Int, Error?) -> Void) { }
|
||||
// MIXED-OPTIONAL-ERROR: {
|
||||
// MIXED-OPTIONAL-ERROR-NEXT: Task {
|
||||
@@ -377,7 +377,7 @@ protocol MyProtocol {
|
||||
}
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-COMPLETION %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-COMPLETION %s
|
||||
func nonCompletion(a: Int) { }
|
||||
// NON-COMPLETION: func nonCompletion(a: Int) async { }
|
||||
|
||||
@@ -387,27 +387,27 @@ func nonEscapingCompletion(completion: (Int) -> Void) { }
|
||||
// NON-ESCAPING-COMPLETION: func nonEscapingCompletion(completion: (Int) -> Void) async { }
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MULTIPLE-RESULTS %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MULTIPLE-RESULTS %s
|
||||
func multipleResults(completion: @escaping (Result<String, Error>, Result<String, Error>) -> Void) { }
|
||||
// MULTIPLE-RESULTS: func multipleResults(completion: @escaping (Result<String, Error>, Result<String, Error>) -> Void) async { }
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-VOID %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-VOID %s
|
||||
func nonVoid(completion: @escaping (String) -> Void) -> Int { return 0 }
|
||||
// NON-VOID: func nonVoid(completion: @escaping (String) -> Void) async -> Int { return 0 }
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=COMPLETION-NON-VOID %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=COMPLETION-NON-VOID %s
|
||||
func completionNonVoid(completion: @escaping (String) -> Int) -> Void { }
|
||||
// COMPLETION-NON-VOID: func completionNonVoid(completion: @escaping (String) -> Int) async -> Void { }
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ALREADY-THROWS %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ALREADY-THROWS %s
|
||||
func alreadyThrows(completion: @escaping (String) -> Void) throws { }
|
||||
// ALREADY-THROWS: func alreadyThrows(completion: @escaping (String) -> Void) async throws { }
|
||||
|
||||
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):1
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=AUTO-CLOSURE %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=AUTO-CLOSURE %s
|
||||
func noParamAutoclosure(completion: @escaping @autoclosure () -> Void) { }
|
||||
// AUTO-CLOSURE: func noParamAutoclosure(completion: @escaping @autoclosure () -> Void) async { }
|
||||
|
||||
@@ -640,13 +640,17 @@ func testSkipAssign() {
|
||||
// SKIP-ASSIGN-FUNC-NEXT: print("assigned"){{$}}
|
||||
// SKIP-ASSIGN-FUNC-NEXT: }{{$}}
|
||||
|
||||
// Same as noParamAutoclosure defined above, but used just for the test below.
|
||||
// This avoids a compiler error when converting noParamAutoclosure to async.
|
||||
func noParamAutoclosure2(completion: @escaping @autoclosure () -> Void) {}
|
||||
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefixes=SKIP-AUTOCLOSURE-FUNC %s
|
||||
func testSkipAutoclosure() {
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
noParamAutoclosure(completion: print("autoclosure"))
|
||||
noParamAutoclosure2(completion: print("autoclosure"))
|
||||
}
|
||||
// SKIP-AUTOCLOSURE-FUNC: {{^}}func testSkipAutoclosure() async {
|
||||
// SKIP-AUTOCLOSURE-FUNC: noParamAutoclosure(completion: print("autoclosure")){{$}}
|
||||
// SKIP-AUTOCLOSURE-FUNC: noParamAutoclosure2(completion: print("autoclosure")){{$}}
|
||||
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=EMPTY-CAPTURE %s
|
||||
func testEmptyCapture() {
|
||||
|
||||
@@ -7,443 +7,458 @@
|
||||
import Foundation
|
||||
import ConvertBoolObjC
|
||||
|
||||
func boolWithErr() async throws -> Bool { true }
|
||||
func boolWithErr(completion: @escaping (Bool, Error?) -> Void) {}
|
||||
|
||||
func multipleBoolWithErr() async throws -> (String, Bool, Bool) { ("", true, true) }
|
||||
func multipleBoolWithErr(completion: @escaping (String?, Bool, Bool, Error?) -> Void) {}
|
||||
|
||||
func optionalBoolWithErr() async throws -> (String, Bool, Bool) { ("", true, true) }
|
||||
func optionalBoolWithErr(completion: @escaping (String?, Bool?, Bool, Error?) -> Void) {}
|
||||
|
||||
// All 7 of the below should generate the same refactoring.
|
||||
func testConvertBool() async throws {
|
||||
// All 7 of the below should generate the same refactoring.
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b && err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b && err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if err != nil && b == false {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b == true && err == nil {
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b && err == nil {
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR: do {
|
||||
// BOOL-WITH-ERR-NEXT: let b = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-NEXT: print("not err")
|
||||
// BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR-NEXT: fatalError("oh no \(err)")
|
||||
// BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// These 3 should both generate the same refactoring.
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if success == true && err == nil {
|
||||
print("hi")
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if success && err == nil {
|
||||
print("hi")
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if err == nil {
|
||||
print("hi")
|
||||
} else if !success {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR2: do {
|
||||
// BOOL-WITH-ERR2-NEXT: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR2-NEXT: print("hi")
|
||||
// BOOL-WITH-ERR2-NEXT: print("not err")
|
||||
// BOOL-WITH-ERR2-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR2-NEXT: fatalError("oh no \(err)")
|
||||
// BOOL-WITH-ERR2-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR3 %s
|
||||
boolWithErr { failure, err in
|
||||
if failure {
|
||||
print("a \(err!)")
|
||||
} else if .random() {
|
||||
print("b")
|
||||
} else {
|
||||
print("c")
|
||||
}
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR3: do {
|
||||
// BOOL-WITH-ERR3-NEXT: let failure = try await boolWithErr()
|
||||
// BOOL-WITH-ERR3-NEXT: if .random() {
|
||||
// BOOL-WITH-ERR3-NEXT: print("b")
|
||||
// BOOL-WITH-ERR3-NEXT: } else {
|
||||
// BOOL-WITH-ERR3-NEXT: print("c")
|
||||
// BOOL-WITH-ERR3-NEXT: }
|
||||
// BOOL-WITH-ERR3-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR3-NEXT: print("a \(err)")
|
||||
// BOOL-WITH-ERR3-NEXT: }
|
||||
|
||||
// Don't handle the below example as the force unwrap of err takes place under a different condition.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
if err != nil {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
if !success {
|
||||
_ = err != nil ? fatalError("oh no \(err!)") : fatalError("some worries")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-DONT-HANDLE: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE-NEXT: if <#err#> != nil {
|
||||
// BOOL-DONT-HANDLE-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE-NEXT: _ = <#err#> != nil ? fatalError("oh no \(<#err#>!)") : fatalError("some worries")
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: print("not err")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE2 %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
func doThings() {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
doThings()
|
||||
print("not err")
|
||||
}
|
||||
if !success {
|
||||
let doThings = {
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b && err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
doThings()
|
||||
print("not err")
|
||||
}
|
||||
if !success {
|
||||
while err != nil {
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b && err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
if !success {
|
||||
for _: Int in [] {
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if err != nil && b == false {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
print("not err")
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if b == true && err == nil {
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR %s
|
||||
boolWithErr { b, err in
|
||||
if !b && err == nil {
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR: do {
|
||||
// BOOL-WITH-ERR-NEXT: let b = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-NEXT: print("not err")
|
||||
// BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR-NEXT: fatalError("oh no \(err)")
|
||||
// BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// These 3 should both generate the same refactoring.
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if success == true && err == nil {
|
||||
print("hi")
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if success && err == nil {
|
||||
print("hi")
|
||||
} else {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR2 %s
|
||||
boolWithErr { success, err in
|
||||
if err == nil {
|
||||
print("hi")
|
||||
} else if !success {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR2: do {
|
||||
// BOOL-WITH-ERR2-NEXT: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR2-NEXT: print("hi")
|
||||
// BOOL-WITH-ERR2-NEXT: print("not err")
|
||||
// BOOL-WITH-ERR2-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR2-NEXT: fatalError("oh no \(err)")
|
||||
// BOOL-WITH-ERR2-NEXT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR3 %s
|
||||
boolWithErr { failure, err in
|
||||
if failure {
|
||||
print("a \(err!)")
|
||||
} else if .random() {
|
||||
print("b")
|
||||
} else {
|
||||
print("c")
|
||||
}
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR3: do {
|
||||
// BOOL-WITH-ERR3-NEXT: let failure = try await boolWithErr()
|
||||
// BOOL-WITH-ERR3-NEXT: if .random() {
|
||||
// BOOL-WITH-ERR3-NEXT: print("b")
|
||||
// BOOL-WITH-ERR3-NEXT: } else {
|
||||
// BOOL-WITH-ERR3-NEXT: print("c")
|
||||
// BOOL-WITH-ERR3-NEXT: }
|
||||
// BOOL-WITH-ERR3-NEXT: } catch let err {
|
||||
// BOOL-WITH-ERR3-NEXT: print("a \(err)")
|
||||
// BOOL-WITH-ERR3-NEXT: }
|
||||
|
||||
// Don't handle the below example as the force unwrap of err takes place under a different condition.
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
if err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
_ = err != nil ? fatalError("oh no \(err!)") : fatalError("some worries")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-DONT-HANDLE: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE-NEXT: if <#err#> != nil {
|
||||
// BOOL-DONT-HANDLE-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE-NEXT: _ = <#err#> != nil ? fatalError("oh no \(<#err#>!)") : fatalError("some worries")
|
||||
// BOOL-DONT-HANDLE-NEXT: }
|
||||
// BOOL-DONT-HANDLE-NEXT: print("not err")
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE2 %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
func doThings() {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
doThings()
|
||||
}
|
||||
if !success {
|
||||
let doThings = {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
doThings()
|
||||
}
|
||||
if !success {
|
||||
while err != nil {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
for _: Int in [] {
|
||||
fatalError("oh no \(err!)")
|
||||
}
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// FIXME: The 'err' in doThings() should become a placeholder (rdar://78509286).
|
||||
// BOOL-DONT-HANDLE2: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: func doThings() {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(err!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: doThings()
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: let doThings = {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: doThings()
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: while <#err#> != nil {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: for _: Int in [] {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: print("not err")
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE3 %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
fatalError("oh no maybe \(String(describing: err))")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// err is not force unwrapped, so don't handle.
|
||||
|
||||
// BOOL-DONT-HANDLE3: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE3-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE3-NEXT: fatalError("oh no maybe \(String(describing: <#err#>))")
|
||||
// BOOL-DONT-HANDLE3-NEXT: }
|
||||
// BOOL-DONT-HANDLE3-NEXT: print("not err")
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE4 %s
|
||||
boolWithErr { failure, err in
|
||||
if failure {
|
||||
print("a")
|
||||
} else if .random() {
|
||||
print("b \(err!)")
|
||||
} else {
|
||||
print("c")
|
||||
}
|
||||
}
|
||||
|
||||
// Don't handle the case where the err unwrap occurs in an unrelated else if
|
||||
// clause.
|
||||
|
||||
// BOOL-DONT-HANDLE4: let failure = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE4-NEXT: if failure {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("a")
|
||||
// BOOL-DONT-HANDLE4-NEXT: } else if .random() {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("b \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE4-NEXT: } else {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("c")
|
||||
// BOOL-DONT-HANDLE4-NEXT: }
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR-SILLY %s
|
||||
boolWithErr { success, err in
|
||||
if success == false && err == nil {
|
||||
print("ummm wat \(err!)")
|
||||
return
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR-SILLY: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: if success == false && <#err#> == nil {
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: <#return#>
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: }
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: print("not err")
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR-SILLY2 %s
|
||||
boolWithErr { success, err in
|
||||
if success {
|
||||
print("ummm wat \(err!)")
|
||||
} else {
|
||||
print("ummm wat \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// The err unwrap is in both blocks, so it's not clear what to classify as.
|
||||
|
||||
// BOOL-WITH-ERR-SILLY2: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: if success {
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: } else {
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=MULTI-BOOL-WITH-ERR %s
|
||||
multipleBoolWithErr { str, b1, b2, err in
|
||||
if !b1 && !b2 {
|
||||
print("a \(err!)")
|
||||
}
|
||||
if b1, b2 {
|
||||
print("b \(err!)")
|
||||
}
|
||||
if !b1 {
|
||||
print("c \(err!)")
|
||||
}
|
||||
if !b2 {
|
||||
print("d \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// Don't handle the case where multiple flag checks are done in a single
|
||||
// condition, because it's not exactly clear what the user is doing. It's a
|
||||
// little unfortunate that we'll allow multiple flag checks in seperate
|
||||
// conditions, but both of these cases seem somewhat uncommon, and there's no
|
||||
// real way to completely enforce a single flag param across e.g multiple calls
|
||||
// to the same function, so this is probably okay for now.
|
||||
|
||||
// MULTI-BOOL-WITH-ERR: do {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: let (str, b1, b2) = try await multipleBoolWithErr()
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: if !<#b1#> && !<#b2#> {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("a \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: if <#b1#>, <#b2#> {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("b \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("c \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("d \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OPT-BOOL-WITH-ERR %s
|
||||
optionalBoolWithErr { str, optBool, b, err in
|
||||
if optBool != nil {
|
||||
print("a \(err!)")
|
||||
}
|
||||
if optBool == nil {
|
||||
print("b \(err!)")
|
||||
}
|
||||
if optBool == true {
|
||||
print("c \(err!)")
|
||||
}
|
||||
if ((optBool) == (false)) {
|
||||
print("d \(err!)")
|
||||
}
|
||||
if optBool == false {
|
||||
print("e \(String(describing: err))")
|
||||
}
|
||||
if optBool != true {
|
||||
print("f \(err!)")
|
||||
}
|
||||
if b {
|
||||
print("g \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// It's a little unfortunate that print("a \(<#err#>!)") gets classified in the success
|
||||
// block below, but it doesn't seem like a case that's likely to come up, as optBool
|
||||
// would then be inaccessible in the error block.
|
||||
|
||||
// OPT-BOOL-WITH-ERR: do {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: let (str, optBool, b) = try await optionalBoolWithErr()
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("a \(<#err#>!)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: if <#optBool#> == false {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("e \(String(describing: <#err#>))")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
// OPT-BOOL-WITH-ERR-NEXT: if <#optBool#> != true {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("f \(<#err#>!)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
// OPT-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("b \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("c \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("d \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("g \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OBJC-BOOL-WITH-ERR %s
|
||||
ClassWithHandlerMethods.firstBoolFlagSuccess("") { str, success, unrelated, err in
|
||||
if !unrelated {
|
||||
print(err!)
|
||||
}
|
||||
if !success {
|
||||
print("oh no")
|
||||
}
|
||||
if !success {
|
||||
print(err!)
|
||||
}
|
||||
if success {
|
||||
print("woo")
|
||||
}
|
||||
if str != nil {
|
||||
print("also woo")
|
||||
}
|
||||
}
|
||||
|
||||
// OBJC-BOOL-WITH-ERR: do {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: let (str, success, unrelated) = try await ClassWithHandlerMethods.firstBoolFlagSuccess("")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: if !unrelated {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print(<#err#>!)
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("woo")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("also woo")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("oh no")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print(err)
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// We cannot use refactor-check-compiles, as a placeholder cannot be force unwrapped.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OBJC-BOOL-WITH-ERR2 %s
|
||||
ClassWithHandlerMethods.secondBoolFlagFailure("") { str, unrelated, failure, err in
|
||||
if unrelated {
|
||||
print(err!)
|
||||
}
|
||||
if failure {
|
||||
print("oh no")
|
||||
}
|
||||
if failure {
|
||||
print(err!)
|
||||
}
|
||||
if !failure {
|
||||
print("woo")
|
||||
}
|
||||
if str != nil {
|
||||
print("also woo")
|
||||
}
|
||||
if failure && err == nil {
|
||||
print("wat")
|
||||
}
|
||||
if failure && err != nil {
|
||||
print("neat")
|
||||
}
|
||||
if failure, let _ = err {
|
||||
print("neato")
|
||||
}
|
||||
}
|
||||
|
||||
// OBJC-BOOL-WITH-ERR2: do {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: let (str, unrelated, failure) = try await ClassWithHandlerMethods.secondBoolFlagFailure("")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: if unrelated {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print(<#err#>!)
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("woo")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("also woo")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: if failure && <#err#> == nil {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("wat")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: } catch let err {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("oh no")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print(err)
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("neat")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("neato")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
}
|
||||
|
||||
// FIXME: The 'err' in doThings() should become a placeholder (rdar://78509286).
|
||||
// BOOL-DONT-HANDLE2: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: func doThings() {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(err!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: doThings()
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: let doThings = {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: doThings()
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: while <#err#> != nil {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE2-NEXT: for _: Int in [] {
|
||||
// BOOL-DONT-HANDLE2-NEXT: fatalError("oh no \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: }
|
||||
// BOOL-DONT-HANDLE2-NEXT: print("not err")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE3 %s
|
||||
boolWithErr { success, err in
|
||||
if !success {
|
||||
fatalError("oh no maybe \(String(describing: err))")
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// err is not force unwrapped, so don't handle.
|
||||
|
||||
// BOOL-DONT-HANDLE3: let success = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE3-NEXT: if !success {
|
||||
// BOOL-DONT-HANDLE3-NEXT: fatalError("oh no maybe \(String(describing: <#err#>))")
|
||||
// BOOL-DONT-HANDLE3-NEXT: }
|
||||
// BOOL-DONT-HANDLE3-NEXT: print("not err")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-DONT-HANDLE4 %s
|
||||
boolWithErr { failure, err in
|
||||
if failure {
|
||||
print("a")
|
||||
} else if .random() {
|
||||
print("b \(err!)")
|
||||
} else {
|
||||
print("c")
|
||||
}
|
||||
}
|
||||
|
||||
// Don't handle the case where the err unwrap occurs in an unrelated else if
|
||||
// clause.
|
||||
|
||||
// BOOL-DONT-HANDLE4: let failure = try await boolWithErr()
|
||||
// BOOL-DONT-HANDLE4-NEXT: if failure {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("a")
|
||||
// BOOL-DONT-HANDLE4-NEXT: } else if .random() {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("b \(<#err#>!)")
|
||||
// BOOL-DONT-HANDLE4-NEXT: } else {
|
||||
// BOOL-DONT-HANDLE4-NEXT: print("c")
|
||||
// BOOL-DONT-HANDLE4-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR-SILLY %s
|
||||
boolWithErr { success, err in
|
||||
if success == false && err == nil {
|
||||
print("ummm wat \(err!)")
|
||||
return
|
||||
}
|
||||
print("not err")
|
||||
}
|
||||
|
||||
// BOOL-WITH-ERR-SILLY: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: if success == false && <#err#> == nil {
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: <#return#>
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: }
|
||||
// BOOL-WITH-ERR-SILLY-NEXT: print("not err")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=BOOL-WITH-ERR-SILLY2 %s
|
||||
boolWithErr { success, err in
|
||||
if success {
|
||||
print("ummm wat \(err!)")
|
||||
} else {
|
||||
print("ummm wat \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// The err unwrap is in both blocks, so it's not clear what to classify as.
|
||||
|
||||
// BOOL-WITH-ERR-SILLY2: let success = try await boolWithErr()
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: if success {
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: } else {
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: print("ummm wat \(<#err#>!)")
|
||||
// BOOL-WITH-ERR-SILLY2-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=MULTI-BOOL-WITH-ERR %s
|
||||
multipleBoolWithErr { str, b1, b2, err in
|
||||
if !b1 && !b2 {
|
||||
print("a \(err!)")
|
||||
}
|
||||
if b1, b2 {
|
||||
print("b \(err!)")
|
||||
}
|
||||
if !b1 {
|
||||
print("c \(err!)")
|
||||
}
|
||||
if !b2 {
|
||||
print("d \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// Don't handle the case where multiple flag checks are done in a single
|
||||
// condition, because it's not exactly clear what the user is doing. It's a
|
||||
// little unfortunate that we'll allow multiple flag checks in seperate
|
||||
// conditions, but both of these cases seem somewhat uncommon, and there's no
|
||||
// real way to completely enforce a single flag param across e.g multiple calls
|
||||
// to the same function, so this is probably okay for now.
|
||||
|
||||
// MULTI-BOOL-WITH-ERR: do {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: let (str, b1, b2) = try await multipleBoolWithErr()
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: if !<#b1#> && !<#b2#> {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("a \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: if <#b1#>, <#b2#> {
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("b \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("c \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: print("d \(err)")
|
||||
// MULTI-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OPT-BOOL-WITH-ERR %s
|
||||
optionalBoolWithErr { str, optBool, b, err in
|
||||
if optBool != nil {
|
||||
print("a \(err!)")
|
||||
}
|
||||
if optBool == nil {
|
||||
print("b \(err!)")
|
||||
}
|
||||
if optBool == true {
|
||||
print("c \(err!)")
|
||||
}
|
||||
if ((optBool) == (false)) {
|
||||
print("d \(err!)")
|
||||
}
|
||||
if optBool == false {
|
||||
print("e \(String(describing: err))")
|
||||
}
|
||||
if optBool != true {
|
||||
print("f \(err!)")
|
||||
}
|
||||
if b {
|
||||
print("g \(err!)")
|
||||
}
|
||||
}
|
||||
|
||||
// It's a little unfortunate that print("a \(<#err#>!)") gets classified in the success
|
||||
// block below, but it doesn't seem like a case that's likely to come up, as optBool
|
||||
// would then be inaccessible in the error block.
|
||||
|
||||
// OPT-BOOL-WITH-ERR: do {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: let (str, optBool, b) = try await optionalBoolWithErr()
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("a \(<#err#>!)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: if <#optBool#> == false {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("e \(String(describing: <#err#>))")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
// OPT-BOOL-WITH-ERR-NEXT: if <#optBool#> != true {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("f \(<#err#>!)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
// OPT-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("b \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("c \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("d \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: print("g \(err)")
|
||||
// OPT-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OBJC-BOOL-WITH-ERR %s
|
||||
ClassWithHandlerMethods.firstBoolFlagSuccess("") { str, success, unrelated, err in
|
||||
if !unrelated {
|
||||
print(err!)
|
||||
}
|
||||
if !success {
|
||||
print("oh no")
|
||||
}
|
||||
if !success {
|
||||
print(err!)
|
||||
}
|
||||
if success {
|
||||
print("woo")
|
||||
}
|
||||
if str != nil {
|
||||
print("also woo")
|
||||
}
|
||||
}
|
||||
|
||||
// OBJC-BOOL-WITH-ERR: do {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: let (str, success, unrelated) = try await ClassWithHandlerMethods.firstBoolFlagSuccess("")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: if !unrelated {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print(<#err#>!)
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("woo")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("also woo")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: } catch let err {
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print("oh no")
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: print(err)
|
||||
// OBJC-BOOL-WITH-ERR-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OBJC-BOOL-WITH-ERR2 %s
|
||||
ClassWithHandlerMethods.secondBoolFlagFailure("") { str, unrelated, failure, err in
|
||||
if unrelated {
|
||||
print(err!)
|
||||
}
|
||||
if failure {
|
||||
print("oh no")
|
||||
}
|
||||
if failure {
|
||||
print(err!)
|
||||
}
|
||||
if !failure {
|
||||
print("woo")
|
||||
}
|
||||
if str != nil {
|
||||
print("also woo")
|
||||
}
|
||||
if failure && err == nil {
|
||||
print("wat")
|
||||
}
|
||||
if failure && err != nil {
|
||||
print("neat")
|
||||
}
|
||||
if failure, let _ = err {
|
||||
print("neato")
|
||||
}
|
||||
}
|
||||
|
||||
// OBJC-BOOL-WITH-ERR2: do {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: let (str, unrelated, failure) = try await ClassWithHandlerMethods.secondBoolFlagFailure("")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: if unrelated {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print(<#err#>!)
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("woo")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("also woo")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: if failure && <#err#> == nil {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("wat")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: } catch let err {
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("oh no")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print(err)
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("neat")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: print("neato")
|
||||
// OBJC-BOOL-WITH-ERR2-NEXT: }
|
||||
|
||||
@@ -269,7 +269,7 @@ func voidResultCompletion(completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
// VOID-RESULT-HANDLER-NEXT: }
|
||||
|
||||
// rdar://77789360 Make sure we don't print a double return statement.
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING %s
|
||||
// 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)
|
||||
}
|
||||
@@ -279,6 +279,8 @@ func testReturnHandling(_ completion: @escaping (String?, Error?) -> Void) {
|
||||
|
||||
// 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
|
||||
|
||||
@@ -1,215 +1,226 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// REQUIRES: concurrency
|
||||
|
||||
func manyWithError() async throws -> (String, Int) { ("", 0) }
|
||||
func manyWithError(_ completion: @escaping (String?, Int?, Error?) -> Void) { }
|
||||
|
||||
func mixed() async -> (String, Int) { ("", 0) }
|
||||
func mixed(_ completion: @escaping (String?, Int) -> Void) { }
|
||||
|
||||
func mixedError() async throws -> (String, Int) { ("", 0) }
|
||||
func mixedError(_ completion: @escaping (String?, Int, Error?) -> Void) { }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let bad = err {
|
||||
print("got error \(bad)")
|
||||
return
|
||||
func testParamsMulti() async throws {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let bad = err {
|
||||
print("got error \(bad)")
|
||||
return
|
||||
}
|
||||
if let str = res1, let i = res2 {
|
||||
print("got result \(str)")
|
||||
print("got result \(i)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
if let str = res1, let i = res2 {
|
||||
// MANYBOUND: do {
|
||||
// MANYBOUND-NEXT: let (str, i) = try await manyWithError()
|
||||
// MANYBOUND-NEXT: print("before")
|
||||
// MANYBOUND-NEXT: print("got result \(str)")
|
||||
// MANYBOUND-NEXT: print("got result \(i)")
|
||||
// MANYBOUND-NEXT: print("after")
|
||||
// MANYBOUND-NEXT: } catch let bad {
|
||||
// MANYBOUND-NEXT: print("got error \(bad)")
|
||||
// MANYBOUND-NEXT: }
|
||||
|
||||
// FIXME: This case is a little tricky: Being in the else block of 'if let str = res1'
|
||||
// should allow us to place 'if let i = res2' in the failure block. However, this
|
||||
// is a success condition, so we still place it in the success block. Really what
|
||||
// we need to do here is check to see if manyWithError has an existing async
|
||||
// alternative that still returns optional success values, and allow success
|
||||
// classification in that case. Otherwise, we'd probably be better off leaving
|
||||
// the condition unhandled, as it's not clear what the user is doing.
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND-ERR %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let str = res1 {
|
||||
print("got result \(str)")
|
||||
} else if let i = res2 {
|
||||
print("got result \(i)")
|
||||
} else {
|
||||
print("got error \(err!)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MANYUNBOUND-ERR: do {
|
||||
// MANYUNBOUND-ERR-NEXT: let (str, i) = try await manyWithError()
|
||||
// MANYUNBOUND-ERR-NEXT: print("before")
|
||||
// MANYUNBOUND-ERR-NEXT: print("got result \(str)")
|
||||
// MANYUNBOUND-ERR-NEXT: print("got result \(i)")
|
||||
// MANYUNBOUND-ERR-NEXT: print("after")
|
||||
// MANYUNBOUND-ERR-NEXT: } catch let err {
|
||||
// MANYUNBOUND-ERR-NEXT: print("got error \(err)")
|
||||
// MANYUNBOUND-ERR-NEXT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let bad = err {
|
||||
print("got error \(bad)")
|
||||
return
|
||||
}
|
||||
if let str = res1 {
|
||||
print("got result \(str)")
|
||||
}
|
||||
if let i = res2 {
|
||||
print("got result \(i)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED-COND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if res1 != nil && res2 == nil {
|
||||
print("got result \(res1!)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MIXED-COND: convert_params_multi.swift
|
||||
// MIXED-COND-NEXT: let (res1, res2) = try await manyWithError()
|
||||
// MIXED-COND-NEXT: print("before")
|
||||
// MIXED-COND-NEXT: if <#res1#> != nil && <#res2#> == nil {
|
||||
// MIXED-COND-NEXT: print("got result \(res1)")
|
||||
// MIXED-COND-NEXT: }
|
||||
// MIXED-COND-NEXT: print("after")
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED-CONDELSE %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if res1 != nil && res2 == nil {
|
||||
print("got result \(res1!)")
|
||||
} else {
|
||||
print("bad")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MIXED-CONDELSE: var res1: String? = nil
|
||||
// MIXED-CONDELSE-NEXT: var res2: Int? = nil
|
||||
// MIXED-CONDELSE-NEXT: var err: Error? = nil
|
||||
// MIXED-CONDELSE-NEXT: do {
|
||||
// MIXED-CONDELSE-NEXT: (res1, res2) = try await manyWithError()
|
||||
// MIXED-CONDELSE-NEXT: } catch {
|
||||
// MIXED-CONDELSE-NEXT: err = error
|
||||
// MIXED-CONDELSE-NEXT: }
|
||||
// MIXED-CONDELSE-EMPTY:
|
||||
// MIXED-CONDELSE-NEXT: print("before")
|
||||
// MIXED-CONDELSE-NEXT: if res1 != nil && res2 == nil {
|
||||
// MIXED-CONDELSE-NEXT: print("got result \(res1!)")
|
||||
// MIXED-CONDELSE-NEXT: } else {
|
||||
// MIXED-CONDELSE-NEXT: print("bad")
|
||||
// MIXED-CONDELSE-NEXT: }
|
||||
// MIXED-CONDELSE-NEXT: print("after")
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND-ERR %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard let str = res1, let i = res2 else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
}
|
||||
print("got result \(str)")
|
||||
print("got result \(i)")
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MANYBOUND: do {
|
||||
// MANYBOUND-NEXT: let (str, i) = try await manyWithError()
|
||||
// MANYBOUND-NEXT: print("before")
|
||||
// MANYBOUND-NEXT: print("got result \(str)")
|
||||
// MANYBOUND-NEXT: print("got result \(i)")
|
||||
// MANYBOUND-NEXT: print("after")
|
||||
// MANYBOUND-NEXT: } catch let bad {
|
||||
// MANYBOUND-NEXT: print("got error \(bad)")
|
||||
// MANYBOUND-NEXT: }
|
||||
|
||||
// FIXME: This case is a little tricky: Being in the else block of 'if let str = res1'
|
||||
// should allow us to place 'if let i = res2' in the failure block. However, this
|
||||
// is a success condition, so we still place it in the success block. Really what
|
||||
// we need to do here is check to see if manyWithError has an existing async
|
||||
// alternative that still returns optional success values, and allow success
|
||||
// classification in that case. Otherwise, we'd probably be better off leaving
|
||||
// the condition unhandled, as it's not clear what the user is doing.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND-ERR %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let str = res1 {
|
||||
print("got result \(str)")
|
||||
} else if let i = res2 {
|
||||
print("got result \(i)")
|
||||
} else {
|
||||
print("got error \(err!)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MANYUNBOUND-ERR: do {
|
||||
// MANYUNBOUND-ERR-NEXT: let (str, i) = try await manyWithError()
|
||||
// MANYUNBOUND-ERR-NEXT: print("before")
|
||||
// MANYUNBOUND-ERR-NEXT: print("got result \(str)")
|
||||
// MANYUNBOUND-ERR-NEXT: print("got result \(i)")
|
||||
// MANYUNBOUND-ERR-NEXT: print("after")
|
||||
// MANYUNBOUND-ERR-NEXT: } catch let err {
|
||||
// MANYUNBOUND-ERR-NEXT: print("got error \(err)")
|
||||
// MANYUNBOUND-ERR-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if let bad = err {
|
||||
print("got error \(bad)")
|
||||
return
|
||||
}
|
||||
if let str = res1 {
|
||||
print("got result \(str)")
|
||||
}
|
||||
if let i = res2 {
|
||||
print("got result \(i)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED-COND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if res1 != nil && res2 == nil {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard res1 != nil && res2 != nil && err == nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MIXED-COND: convert_params_multi.swift
|
||||
// MIXED-COND-NEXT: let (res1, res2) = try await manyWithError()
|
||||
// MIXED-COND-NEXT: print("before")
|
||||
// MIXED-COND-NEXT: if <#res1#> != nil && <#res2#> == nil {
|
||||
// MIXED-COND-NEXT: print("got result \(res1)")
|
||||
// MIXED-COND-NEXT: }
|
||||
// MIXED-COND-NEXT: print("after")
|
||||
// MANYUNBOUND: do {
|
||||
// MANYUNBOUND-NEXT: let (res1, res2) = try await manyWithError()
|
||||
// MANYUNBOUND-NEXT: print("before")
|
||||
// MANYUNBOUND-NEXT: print("got result \(res1)")
|
||||
// MANYUNBOUND-NEXT: print("got result \(res2)")
|
||||
// MANYUNBOUND-NEXT: print("after")
|
||||
// MANYUNBOUND-NEXT: } catch let err {
|
||||
// MANYUNBOUND-NEXT: print("got error \(err)")
|
||||
// MANYUNBOUND-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED-CONDELSE %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
if res1 != nil && res2 == nil {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard res1 != nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
} else {
|
||||
print("bad")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MIXED-CONDELSE: var res1: String? = nil
|
||||
// MIXED-CONDELSE-NEXT: var res2: Int? = nil
|
||||
// MIXED-CONDELSE-NEXT: var err: Error? = nil
|
||||
// MIXED-CONDELSE-NEXT: do {
|
||||
// MIXED-CONDELSE-NEXT: (res1, res2) = try await manyWithError()
|
||||
// MIXED-CONDELSE-NEXT: } catch {
|
||||
// MIXED-CONDELSE-NEXT: err = error
|
||||
// MIXED-CONDELSE-NEXT: }
|
||||
// MIXED-CONDELSE-EMPTY:
|
||||
// MIXED-CONDELSE-NEXT: print("before")
|
||||
// MIXED-CONDELSE-NEXT: if res1 != nil && res2 == nil {
|
||||
// MIXED-CONDELSE-NEXT: print("got result \(res1!)")
|
||||
// MIXED-CONDELSE-NEXT: } else {
|
||||
// MIXED-CONDELSE-NEXT: print("bad")
|
||||
// MIXED-CONDELSE-NEXT: }
|
||||
// MIXED-CONDELSE-NEXT: print("after")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND-ERR %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard let str = res1, let i = res2 else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard err == nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
}
|
||||
print("got result \(str)")
|
||||
print("got result \(i)")
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard res1 != nil && res2 != nil && err == nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
// Cannot use refactor-check-compiles, as cannot use non-optional 'str' in
|
||||
// optional binding.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED %s
|
||||
mixed { str, num in
|
||||
print("before")
|
||||
if let res = str {
|
||||
print("got result \(res)")
|
||||
}
|
||||
print("\(num)")
|
||||
print("after")
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
}
|
||||
// MANYUNBOUND: do {
|
||||
// MANYUNBOUND-NEXT: let (res1, res2) = try await manyWithError()
|
||||
// MANYUNBOUND-NEXT: print("before")
|
||||
// MANYUNBOUND-NEXT: print("got result \(res1)")
|
||||
// MANYUNBOUND-NEXT: print("got result \(res2)")
|
||||
// MANYUNBOUND-NEXT: print("after")
|
||||
// MANYUNBOUND-NEXT: } catch let err {
|
||||
// MANYUNBOUND-NEXT: print("got error \(err)")
|
||||
// MANYUNBOUND-NEXT: }
|
||||
// MIXED: convert_params_multi.swift
|
||||
// MIXED-NEXT: let (str, num) = await mixed()
|
||||
// MIXED-NEXT: print("before")
|
||||
// MIXED-NEXT: if let res = str {
|
||||
// MIXED-NEXT: print("got result \(res)")
|
||||
// MIXED-NEXT: }
|
||||
// MIXED-NEXT: print("\(num)")
|
||||
// MIXED-NEXT: print("after")
|
||||
// MIXED-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard res1 != nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MIXED-ERROR %s
|
||||
mixedError { str, num, err in
|
||||
print("before")
|
||||
if let res = str {
|
||||
print("got result \(res)")
|
||||
} else {
|
||||
print("got \(err!)")
|
||||
}
|
||||
print("\(num)")
|
||||
print("after")
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
// MIXED-ERROR: convert_params_multi.swift
|
||||
// MIXED-ERROR-NEXT: do {
|
||||
// MIXED-ERROR-NEXT: let (res, num) = try await mixedError()
|
||||
// MIXED-ERROR-NEXT: print("before")
|
||||
// MIXED-ERROR-NEXT: print("got result \(res)")
|
||||
// MIXED-ERROR-NEXT: print("\(num)")
|
||||
// MIXED-ERROR-NEXT: print("after")
|
||||
// MIXED-ERROR-NEXT: } catch let err {
|
||||
// MIXED-ERROR-NEXT: print("got \(err)")
|
||||
// MIXED-ERROR-NEXT: }
|
||||
// MIXED-ERROR-NOT: }
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MANYUNBOUND %s
|
||||
manyWithError { res1, res2, err in
|
||||
print("before")
|
||||
guard err == nil else {
|
||||
print("got error \(err!)")
|
||||
return
|
||||
}
|
||||
print("got result \(res1!)")
|
||||
print("got result \(res2!)")
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MIXED %s
|
||||
mixed { str, num in
|
||||
print("before")
|
||||
if let res = str {
|
||||
print("got result \(res)")
|
||||
}
|
||||
print("\(num)")
|
||||
print("after")
|
||||
}
|
||||
// MIXED: convert_params_multi.swift
|
||||
// MIXED-NEXT: let (str, num) = await mixed()
|
||||
// MIXED-NEXT: print("before")
|
||||
// MIXED-NEXT: if let res = str {
|
||||
// MIXED-NEXT: print("got result \(res)")
|
||||
// MIXED-NEXT: }
|
||||
// MIXED-NEXT: print("\(num)")
|
||||
// MIXED-NEXT: print("after")
|
||||
// MIXED-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MIXED-ERROR %s
|
||||
mixedError { str, num, err in
|
||||
print("before")
|
||||
if let res = str {
|
||||
print("got result \(res)")
|
||||
} else {
|
||||
print("got \(err!)")
|
||||
}
|
||||
print("\(num)")
|
||||
print("after")
|
||||
}
|
||||
// MIXED-ERROR: convert_params_multi.swift
|
||||
// MIXED-ERROR-NEXT: do {
|
||||
// MIXED-ERROR-NEXT: let (res, num) = try await mixedError()
|
||||
// MIXED-ERROR-NEXT: print("before")
|
||||
// MIXED-ERROR-NEXT: print("got result \(res)")
|
||||
// MIXED-ERROR-NEXT: print("\(num)")
|
||||
// MIXED-ERROR-NEXT: print("after")
|
||||
// MIXED-ERROR-NEXT: } catch let err {
|
||||
// MIXED-ERROR-NEXT: print("got \(err)")
|
||||
// MIXED-ERROR-NEXT: }
|
||||
// MIXED-ERROR-NOT: }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,7 +123,7 @@ func testPatterns() async throws {
|
||||
// FALLBACK-NEXT: guard let (str1, str2) = strs, str1 == "hi" else { fatalError() }
|
||||
// FALLBACK-NEXT: print(str1, str2, err)
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=GUARD-AND-UNHANDLED %s
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=GUARD-AND-UNHANDLED %s
|
||||
stringTupleParam { strs, err in
|
||||
guard let (str1, str2) = strs else { fatalError() }
|
||||
print(str1, str2)
|
||||
@@ -436,6 +436,7 @@ func testNameCollision2(_ completion: @escaping () -> Void) {
|
||||
// NAME-COLLISION2-NEXT: print("b", x, y, z)
|
||||
// NAME-COLLISION2-NEXT: }
|
||||
|
||||
// Cannot use refactor-check-compiles, as cannot pattern match with placeholders.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=TEST-UNHANDLED %s
|
||||
anyCompletion { val, err in
|
||||
if let x = val {
|
||||
@@ -552,7 +553,7 @@ anyResultCompletion { res in
|
||||
|
||||
// Make sure we handle a capture list okay.
|
||||
class C {
|
||||
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=CAPTURE %s
|
||||
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=CAPTURE %s
|
||||
func foo() {
|
||||
let _ = { [weak self] in
|
||||
print(self!)
|
||||
|
||||
@@ -1,513 +1,531 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// REQUIRES: concurrency
|
||||
|
||||
func simple(_ completion: @escaping (Result<String, Error>) -> Void) { }
|
||||
func simple() async throws -> String { "" }
|
||||
|
||||
func simpleWithArg(_ arg: Int) async throws -> String { "" }
|
||||
func simpleWithArg(_ arg: Int, _ completion: @escaping (Result<String, Error>) -> Void) { }
|
||||
|
||||
func noError() async -> String { "" }
|
||||
func noError(_ completion: @escaping (Result<String, Never>) -> Void) { }
|
||||
|
||||
func voidNoError() async {}
|
||||
func voidNoError(completion: @escaping (Result<Void, Never>) -> Void) {}
|
||||
|
||||
func voidError() async throws {}
|
||||
func voidError(completion: @escaping (Result<Void, Error>) -> Void) {}
|
||||
|
||||
func test(_ str: String) -> Bool { return false }
|
||||
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-RESULT %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-RESULT %s
|
||||
func voidResult(completion: @escaping (Result<Void, Never>) -> Void) {}
|
||||
// VOID-RESULT: func voidResult() async {}
|
||||
|
||||
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-AND-ERROR-RESULT %s
|
||||
// RUN: %refactor-check-compiles -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix VOID-AND-ERROR-RESULT %s
|
||||
func voidAndErrorResult(completion: @escaping (Result<Void, Error>) -> Void) {}
|
||||
// VOID-AND-ERROR-RESULT: func voidAndErrorResult() async throws {}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=SIMPLE %s
|
||||
simple { res in
|
||||
print("result \(res)")
|
||||
}
|
||||
// SIMPLE: let res = try await simple()
|
||||
// SIMPLE-NEXT: print("result \(<#res#>)")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NOERROR %s
|
||||
noError { res in
|
||||
print("result \(res)")
|
||||
}
|
||||
// NOERROR: let res = await noError()
|
||||
// NOERROR-NEXT: print("result \(<#res#>)")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
func testResultConversion() async throws {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=SIMPLE %s
|
||||
simple { res in
|
||||
print("result \(res)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// DOBLOCK: do {
|
||||
// DOBLOCK-NEXT: let str = try await simple()
|
||||
// DOBLOCK-NEXT: print("before")
|
||||
// DOBLOCK-NEXT: print("result \(str)")
|
||||
// DOBLOCK-NEXT: print("after")
|
||||
// DOBLOCK-NEXT: } catch let err {
|
||||
// DOBLOCK-NEXT: print("error \(err)")
|
||||
// DOBLOCK-NEXT: }
|
||||
// SIMPLE: let res = try await simple()
|
||||
// SIMPLE-NEXT: print("result \(<#res#>)")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
} else if case .failure(let err) = res {
|
||||
print("error \(err)")
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NOERROR %s
|
||||
noError { res in
|
||||
print("result \(res)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// NOERROR: let res = await noError()
|
||||
// NOERROR-NEXT: print("result \(<#res#>)")
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
break
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
break
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// DOBLOCK: do {
|
||||
// DOBLOCK-NEXT: let str = try await simple()
|
||||
// DOBLOCK-NEXT: print("before")
|
||||
// DOBLOCK-NEXT: print("result \(str)")
|
||||
// DOBLOCK-NEXT: print("after")
|
||||
// DOBLOCK-NEXT: } catch let err {
|
||||
// DOBLOCK-NEXT: print("error \(err)")
|
||||
// DOBLOCK-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
return
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
return
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
} else if case .failure(let err) = res {
|
||||
print("error \(err)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
break
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
break
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// SUCCESS: convert_result.swift
|
||||
// SUCCESS-NEXT: let str = try await simple()
|
||||
// SUCCESS-NEXT: print("before")
|
||||
// SUCCESS-NEXT: print("result \(str)")
|
||||
// SUCCESS-NEXT: print("after")
|
||||
// SUCCESS-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard case .success(let str) = res else {
|
||||
return
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
return
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
return
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
print("result \(str)")
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCKUNBOUND %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard case .success(let str) = res else {
|
||||
print("err")
|
||||
return
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
print("result \(str)")
|
||||
print("after")
|
||||
}
|
||||
// DOBLOCKUNBOUND: do {
|
||||
// DOBLOCKUNBOUND-NEXT: let str = try await simple()
|
||||
// DOBLOCKUNBOUND-NEXT: print("before")
|
||||
// DOBLOCKUNBOUND-NEXT: print("result \(str)")
|
||||
// DOBLOCKUNBOUND-NEXT: print("after")
|
||||
// DOBLOCKUNBOUND-NEXT: } catch {
|
||||
// DOBLOCKUNBOUND-NEXT: print("err")
|
||||
// DOBLOCKUNBOUND-NEXT: }
|
||||
// SUCCESS: convert_result.swift
|
||||
// SUCCESS-NEXT: let str = try await simple()
|
||||
// SUCCESS-NEXT: print("before")
|
||||
// SUCCESS-NEXT: print("result \(str)")
|
||||
// SUCCESS-NEXT: print("after")
|
||||
// SUCCESS-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if let str = try? res.get() {
|
||||
print("result \(str)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=DOBLOCKUNBOUND %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard let str = try? res.get() else {
|
||||
print("err")
|
||||
return
|
||||
}
|
||||
print("result \(str)")
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=UNKNOWN %s
|
||||
simple { res in
|
||||
print("before \(res)")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str) \(try! res.get())")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// UNKNOWN: convert_result.swift
|
||||
// UNKNOWN-NEXT: let str = try await simple()
|
||||
// UNKNOWN-NEXT: print("before \(<#str#>)")
|
||||
// UNKNOWN-NEXT: print("result \(str) \(try! <#str#>.get())")
|
||||
// UNKNOWN-NEXT: print("after")
|
||||
// UNKNOWN-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=UNKNOWNUNBOUND %s
|
||||
simple { res in
|
||||
print("before \(res)")
|
||||
if case .success = res {
|
||||
print("result \(res) \(try! res.get())")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// UNKNOWNUNBOUND: convert_result.swift
|
||||
// UNKNOWNUNBOUND-NEXT: let res = try await simple()
|
||||
// UNKNOWNUNBOUND-NEXT: print("before \(<#res#>)")
|
||||
// UNKNOWNUNBOUND-NEXT: print("result \(<#res#>) \(try! <#res#>.get())")
|
||||
// UNKNOWNUNBOUND-NEXT: print("after")
|
||||
// UNKNOWN-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=MULTIPLE-BINDS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
}
|
||||
if case .success(let str2) = res {
|
||||
print("result \(str2)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MULTIPLE-BINDS: convert_result.swift
|
||||
// MULTIPLE-BINDS-NEXT: let str = try await simple()
|
||||
// MULTIPLE-BINDS-NEXT: print("before")
|
||||
// MULTIPLE-BINDS-NEXT: print("result \(str)")
|
||||
// MULTIPLE-BINDS-NEXT: print("result \(str)")
|
||||
// MULTIPLE-BINDS-NEXT: print("after")
|
||||
// MULTIPLE-BINDS-NOT: }
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
default:
|
||||
print("default")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
default:
|
||||
print("err")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success, .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success, .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success:
|
||||
fallthrough
|
||||
case .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str) where str.hasPrefix("match"):
|
||||
print("pattern matched result \(str)")
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NESTEDRET %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
if test(str) {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard case .success(let str) = res else {
|
||||
return
|
||||
}
|
||||
print("result \(str)")
|
||||
case .failure:
|
||||
break
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// NESTEDRET: convert_result.swift
|
||||
// NESTEDRET-NEXT: let str = try await simple()
|
||||
// NESTEDRET-NEXT: print("before")
|
||||
// NESTEDRET-NEXT: if test(str) {
|
||||
// NESTEDRET-NEXT: <#return#>
|
||||
// NESTEDRET-NEXT: }
|
||||
// NESTEDRET-NEXT: print("result \(str)")
|
||||
// NESTEDRET-NEXT: print("after")
|
||||
// NESTEDRET-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NESTEDBREAK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
if test(str) {
|
||||
break
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCKUNBOUND %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard case .success(let str) = res else {
|
||||
print("err")
|
||||
return
|
||||
}
|
||||
print("result \(str)")
|
||||
case .failure:
|
||||
break
|
||||
print("after")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// NESTEDBREAK: convert_result.swift
|
||||
// NESTEDBREAK-NEXT: let str = try await simple()
|
||||
// NESTEDBREAK-NEXT: print("before")
|
||||
// NESTEDBREAK-NEXT: if test(str) {
|
||||
// NESTEDBREAK-NEXT: <#break#>
|
||||
// NESTEDBREAK-NEXT: }
|
||||
// NESTEDBREAK-NEXT: print("result \(str)")
|
||||
// NESTEDBREAK-NEXT: print("after")
|
||||
// NESTEDBREAK-NOT: }
|
||||
// DOBLOCKUNBOUND: do {
|
||||
// DOBLOCKUNBOUND-NEXT: let str = try await simple()
|
||||
// DOBLOCKUNBOUND-NEXT: print("before")
|
||||
// DOBLOCKUNBOUND-NEXT: print("result \(str)")
|
||||
// DOBLOCKUNBOUND-NEXT: print("after")
|
||||
// DOBLOCKUNBOUND-NEXT: } catch {
|
||||
// DOBLOCKUNBOUND-NEXT: print("err")
|
||||
// DOBLOCKUNBOUND-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NESTEDBREAK-COMMENT %s
|
||||
simple { res in // a
|
||||
// b
|
||||
print("before")
|
||||
// c
|
||||
switch res {
|
||||
// d
|
||||
case .success(let str): // e
|
||||
if test(str) {
|
||||
// f
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=SUCCESS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if let str = try? res.get() {
|
||||
print("result \(str)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=DOBLOCKUNBOUND %s
|
||||
simple { res in
|
||||
print("before")
|
||||
guard let str = try? res.get() else {
|
||||
print("err")
|
||||
return
|
||||
}
|
||||
print("result \(str)")
|
||||
print("after")
|
||||
}
|
||||
|
||||
// Cannot use refactor-check-compiles, as cannot infer type of the 'get' member on the placeholder.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNKNOWN %s
|
||||
simple { res in
|
||||
print("before \(res)")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str) \(try! res.get())")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// UNKNOWN: convert_result.swift
|
||||
// UNKNOWN-NEXT: let str = try await simple()
|
||||
// UNKNOWN-NEXT: print("before \(<#str#>)")
|
||||
// UNKNOWN-NEXT: print("result \(str) \(try! <#str#>.get())")
|
||||
// UNKNOWN-NEXT: print("after")
|
||||
// UNKNOWN-NOT: }
|
||||
|
||||
// Cannot use refactor-check-compiles, as cannot infer type of the 'get' member on the placeholder.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNKNOWNUNBOUND %s
|
||||
simple { res in
|
||||
print("before \(res)")
|
||||
if case .success = res {
|
||||
print("result \(res) \(try! res.get())")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// UNKNOWNUNBOUND: convert_result.swift
|
||||
// UNKNOWNUNBOUND-NEXT: let res = try await simple()
|
||||
// UNKNOWNUNBOUND-NEXT: print("before \(<#res#>)")
|
||||
// UNKNOWNUNBOUND-NEXT: print("result \(<#res#>) \(try! <#res#>.get())")
|
||||
// UNKNOWNUNBOUND-NEXT: print("after")
|
||||
// UNKNOWN-NOT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MULTIPLE-BINDS %s
|
||||
simple { res in
|
||||
print("before")
|
||||
if case .success(let str) = res {
|
||||
print("result \(str)")
|
||||
}
|
||||
if case .success(let str2) = res {
|
||||
print("result \(str2)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// MULTIPLE-BINDS: convert_result.swift
|
||||
// MULTIPLE-BINDS-NEXT: let str = try await simple()
|
||||
// MULTIPLE-BINDS-NEXT: print("before")
|
||||
// MULTIPLE-BINDS-NEXT: print("result \(str)")
|
||||
// MULTIPLE-BINDS-NEXT: print("result \(str)")
|
||||
// MULTIPLE-BINDS-NEXT: print("after")
|
||||
// MULTIPLE-BINDS-NOT: }
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
default:
|
||||
print("default")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
default:
|
||||
print("err")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success, .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success, .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success:
|
||||
fallthrough
|
||||
case .failure:
|
||||
print("either")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: not %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str) where str.hasPrefix("match"):
|
||||
print("pattern matched result \(str)")
|
||||
case .success(let str):
|
||||
print("result \(str)")
|
||||
case .failure(let err):
|
||||
print("error \(err)")
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NESTEDRET %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
if test(str) {
|
||||
return
|
||||
}
|
||||
print("result \(str)")
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// NESTEDRET: convert_result.swift
|
||||
// NESTEDRET-NEXT: let str = try await simple()
|
||||
// NESTEDRET-NEXT: print("before")
|
||||
// NESTEDRET-NEXT: if test(str) {
|
||||
// NESTEDRET-NEXT: <#return#>
|
||||
// NESTEDRET-NEXT: }
|
||||
// NESTEDRET-NEXT: print("result \(str)")
|
||||
// NESTEDRET-NEXT: print("after")
|
||||
// NESTEDRET-NOT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NESTEDBREAK %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch res {
|
||||
case .success(let str):
|
||||
if test(str) {
|
||||
break
|
||||
}
|
||||
print("result \(str)")
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// NESTEDBREAK: convert_result.swift
|
||||
// NESTEDBREAK-NEXT: let str = try await simple()
|
||||
// NESTEDBREAK-NEXT: print("before")
|
||||
// NESTEDBREAK-NEXT: if test(str) {
|
||||
// NESTEDBREAK-NEXT: <#break#>
|
||||
// NESTEDBREAK-NEXT: }
|
||||
// NESTEDBREAK-NEXT: print("result \(str)")
|
||||
// NESTEDBREAK-NEXT: print("after")
|
||||
// NESTEDBREAK-NOT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NESTEDBREAK-COMMENT %s
|
||||
simple { res in // a
|
||||
// b
|
||||
print("before")
|
||||
// c
|
||||
switch res {
|
||||
// d
|
||||
case .success(let str): // e
|
||||
if test(str) {
|
||||
// f
|
||||
break
|
||||
// g
|
||||
}
|
||||
// h
|
||||
print("result \(str)")
|
||||
// i
|
||||
case .failure:
|
||||
// j
|
||||
break
|
||||
// k
|
||||
}
|
||||
// l
|
||||
print("after")
|
||||
// m
|
||||
}
|
||||
// NESTEDBREAK-COMMENT: let str = try await simple()
|
||||
// NESTEDBREAK-COMMENT-NEXT: // a
|
||||
// NESTEDBREAK-COMMENT-NEXT: // b
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("before")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // c
|
||||
// NESTEDBREAK-COMMENT-NEXT: // d
|
||||
// NESTEDBREAK-COMMENT-NEXT: // e
|
||||
// NESTEDBREAK-COMMENT-NEXT: if test(str) {
|
||||
// NESTEDBREAK-COMMENT-NEXT: // f
|
||||
// NESTEDBREAK-COMMENT-NEXT: <#break#>
|
||||
// NESTEDBREAK-COMMENT-NEXT: // g
|
||||
// NESTEDBREAK-COMMENT-NEXT: }
|
||||
// NESTEDBREAK-COMMENT-NEXT: // h
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("result \(str)")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // i
|
||||
// NESTEDBREAK-COMMENT-NEXT: // j
|
||||
// NESTEDBREAK-COMMENT-NEXT: // k
|
||||
// NESTEDBREAK-COMMENT-NEXT: // l
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("after")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // m
|
||||
// NESTEDBREAK-COMMENT-NEXT: {{ }}
|
||||
// NESTEDBREAK-COMMENT-NOT: }
|
||||
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=ERROR-BLOCK-COMMENT %s
|
||||
simple { res in
|
||||
// a
|
||||
print("before")
|
||||
// b
|
||||
switch res {
|
||||
case .success(let str):
|
||||
// c
|
||||
print("result \(str)")
|
||||
// d
|
||||
case .failure:
|
||||
// e
|
||||
print("fail")
|
||||
// f
|
||||
return
|
||||
// g
|
||||
}
|
||||
// h
|
||||
print("result \(str)")
|
||||
print("after")
|
||||
// i
|
||||
case .failure:
|
||||
// j
|
||||
break
|
||||
// k
|
||||
}
|
||||
// l
|
||||
print("after")
|
||||
// m
|
||||
}
|
||||
// NESTEDBREAK-COMMENT: let str = try await simple()
|
||||
// NESTEDBREAK-COMMENT-NEXT: // a
|
||||
// NESTEDBREAK-COMMENT-NEXT: // b
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("before")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // c
|
||||
// NESTEDBREAK-COMMENT-NEXT: // d
|
||||
// NESTEDBREAK-COMMENT-NEXT: // e
|
||||
// NESTEDBREAK-COMMENT-NEXT: if test(str) {
|
||||
// NESTEDBREAK-COMMENT-NEXT: // f
|
||||
// NESTEDBREAK-COMMENT-NEXT: <#break#>
|
||||
// NESTEDBREAK-COMMENT-NEXT: // g
|
||||
// NESTEDBREAK-COMMENT-NEXT: }
|
||||
// NESTEDBREAK-COMMENT-NEXT: // h
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("result \(str)")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // i
|
||||
// NESTEDBREAK-COMMENT-NEXT: // j
|
||||
// NESTEDBREAK-COMMENT-NEXT: // k
|
||||
// NESTEDBREAK-COMMENT-NEXT: // l
|
||||
// NESTEDBREAK-COMMENT-NEXT: print("after")
|
||||
// NESTEDBREAK-COMMENT-NEXT: // m
|
||||
// NESTEDBREAK-COMMENT-EMPTY:
|
||||
// NESTEDBREAK-COMMENT-NOT: }
|
||||
// ERROR-BLOCK-COMMENT: do {
|
||||
// ERROR-BLOCK-COMMENT-NEXT: let str = try await simple()
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // a
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("before")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // b
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // c
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("result \(str)")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // d
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // h
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("after")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // i
|
||||
// ERROR-BLOCK-COMMENT-NEXT: {{ }}
|
||||
// ERROR-BLOCK-COMMENT-NEXT: } catch {
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // e
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("fail")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // f
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // g
|
||||
// ERROR-BLOCK-COMMENT-NEXT: {{ }}
|
||||
// ERROR-BLOCK-COMMENT-NEXT: }
|
||||
// ERROR-BLOCK-COMMENT-NOT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ERROR-BLOCK-COMMENT %s
|
||||
simple { res in
|
||||
// a
|
||||
print("before")
|
||||
// b
|
||||
switch res {
|
||||
case .success(let str):
|
||||
// c
|
||||
print("result \(str)")
|
||||
// d
|
||||
case .failure:
|
||||
// e
|
||||
print("fail")
|
||||
// f
|
||||
return
|
||||
// g
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=VOID-RESULT-CALL %s
|
||||
voidNoError { res in
|
||||
print(res)
|
||||
}
|
||||
// h
|
||||
print("after")
|
||||
// i
|
||||
}
|
||||
// ERROR-BLOCK-COMMENT: do {
|
||||
// ERROR-BLOCK-COMMENT-NEXT: let str = try await simple()
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // a
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("before")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // b
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // c
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("result \(str)")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // d
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // h
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("after")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // i
|
||||
// ERROR-BLOCK-COMMENT-EMPTY:
|
||||
// ERROR-BLOCK-COMMENT-NEXT: } catch {
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // e
|
||||
// ERROR-BLOCK-COMMENT-NEXT: print("fail")
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // f
|
||||
// ERROR-BLOCK-COMMENT-NEXT: // g
|
||||
// ERROR-BLOCK-COMMENT-NEXT: {{ }}
|
||||
// ERROR-BLOCK-COMMENT-NEXT: }
|
||||
// ERROR-BLOCK-COMMENT-NOT: }
|
||||
// VOID-RESULT-CALL: {{^}}await voidNoError()
|
||||
// VOID-RESULT-CALL: {{^}}print(<#res#>)
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=VOID-RESULT-CALL %s
|
||||
voidResult { res in
|
||||
print(res)
|
||||
}
|
||||
// VOID-RESULT-CALL: {{^}}await voidResult()
|
||||
// VOID-RESULT-CALL: {{^}}print(<#res#>)
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=VOID-AND-ERROR-RESULT-CALL %s
|
||||
voidAndErrorResult { res in
|
||||
print(res)
|
||||
}
|
||||
// VOID-AND-ERROR-RESULT-CALL: {{^}}try await voidAndErrorResult()
|
||||
// VOID-AND-ERROR-RESULT-CALL: {{^}}print(<#res#>)
|
||||
|
||||
// Make sure we ignore an unrelated switch.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=IGNORE-UNRELATED %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch Bool.random() {
|
||||
case true:
|
||||
break
|
||||
case false:
|
||||
break
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=VOID-AND-ERROR-RESULT-CALL %s
|
||||
voidError { res in
|
||||
print(res)
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// IGNORE-UNRELATED: let res = try await simple()
|
||||
// IGNORE-UNRELATED-NEXT: print("before")
|
||||
// IGNORE-UNRELATED-NEXT: switch Bool.random() {
|
||||
// IGNORE-UNRELATED-NEXT: case true:
|
||||
// IGNORE-UNRELATED-NEXT: {{^}} break{{$}}
|
||||
// IGNORE-UNRELATED-NEXT: case false:
|
||||
// IGNORE-UNRELATED-NEXT: {{^}} break{{$}}
|
||||
// IGNORE-UNRELATED-NEXT: }
|
||||
// IGNORE-UNRELATED-NEXT: print("after")
|
||||
// VOID-AND-ERROR-RESULT-CALL: {{^}}try await voidError()
|
||||
// VOID-AND-ERROR-RESULT-CALL: {{^}}print(<#res#>)
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=BREAK-RET-PLACEHOLDER %s
|
||||
simpleWithArg({ return 0 }()) { res in
|
||||
switch res {
|
||||
case .success:
|
||||
if .random() { break }
|
||||
x: if .random() { break x }
|
||||
case .failure:
|
||||
break
|
||||
// Make sure we ignore an unrelated switch.
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=IGNORE-UNRELATED %s
|
||||
simple { res in
|
||||
print("before")
|
||||
switch Bool.random() {
|
||||
case true:
|
||||
break
|
||||
case false:
|
||||
break
|
||||
}
|
||||
print("after")
|
||||
}
|
||||
// IGNORE-UNRELATED: let res = try await simple()
|
||||
// IGNORE-UNRELATED-NEXT: print("before")
|
||||
// IGNORE-UNRELATED-NEXT: switch Bool.random() {
|
||||
// IGNORE-UNRELATED-NEXT: case true:
|
||||
// IGNORE-UNRELATED-NEXT: {{^}} break{{$}}
|
||||
// IGNORE-UNRELATED-NEXT: case false:
|
||||
// IGNORE-UNRELATED-NEXT: {{^}} break{{$}}
|
||||
// IGNORE-UNRELATED-NEXT: }
|
||||
// IGNORE-UNRELATED-NEXT: print("after")
|
||||
|
||||
func foo<T>(_ x: T) {
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=BREAK-RET-PLACEHOLDER %s
|
||||
simpleWithArg({ return 0 }()) { res in
|
||||
switch res {
|
||||
case .success:
|
||||
if .random() { break }
|
||||
x: if .random() { break x }
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
|
||||
func foo<T>(_ x: T) {
|
||||
if .random() { return }
|
||||
}
|
||||
foo(res)
|
||||
|
||||
let fn = {
|
||||
if .random() { return }
|
||||
return
|
||||
}
|
||||
fn()
|
||||
|
||||
_ = { return }()
|
||||
|
||||
switch Bool.random() {
|
||||
case true:
|
||||
break
|
||||
case false:
|
||||
if .random() { break }
|
||||
y: if .random() { break y }
|
||||
return
|
||||
}
|
||||
|
||||
x: if .random() {
|
||||
break x
|
||||
}
|
||||
if .random() { return }
|
||||
}
|
||||
foo(res)
|
||||
|
||||
let fn = {
|
||||
if .random() { return }
|
||||
return
|
||||
}
|
||||
fn()
|
||||
// Make sure we replace lifted break/returns with placeholders, but keep nested
|
||||
// break/returns in e.g closures or labelled control flow in place.
|
||||
|
||||
_ = { return }()
|
||||
|
||||
switch Bool.random() {
|
||||
case true:
|
||||
break
|
||||
case false:
|
||||
if .random() { break }
|
||||
y: if .random() { break y }
|
||||
return
|
||||
}
|
||||
|
||||
x: if .random() {
|
||||
break x
|
||||
}
|
||||
if .random() { return }
|
||||
// BREAK-RET-PLACEHOLDER: let res = try await simpleWithArg({ return 0 }())
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { <#break#> }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: x: if .random() { break x }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: func foo<T>(_ x: T) {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { return }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: foo(<#res#>)
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: let fn = {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { return }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} return{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: fn()
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: _ = { return }()
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: switch Bool.random() {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: case true:
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} break{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: case false:
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { break }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: y: if .random() { break y }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: <#return#>
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: x: if .random() {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} break x{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { <#return#> }
|
||||
}
|
||||
|
||||
// Make sure we replace lifted break/returns with placeholders, but keep nested
|
||||
// break/returns in e.g closures or labelled control flow in place.
|
||||
|
||||
// BREAK-RET-PLACEHOLDER: let res = try await simpleWithArg({ return 0 }())
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { <#break#> }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: x: if .random() { break x }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: func foo<T>(_ x: T) {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { return }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: foo(<#res#>)
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: let fn = {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { return }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} return{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: fn()
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: _ = { return }()
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: switch Bool.random() {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: case true:
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} break{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: case false:
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { break }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: y: if .random() { break y }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: <#return#>
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: x: if .random() {
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: {{^}} break x{{$}}
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: }
|
||||
// BREAK-RET-PLACEHOLDER-NEXT: if .random() { <#return#> }
|
||||
|
||||
@@ -62,7 +62,7 @@ func testPathClassification() async throws {
|
||||
// ELSE-IF-CLASSIFICATION-NEXT: print("d")
|
||||
// ELSE-IF-CLASSIFICATION-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=ELSE-IF-CLASSIFICATION2 %s
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=ELSE-IF-CLASSIFICATION2 %s
|
||||
simpleWithError { str, err in
|
||||
if err == nil {
|
||||
print("a")
|
||||
@@ -172,6 +172,8 @@ func testPathClassification() async throws {
|
||||
// ELSE-IF-CLASSIFICATION5-NEXT: }
|
||||
// ELSE-IF-CLASSIFICATION5-NEXT: }
|
||||
|
||||
// Cannot use refactor-check-compiles, as 'err' cannot have its type inferred
|
||||
// from placeholder.
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=IF-LET-RETURN-CLASSIFICATION %s
|
||||
simpleWithError { str, err in
|
||||
if let str = str {
|
||||
@@ -196,7 +198,7 @@ func testPathClassification() async throws {
|
||||
// IF-LET-RETURN-CLASSIFICATION-NEXT: }
|
||||
// IF-LET-RETURN-CLASSIFICATION-NEXT: }
|
||||
|
||||
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=GUARD-CLASSIFICATION %s
|
||||
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=GUARD-CLASSIFICATION %s
|
||||
simpleWithError { str, err in
|
||||
guard let str = str else {
|
||||
print("a")
|
||||
|
||||
@@ -23,7 +23,8 @@ def parse_args():
|
||||
A drop-in replacement for a 'swift-refactor -dump-text' call that
|
||||
1. Checks that the file still compiles after the refactoring by doing
|
||||
'swift-refactor -dump-rewritten' and feeding the result to
|
||||
'swift-frontend -typecheck'
|
||||
'swift-frontend -typecheck -disable-availability-checking
|
||||
-warn-on-editor-placeholder'
|
||||
2. Outputting the result of the 'swift-refactor -dump-text' call
|
||||
|
||||
All arguments other than the following will be forwarded to
|
||||
@@ -32,6 +33,9 @@ def parse_args():
|
||||
- swift-refactor
|
||||
- temp-dir
|
||||
- enable-experimental-concurrency (sent to both)
|
||||
- I (sent to both)
|
||||
- sdk (sent to both)
|
||||
- target (sent to both)
|
||||
""")
|
||||
|
||||
parser.add_argument(
|
||||
@@ -70,6 +74,19 @@ def parse_args():
|
||||
swift-frontend
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-I',
|
||||
action='append',
|
||||
help='Add a directory to the import search path'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-sdk',
|
||||
help='Path to the SDK to build against'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-target',
|
||||
help='The target triple to build for'
|
||||
)
|
||||
|
||||
return parser.parse_known_args()
|
||||
|
||||
@@ -80,10 +97,16 @@ def main():
|
||||
args.pos.replace(':', '.')
|
||||
temp_file_path = os.path.join(args.temp_dir, temp_file_name)
|
||||
|
||||
extra_frontend_args = []
|
||||
extra_both_args = []
|
||||
if args.enable_experimental_concurrency:
|
||||
extra_refactor_args.append('-enable-experimental-concurrency')
|
||||
extra_frontend_args.append('-enable-experimental-concurrency')
|
||||
extra_both_args.append('-enable-experimental-concurrency')
|
||||
if args.I:
|
||||
for path in args.I:
|
||||
extra_both_args += ['-I', path]
|
||||
if args.sdk:
|
||||
extra_both_args += ['-sdk', args.sdk]
|
||||
if args.target:
|
||||
extra_both_args += ['-target', args.target]
|
||||
|
||||
dump_text_output = run_cmd([
|
||||
args.swift_refactor,
|
||||
@@ -91,15 +114,16 @@ def main():
|
||||
'-source-filename', args.source_filename,
|
||||
'-rewritten-output-file', temp_file_path,
|
||||
'-pos', args.pos
|
||||
] + extra_refactor_args, desc='producing edit').decode("utf-8")
|
||||
] + extra_refactor_args + extra_both_args, desc='producing edit').decode("utf-8")
|
||||
sys.stdout.write(dump_text_output)
|
||||
|
||||
run_cmd([
|
||||
args.swift_frontend,
|
||||
'-typecheck',
|
||||
temp_file_path,
|
||||
'-disable-availability-checking'
|
||||
] + extra_frontend_args, desc='checking that rewritten file compiles')
|
||||
'-disable-availability-checking',
|
||||
'-warn-on-editor-placeholder'
|
||||
] + extra_both_args, desc='checking that rewritten file compiles')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user