Skip to content

Commit aa189f2

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 854a8bc commit aa189f2

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
@@ -5736,15 +5736,23 @@ class AsyncConverter : private SourceEntityWalker {
57365736
void addHandlerCall(const CallExpr *CE) {
57375737
auto Exprs = TopHandler.extractResultArgs(CE);
57385738

5739+
bool AddedReturnOrThrow = true;
57395740
if (!Exprs.isError()) {
5740-
OS << tok::kw_return;
5741+
// It's possible the user has already written an explicit return statement
5742+
// for the completion handler call, e.g 'return completion(args...)'. In
5743+
// that case, be sure not to add another return.
5744+
auto *parent = getWalker().Parent.getAsStmt();
5745+
AddedReturnOrThrow = !(parent && isa<ReturnStmt>(parent));
5746+
if (AddedReturnOrThrow)
5747+
OS << tok::kw_return;
57415748
} else {
57425749
OS << tok::kw_throw;
57435750
}
57445751

57455752
ArrayRef<Expr *> Args = Exprs.args();
57465753
if (!Args.empty()) {
5747-
OS << " ";
5754+
if (AddedReturnOrThrow)
5755+
OS << " ";
57485756
if (Args.size() > 1)
57495757
OS << tok::l_paren;
57505758
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)