Merge pull request #9649 from a3d4/improve-error-coverage-erorrecovery

Complete test coverage for errors related to parser error recovery
This commit is contained in:
chriseth 2020-08-31 18:33:19 +02:00 committed by GitHub
commit 0203eea20e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 9 deletions

View File

@ -94,6 +94,8 @@ void ParserBase::expectToken(Token _value, bool _advance)
void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentNodeName, bool _advance) void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentNodeName, bool _advance)
{ {
solAssert(m_inParserRecovery, "The function is supposed to be called during parser recovery only.");
Token tok = m_scanner->currentToken(); Token tok = m_scanner->currentToken();
if (tok != _value) if (tok != _value)
{ {
@ -103,24 +105,20 @@ void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentN
m_scanner->next(); m_scanner->next();
string const expectedToken = ParserBase::tokenName(_value); string const expectedToken = ParserBase::tokenName(_value);
string const msg = "In " + _currentNodeName + ", " + expectedToken + "is expected; got " + ParserBase::tokenName(tok) + " instead.";
if (m_scanner->currentToken() == Token::EOS) if (m_scanner->currentToken() == Token::EOS)
{ {
// rollback to where the token started, and raise exception to be caught at a higher level. // rollback to where the token started, and raise exception to be caught at a higher level.
m_scanner->setPosition(static_cast<size_t>(startPosition)); m_scanner->setPosition(static_cast<size_t>(startPosition));
m_inParserRecovery = true; string const msg = "In " + _currentNodeName + ", " + expectedToken + "is expected; got " + ParserBase::tokenName(tok) + " instead.";
fatalParserError(1957_error, errorLoc, msg); fatalParserError(1957_error, errorLoc, msg);
} }
else else
{ {
if (m_inParserRecovery) parserWarning(3796_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
parserWarning(3796_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
else
parserError(1054_error, errorLoc, msg + "Recovered at next " + expectedToken);
m_inParserRecovery = false; m_inParserRecovery = false;
} }
} }
else if (m_inParserRecovery) else
{ {
string expectedToken = ParserBase::tokenName(_value); string expectedToken = ParserBase::tokenName(_value);
parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + "."); parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");

View File

@ -1106,7 +1106,7 @@ ASTPointer<Block> Parser::parseBlock(ASTPointer<ASTString> const& _docString)
BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */ BOOST_THROW_EXCEPTION(FatalError()); /* Don't try to recover here. */
m_inParserRecovery = true; m_inParserRecovery = true;
} }
if (m_parserErrorRecovery) if (m_inParserRecovery)
expectTokenOrConsumeUntil(Token::RBrace, "Block"); expectTokenOrConsumeUntil(Token::RBrace, "Block");
else else
expectToken(Token::RBrace); expectToken(Token::RBrace);

View File

@ -219,7 +219,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
return False return False
old_source_only_ids = { old_source_only_ids = {
"1054", "1123", "1133", "1220", "1584", "1823", "1950", "1957", "1123", "1133", "1220", "1584", "1823", "1950",
"1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856", "1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856",
"3263", "3356", "3441", "3682", "3876", "3263", "3356", "3441", "3682", "3876",
"3893", "3997", "4010", "4802", "4805", "4828", "3893", "3997", "4010", "4802", "4805", "4828",

View File

@ -0,0 +1,10 @@
pragma solidity >=0.0.0;
contract Error7 {
constructor() {
a =
// ----
// ParserError 6933: (76-76): Expected primary expression.
// ParserError 1957: (76-76): In Statement, ';'is expected; got end of source instead.
// ParserError 1957: (76-76): In Block, '}'is expected; got end of source instead.
// ParserError 1957: (76-76): In ContractDefinition, '}'is expected; got end of source instead.