Skip to content

Commit 204898a

Browse files
committed
[Refactoring] Avoid duplicating return statements
It's possible the user has already written an explicit return for the call to the completion handler. In that case, avoid adding another return. rdar://77789360
1 parent 0c675a9 commit 204898a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5744,15 +5744,23 @@ class AsyncConverter : private SourceEntityWalker {
57445744
void addHandlerCall(const CallExpr *CE) {
57455745
auto Exprs = TopHandler.extractResultArgs(CE);
57465746

5747+
bool AddedReturnOrThrow = true;
57475748
if (!Exprs.isError()) {
5748-
OS << tok::kw_return;
5749+
// It's possible the user has already written an explicit return statement
5750+
// for the completion handler call, e.g 'return completion(args...)'. In
5751+
// that case, be sure not to add another return.
5752+
auto *parent = getWalker().Parent.getAsStmt();
5753+
AddedReturnOrThrow = !(parent && isa<ReturnStmt>(parent));
5754+
if (AddedReturnOrThrow)
5755+
OS << tok::kw_return;
57495756
} else {
57505757
OS << tok::kw_throw;
57515758
}
57525759

57535760
ArrayRef<Expr *> Args = Exprs.args();
57545761
if (!Args.empty()) {
5755-
OS << " ";
5762+
if (AddedReturnOrThrow)
5763+
OS << " ";
57565764
if (Args.size() > 1)
57575765
OS << tok::l_paren;
57585766
for (size_t I = 0, E = Args.size(); I < E; ++I) {

test/refactoring/ConvertAsync/convert_function.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,13 @@ func voidResultCompletion(completion: (Result<Void, Error>) -> Void) {
247247
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=NON-COMPLETION-HANDLER %s
248248
func functionWithSomeHandler(handler: (String) -> Void) {}
249249
// NON-COMPLETION-HANDLER: func functionWithSomeHandler() async -> String {}
250+
251+
// rdar://77789360 Make sure we don't print a double return statement.
252+
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1 | %FileCheck -check-prefix=RETURN-HANDLING %s
253+
func testReturnHandling(_ completion: (String?, Error?) -> Void) {
254+
return completion("", nil)
255+
}
256+
// RETURN-HANDLING: func testReturnHandling() async throws -> String {
257+
// RETURN-HANDLING-NEXT: {{^}} return ""{{$}}
258+
// RETURN-HANDLING-NEXT: }
259+

0 commit comments

Comments
 (0)