[Refactoring] Fix crash when refactoring protocol requirement to async

When a function declaration has no body (e.g. because it’s a protocol requirement), we construct the range to replace by the `async` keyword as follows:
- Start: One character after the closing `)` (or potentially the `throws` keyword if it exists)
- End: Last token in the function declaration

Since the last token in the function declaration is the `)`, we end up with a range that has `End < Start`, which crashes when trying to print the range.

If the function has no body, we should just use the range’s start location as the end location to construct an empty range.

Fixes rdar://76677035
This commit is contained in:
Alex Hoppen
2021-04-21 17:33:14 +02:00
parent c8ba622532
commit 9d62f9d4db
2 changed files with 8 additions and 2 deletions

View File

@@ -4914,7 +4914,7 @@ private:
RightStartLoc = Lexer::getLocForEndOfToken(SM, FD->getThrowsLoc());
}
SourceLoc RightEndLoc =
FD->getBody() ? FD->getBody()->getLBraceLoc() : FD->getEndLoc();
FD->getBody() ? FD->getBody()->getLBraceLoc() : RightStartLoc;
addRange(RightStartLoc, RightEndLoc);
return;
}

View File

@@ -150,9 +150,15 @@ struct MyStruct {
func retStruct() -> MyStruct { return MyStruct() }
protocol MyProtocol {
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=PROTO-MEMBER %s
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):3 | %FileCheck -check-prefix=PROTO-MEMBER %s
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=PROTO-MEMBER-TO-ASYNC %s
func protoMember(completion: (String) -> Void)
// PROTO-MEMBER: func protoMember() async -> String{{$}}
// FIXME: The current async refactoring only refactors the client side and thus only adds the 'async' keyword.
// We should be refactoring the entire method signature here and removing the completion parameter.
// This test currently checks that we are not crashing.
// PROTO-MEMBER-TO-ASYNC: func protoMember(completion: (String) -> Void) async
}
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1