mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SR-11261: [Diagnostics][Qol] Parser recovery for keyword (#26596)
* Fixes SR-11261 * Improving diagnostics for multi-case declaration that uses a keyword * Only doing pattern matching if token is not a keywork or if is a possible identifier * Using BacktrackingScope to fix expected pattern * Updating NameLoc with the token consumed. * Updating Name with the consumed token
This commit is contained in:
committed by
Rintaro Ishizaki
parent
ae8ab3fa24
commit
f4423211ac
@@ -5803,24 +5803,32 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
|
||||
|
||||
// For recovery, see if the user typed something resembling a switch
|
||||
// "case" label.
|
||||
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
|
||||
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
|
||||
parseMatchingPattern(/*isExprBasic*/false);
|
||||
|
||||
if (consumeIf(tok::colon)) {
|
||||
diagnose(CaseLoc, diag::case_outside_of_switch, "case");
|
||||
Status.setIsParseError();
|
||||
return Status;
|
||||
}
|
||||
if (CommaLoc.isValid()) {
|
||||
diagnose(Tok, diag::expected_identifier_after_case_comma);
|
||||
Status.setIsParseError();
|
||||
return Status;
|
||||
{
|
||||
BacktrackingScope backtrack(*this);
|
||||
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
|
||||
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
|
||||
parseMatchingPattern(/*isExprBasic*/false);
|
||||
|
||||
if (consumeIf(tok::colon)) {
|
||||
backtrack.cancelBacktrack();
|
||||
diagnose(CaseLoc, diag::case_outside_of_switch, "case");
|
||||
Status.setIsParseError();
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (NameIsKeyword) {
|
||||
diagnose(TokLoc, diag::keyword_cant_be_identifier, TokText);
|
||||
diagnose(TokLoc, diag::backticks_to_escape)
|
||||
.fixItReplace(TokLoc, "`" + TokText.str() + "`");
|
||||
if (!Tok.isAtStartOfLine()) {
|
||||
Name = Context.getIdentifier(Tok.getText());
|
||||
NameLoc = consumeToken();
|
||||
}
|
||||
} else if (CommaLoc.isValid()) {
|
||||
diagnose(Tok, diag::expected_identifier_after_case_comma);
|
||||
Status.setIsParseError();
|
||||
return Status;
|
||||
} else {
|
||||
diagnose(CaseLoc, diag::expected_identifier_in_decl, "enum 'case'");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user