mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add fixit for '-> throws' to 'throws ->' (#3335)
This commit is contained in:
@@ -648,6 +648,26 @@ Parser::parseFunctionSignature(Identifier SimpleName,
|
||||
}
|
||||
|
||||
SourceLoc arrowLoc;
|
||||
|
||||
auto diagnoseInvalidThrows = [&]() -> Optional<InFlightDiagnostic> {
|
||||
if (throwsLoc.isValid())
|
||||
return None;
|
||||
|
||||
if (Tok.is(tok::kw_throws)) {
|
||||
throwsLoc = consumeToken();
|
||||
} else if (Tok.is(tok::kw_rethrows)) {
|
||||
throwsLoc = consumeToken();
|
||||
rethrows = true;
|
||||
}
|
||||
|
||||
if (!throwsLoc.isValid())
|
||||
return None;
|
||||
|
||||
auto diag = rethrows ? diag::rethrows_in_wrong_position
|
||||
: diag::throws_in_wrong_position;
|
||||
return diagnose(Tok, diag);
|
||||
};
|
||||
|
||||
// If there's a trailing arrow, parse the rest as the result type.
|
||||
if (Tok.isAny(tok::arrow, tok::colon)) {
|
||||
if (!consumeIf(tok::arrow, arrowLoc)) {
|
||||
@@ -657,6 +677,15 @@ Parser::parseFunctionSignature(Identifier SimpleName,
|
||||
arrowLoc = consumeToken(tok::colon);
|
||||
}
|
||||
|
||||
// Check for 'throws' and 'rethrows' after the arrow, but
|
||||
// before the type, and correct it.
|
||||
if (auto diagOpt = diagnoseInvalidThrows()) {
|
||||
assert(arrowLoc.isValid());
|
||||
assert(throwsLoc.isValid());
|
||||
(*diagOpt).fixItExchange(SourceRange(arrowLoc),
|
||||
SourceRange(throwsLoc));
|
||||
}
|
||||
|
||||
ParserResult<TypeRepr> ResultType =
|
||||
parseType(diag::expected_type_function_result);
|
||||
if (ResultType.hasCodeCompletion())
|
||||
@@ -672,26 +701,14 @@ Parser::parseFunctionSignature(Identifier SimpleName,
|
||||
}
|
||||
|
||||
// Check for 'throws' and 'rethrows' after the type and correct it.
|
||||
if (!throwsLoc.isValid()) {
|
||||
if (Tok.is(tok::kw_throws)) {
|
||||
throwsLoc = consumeToken();
|
||||
} else if (Tok.is(tok::kw_rethrows)) {
|
||||
throwsLoc = consumeToken();
|
||||
rethrows = true;
|
||||
}
|
||||
|
||||
if (throwsLoc.isValid()) {
|
||||
assert(arrowLoc.isValid());
|
||||
assert(retType);
|
||||
auto diag = rethrows ? diag::rethrows_after_function_result
|
||||
: diag::throws_after_function_result;
|
||||
SourceLoc typeEndLoc = Lexer::getLocForEndOfToken(SourceMgr,
|
||||
retType->getEndLoc());
|
||||
SourceLoc throwsEndLoc = Lexer::getLocForEndOfToken(SourceMgr, throwsLoc);
|
||||
diagnose(Tok, diag)
|
||||
.fixItInsert(arrowLoc, rethrows ? "rethrows " : "throws ")
|
||||
.fixItRemoveChars(typeEndLoc, throwsEndLoc);
|
||||
}
|
||||
if (auto diagOpt = diagnoseInvalidThrows()) {
|
||||
assert(arrowLoc.isValid());
|
||||
assert(retType);
|
||||
SourceLoc typeEndLoc = Lexer::getLocForEndOfToken(SourceMgr,
|
||||
retType->getEndLoc());
|
||||
SourceLoc throwsEndLoc = Lexer::getLocForEndOfToken(SourceMgr, throwsLoc);
|
||||
(*diagOpt).fixItInsert(arrowLoc, rethrows ? "rethrows " : "throws ")
|
||||
.fixItRemoveChars(typeEndLoc, throwsEndLoc);
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
Reference in New Issue
Block a user