Show previous visibility specifier in parser error

This commit is contained in:
Alex Beregszaszi 2017-08-09 13:35:38 +01:00
parent a8ca623a0f
commit efd45f64a5
4 changed files with 32 additions and 4 deletions

View File

@ -1,6 +1,7 @@
### 0.4.16 (unreleased) ### 0.4.16 (unreleased)
Features: Features:
* Parser: Display previous visibility specifier in error if multiple are found.
Bugfixes: Bugfixes:

View File

@ -307,6 +307,24 @@ Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
return visibility; return visibility;
} }
string Parser::visibilitySpecifierName(Declaration::Visibility _visibility)
{
switch(_visibility)
{
case Declaration::Visibility::Public:
return "public";
case Declaration::Visibility::Internal:
return "internal";
case Declaration::Visibility::Private:
return "private";
case Declaration::Visibility::External:
return "external";
default:
solAssert(false, "Invalid visibility specifier.");
}
return string();
}
Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers) Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers)
{ {
FunctionHeaderParserResult result; FunctionHeaderParserResult result;
@ -354,7 +372,11 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
{ {
if (result.visibility != Declaration::Visibility::Default) if (result.visibility != Declaration::Visibility::Default)
{ {
parserError(string("Visibility already specified.")); parserError(string(
"Visibility already specified as \"" +
visibilitySpecifierName(result.visibility) +
"\"."
));
m_scanner->next(); m_scanner->next();
} }
else else
@ -512,7 +534,11 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
{ {
if (visibility != Declaration::Visibility::Default) if (visibility != Declaration::Visibility::Default)
{ {
parserError(string("Visibility already specified.")); parserError(string(
"Visibility already specified as \"" +
visibilitySpecifierName(visibility) +
"\"."
));
m_scanner->next(); m_scanner->next();
} }
else else

View File

@ -73,6 +73,7 @@ private:
ASTPointer<ContractDefinition> parseContractDefinition(Token::Value _expectedKind); ASTPointer<ContractDefinition> parseContractDefinition(Token::Value _expectedKind);
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier(); ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); Declaration::Visibility parseVisibilitySpecifier(Token::Value _token);
std::string visibilitySpecifierName(Declaration::Visibility _visibility);
FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers); FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers);
ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName); ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName);
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);

View File

@ -898,12 +898,12 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
contract c { contract c {
uint private internal a; uint private internal a;
})"; })";
CHECK_PARSE_ERROR(text, "Visibility already specified."); CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\".");
text = R"( text = R"(
contract c { contract c {
function f() private external {} function f() private external {}
})"; })";
CHECK_PARSE_ERROR(text, "Visibility already specified."); CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\".");
} }
BOOST_AUTO_TEST_CASE(multiple_payable_specifiers) BOOST_AUTO_TEST_CASE(multiple_payable_specifiers)