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:
Luciano Almeida
2019-08-23 00:50:44 -03:00
committed by Rintaro Ishizaki
parent ae8ab3fa24
commit f4423211ac
4 changed files with 69 additions and 22 deletions

View File

@@ -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'");
}