mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Previously we would drop comments between nodes in a BraceStmt, as we printed each node out individually. To remedy this, always make sure we scan backwards to find any preceding comments attached to a node, and also keep track of any SourceLocs which we don't print, but may have comments attached which we want to preserve. rdar://77401810
519 lines
15 KiB
Swift
519 lines
15 KiB
Swift
func withError(_ completion: (String?, Error?) -> Void) { }
|
|
func notOptional(_ completion: (String, Error?) -> Void) { }
|
|
func errorOnly(_ completion: (Error?) -> Void) { }
|
|
func test(_ str: String) -> Bool { return false }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNRELATED %s
|
|
withError { res, err in
|
|
if test("unrelated") {
|
|
print("unrelated")
|
|
} else {
|
|
print("else unrelated")
|
|
}
|
|
}
|
|
// UNRELATED: convert_params_single.swift
|
|
// UNRELATED-NEXT: let res = try await withError()
|
|
// UNRELATED-NEXT: if test("unrelated") {
|
|
// UNRELATED-NEXT: print("unrelated")
|
|
// UNRELATED-NEXT: } else {
|
|
// UNRELATED-NEXT: print("else unrelated")
|
|
// UNRELATED-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=BOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
return
|
|
}
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
print("after")
|
|
}
|
|
// BOUND: do {
|
|
// BOUND-NEXT: let str = try await withError()
|
|
// BOUND-NEXT: print("before")
|
|
// BOUND-NEXT: print("got result \(str)")
|
|
// BOUND-NEXT: print("after")
|
|
// BOUND-NEXT: } catch let bad {
|
|
// BOUND-NEXT: print("got error \(bad)")
|
|
// BOUND-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=BOUND-COMMENT %s
|
|
withError { res, err in // a
|
|
// b
|
|
print("before")
|
|
// c
|
|
if let bad = err { // d
|
|
// e
|
|
print("got error \(bad)")
|
|
// f
|
|
return
|
|
// g
|
|
}
|
|
// h
|
|
if let str = res { // i
|
|
// j
|
|
print("got result \(str)")
|
|
// k
|
|
}
|
|
// l
|
|
print("after")
|
|
// m
|
|
}
|
|
// BOUND-COMMENT: do {
|
|
// BOUND-COMMENT-NEXT: let str = try await withError()
|
|
// BOUND-COMMENT-NEXT: // a
|
|
// BOUND-COMMENT-NEXT: // b
|
|
// BOUND-COMMENT-NEXT: print("before")
|
|
// BOUND-COMMENT-NEXT: // c
|
|
// BOUND-COMMENT-NEXT: // h
|
|
// BOUND-COMMENT-NEXT: // i
|
|
// BOUND-COMMENT-NEXT: // j
|
|
// BOUND-COMMENT-NEXT: print("got result \(str)")
|
|
// BOUND-COMMENT-NEXT: // k
|
|
// BOUND-COMMENT-NEXT: // l
|
|
// BOUND-COMMENT-NEXT: print("after")
|
|
// BOUND-COMMENT-NEXT: // m
|
|
// BOUND-COMMENT-EMPTY:
|
|
// BOUND-COMMENT-NEXT: } catch let bad {
|
|
// BOUND-COMMENT-NEXT: // d
|
|
// BOUND-COMMENT-NEXT: // e
|
|
// BOUND-COMMENT-NEXT: print("got error \(bad)")
|
|
// BOUND-COMMENT-NEXT: // f
|
|
// BOUND-COMMENT-NEXT: // g
|
|
// BOUND-COMMENT-NEXT: {{ }}
|
|
// BOUND-COMMENT-NEXT: }
|
|
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-ERR %s
|
|
withError { res, err in
|
|
print("before")
|
|
guard let str = res else {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(str)")
|
|
print("after")
|
|
}
|
|
// UNBOUND-ERR: do {
|
|
// UNBOUND-ERR-NEXT: let str = try await withError()
|
|
// UNBOUND-ERR-NEXT: print("before")
|
|
// UNBOUND-ERR-NEXT: print("got result \(str)")
|
|
// UNBOUND-ERR-NEXT: print("after")
|
|
// UNBOUND-ERR-NEXT: } catch let err {
|
|
// UNBOUND-ERR-NEXT: print("got error \(err)")
|
|
// UNBOUND-ERR-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=BOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
} else if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=BOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
return
|
|
}
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-RES %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
return
|
|
}
|
|
print("got result \(res!)")
|
|
print("after")
|
|
}
|
|
// UNBOUND-RES: do {
|
|
// UNBOUND-RES-NEXT: let res = try await withError()
|
|
// UNBOUND-RES-NEXT: print("before")
|
|
// UNBOUND-RES-NEXT: print("got result \(res)")
|
|
// UNBOUND-RES-NEXT: print("after")
|
|
// UNBOUND-RES-NEXT: } catch let bad {
|
|
// UNBOUND-RES-NEXT: print("got error \(bad)")
|
|
// UNBOUND-RES-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-ERR %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
print("after")
|
|
return
|
|
}
|
|
print("got error \(err!)")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-RES %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
} else {
|
|
print("got result \(res!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-ERR %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
} else {
|
|
print("got error \(err!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if err != nil {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(res!)")
|
|
print("after")
|
|
}
|
|
// UNBOUND: do {
|
|
// UNBOUND-NEXT: let res = try await withError()
|
|
// UNBOUND-NEXT: print("before")
|
|
// UNBOUND-NEXT: print("got result \(res)")
|
|
// UNBOUND-NEXT: print("after")
|
|
// UNBOUND-NEXT: } catch let err {
|
|
// UNBOUND-NEXT: print("got error \(err)")
|
|
// UNBOUND-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res != nil {
|
|
print("got result \(res!)")
|
|
print("after")
|
|
return
|
|
}
|
|
print("got error \(err!)")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if err != nil {
|
|
print("got error \(err!)")
|
|
} else {
|
|
print("got result \(res!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res != nil {
|
|
print("got result \(res!)")
|
|
} else {
|
|
print("got error \(err!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if err == nil {
|
|
print("got result \(res!)")
|
|
} else {
|
|
print("got error \(err!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res == nil {
|
|
print("got error \(err!)")
|
|
} else {
|
|
print("got result \(res!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNHANDLEDNESTED %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
} else {
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
}
|
|
print("after")
|
|
}
|
|
// UNHANDLEDNESTED: do {
|
|
// UNHANDLEDNESTED-NEXT: let res = try await withError()
|
|
// UNHANDLEDNESTED-NEXT: print("before")
|
|
// UNHANDLEDNESTED-NEXT: if let str = <#res#> {
|
|
// UNHANDLEDNESTED-NEXT: print("got result \(str)")
|
|
// UNHANDLEDNESTED-NEXT: }
|
|
// UNHANDLEDNESTED-NEXT: print("after")
|
|
// UNHANDLEDNESTED-NEXT: } catch let bad {
|
|
// UNHANDLEDNESTED-NEXT: print("got error \(bad)")
|
|
// UNHANDLEDNESTED-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NOERR %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
print("after")
|
|
}
|
|
// NOERR: convert_params_single.swift
|
|
// NOERR-NEXT: let str = try await withError()
|
|
// NOERR-NEXT: print("before")
|
|
// NOERR-NEXT: print("got result \(str)")
|
|
// NOERR-NEXT: print("after")
|
|
// NOERR-NOT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NORES %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let bad = err {
|
|
print("got error \(bad)")
|
|
}
|
|
print("after")
|
|
}
|
|
// NORES: do {
|
|
// NORES-NEXT: let res = try await withError()
|
|
// NORES-NEXT: print("before")
|
|
// NORES-NEXT: print("after")
|
|
// NORES-NEXT: } catch let bad {
|
|
// NORES-NEXT: print("got error \(bad)")
|
|
// NORES-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res != nil && err == nil {
|
|
print("got result \(res!)")
|
|
} else {
|
|
print("got error \(err!)")
|
|
}
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNKNOWN-COND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res != nil && test(res!) {
|
|
print("got result \(res!)")
|
|
}
|
|
print("after")
|
|
}
|
|
// UNKNOWN-COND: convert_params_single.swift
|
|
// UNKNOWN-COND-NEXT: let res = try await withError()
|
|
// UNKNOWN-COND-NEXT: print("before")
|
|
// UNKNOWN-COND-NEXT: if <#res#> != nil && test(res) {
|
|
// UNKNOWN-COND-NEXT: print("got result \(res)")
|
|
// UNKNOWN-COND-NEXT: }
|
|
// UNKNOWN-COND-NEXT: print("after")
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNKNOWN-CONDELSE %s
|
|
withError { res, err in
|
|
print("before")
|
|
if res != nil && test(res!) {
|
|
print("got result \(res!)")
|
|
} else {
|
|
print("bad")
|
|
}
|
|
print("after")
|
|
}
|
|
// UNKNOWN-CONDELSE: var res: String? = nil
|
|
// UNKNOWN-CONDELSE-NEXT: var err: Error? = nil
|
|
// UNKNOWN-CONDELSE-NEXT: do {
|
|
// UNKNOWN-CONDELSE-NEXT: res = try await withError()
|
|
// UNKNOWN-CONDELSE-NEXT: } catch {
|
|
// UNKNOWN-CONDELSE-NEXT: err = error
|
|
// UNKNOWN-CONDELSE-NEXT: }
|
|
// UNKNOWN-CONDELSE-EMPTY:
|
|
// UNKNOWN-CONDELSE-NEXT: print("before")
|
|
// UNKNOWN-CONDELSE-NEXT: if res != nil && test(res!) {
|
|
// UNKNOWN-CONDELSE-NEXT: print("got result \(res!)")
|
|
// UNKNOWN-CONDELSE-NEXT: } else {
|
|
// UNKNOWN-CONDELSE-NEXT: print("bad")
|
|
// UNKNOWN-CONDELSE-NEXT: }
|
|
// UNKNOWN-CONDELSE-NEXT: print("after")
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=MULTIBIND %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let str = res {
|
|
print("got result \(str)")
|
|
}
|
|
if let str2 = res {
|
|
print("got result \(str2)")
|
|
}
|
|
print("after")
|
|
}
|
|
// MULTIBIND: let str = try await withError()
|
|
// MULTIBIND-NEXT: print("before")
|
|
// MULTIBIND-NEXT: print("got result \(str)")
|
|
// MULTIBIND-NEXT: print("got result \(str)")
|
|
// MULTIBIND-NEXT: print("after")
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=NESTEDRET %s
|
|
withError { res, err in
|
|
print("before")
|
|
if let str = res {
|
|
if test(str) {
|
|
return
|
|
}
|
|
print("got result \(str)")
|
|
}
|
|
print("after")
|
|
}
|
|
// NESTEDRET: convert_params_single.swift
|
|
// NESTEDRET-NEXT: let str = try await withError()
|
|
// NESTEDRET-NEXT: print("before")
|
|
// NESTEDRET-NEXT: if test(str) {
|
|
// NESTEDRET-NEXT: <#return#>
|
|
// NESTEDRET-NEXT: }
|
|
// NESTEDRET-NEXT: print("got result \(str)")
|
|
// NESTEDRET-NEXT: print("after")
|
|
// NESTEDRET-NOT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND-ERR %s
|
|
withError { res, err in
|
|
print("before")
|
|
guard let str = res, err == nil else {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(str)")
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
guard res != nil else {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(res!)")
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
guard err == nil else {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(res!)")
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNBOUND %s
|
|
withError { res, err in
|
|
print("before")
|
|
guard res != nil && err == nil else {
|
|
print("got error \(err!)")
|
|
return
|
|
}
|
|
print("got result \(res!)")
|
|
print("after")
|
|
}
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=UNWRAPPING %s
|
|
withError { str, err in
|
|
print("before")
|
|
guard err == nil else { return }
|
|
_ = str!.count
|
|
_ = /*before*/str!/*after*/.count
|
|
_ = str?.count
|
|
_ = str!.count.bitWidth
|
|
_ = str?.count.bitWidth
|
|
_ = (str?.count.bitWidth)!
|
|
_ = str!.first?.isWhitespace
|
|
_ = str?.first?.isWhitespace
|
|
_ = (str?.first?.isWhitespace)!
|
|
print("after")
|
|
}
|
|
// UNWRAPPING: let str = try await withError()
|
|
// UNWRAPPING-NEXT: print("before")
|
|
// UNWRAPPING-NEXT: _ = str.count
|
|
// UNWRAPPING-NEXT: _ = /*before*/str/*after*/.count
|
|
// UNWRAPPING-NEXT: _ = str.count
|
|
// UNWRAPPING-NEXT: _ = str.count.bitWidth
|
|
// UNWRAPPING-NEXT: _ = str.count.bitWidth
|
|
|
|
// Note this transform results in invalid code as str.count.bitWidth is no
|
|
// longer optional, but arguably it's more useful than leaving str as a
|
|
// placeholder. In general, the tranform we perform here is locally valid
|
|
// within the optional chain, but may change the type of the overall chain.
|
|
// UNWRAPPING-NEXT: _ = (str.count.bitWidth)!
|
|
|
|
// UNWRAPPING-NEXT: _ = str.first?.isWhitespace
|
|
// UNWRAPPING-NEXT: _ = str.first?.isWhitespace
|
|
// UNWRAPPING-NEXT: _ = (str.first?.isWhitespace)!
|
|
// UNWRAPPING-NEXT: print("after")
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NOT-OPTIONAL %s
|
|
notOptional { str, err in
|
|
print("before")
|
|
if let err2 = err {
|
|
print("got error \(err2)")
|
|
return
|
|
}
|
|
print("got result \(str)")
|
|
print("after")
|
|
}
|
|
// NOT-OPTIONAL: do {
|
|
// NOT-OPTIONAL-NEXT: let str = try await notOptional()
|
|
// NOT-OPTIONAL-NEXT: print("before")
|
|
// NOT-OPTIONAL-NEXT: print("got result \(str)")
|
|
// NOT-OPTIONAL-NEXT: print("after")
|
|
// NOT-OPTIONAL-NEXT: } catch let err2 {
|
|
// NOT-OPTIONAL-NEXT: print("got error \(err2)")
|
|
// NOT-OPTIONAL-NEXT: }
|
|
|
|
// RUN: %refactor -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=ERROR-ONLY %s
|
|
errorOnly { err in
|
|
print("before")
|
|
if let err2 = err {
|
|
print("got error \(err2)")
|
|
return
|
|
}
|
|
print("after")
|
|
}
|
|
// ERROR-ONLY: convert_params_single.swift
|
|
// ERROR-ONLY-NEXT: do {
|
|
// ERROR-ONLY-NEXT: try await errorOnly()
|
|
// ERROR-ONLY-NEXT: print("before")
|
|
// ERROR-ONLY-NEXT: print("after")
|
|
// ERROR-ONLY-NEXT: } catch let err2 {
|
|
// ERROR-ONLY-NEXT: print("got error \(err2)")
|
|
// ERROR-ONLY-NEXT: }
|
|
// ERROR-ONLY-NOT: }
|