mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2720 from ethereum/visibility-parser
Show previous visibility specifier in parser error
This commit is contained in:
commit
279e64ae75
@ -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:
|
||||||
|
|
||||||
|
@ -152,6 +152,24 @@ public:
|
|||||||
/// Visibility ordered from restricted to unrestricted.
|
/// Visibility ordered from restricted to unrestricted.
|
||||||
enum class Visibility { Default, Private, Internal, Public, External };
|
enum class Visibility { Default, Private, Internal, Public, External };
|
||||||
|
|
||||||
|
static std::string visibilityToString(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 std::string();
|
||||||
|
}
|
||||||
|
|
||||||
Declaration(
|
Declaration(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
ASTPointer<ASTString> const& _name,
|
ASTPointer<ASTString> const& _name,
|
||||||
|
@ -285,7 +285,7 @@ bool ASTJsonConverter::visit(StructDefinition const& _node)
|
|||||||
{
|
{
|
||||||
setJsonNode(_node, "StructDefinition", {
|
setJsonNode(_node, "StructDefinition", {
|
||||||
make_pair("name", _node.name()),
|
make_pair("name", _node.name()),
|
||||||
make_pair("visibility", visibility(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair("canonicalName", _node.annotation().canonicalName),
|
make_pair("canonicalName", _node.annotation().canonicalName),
|
||||||
make_pair("members", toJson(_node.members())),
|
make_pair("members", toJson(_node.members())),
|
||||||
make_pair("scope", idOrNull(_node.scope()))
|
make_pair("scope", idOrNull(_node.scope()))
|
||||||
@ -325,7 +325,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
|
|||||||
make_pair("name", _node.name()),
|
make_pair("name", _node.name()),
|
||||||
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
|
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
|
||||||
make_pair("payable", _node.isPayable()),
|
make_pair("payable", _node.isPayable()),
|
||||||
make_pair("visibility", visibility(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair("parameters", toJson(_node.parameterList())),
|
make_pair("parameters", toJson(_node.parameterList())),
|
||||||
make_pair("isConstructor", _node.isConstructor()),
|
make_pair("isConstructor", _node.isConstructor()),
|
||||||
make_pair("returnParameters", toJson(*_node.returnParameterList())),
|
make_pair("returnParameters", toJson(*_node.returnParameterList())),
|
||||||
@ -346,7 +346,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node)
|
|||||||
make_pair("constant", _node.isConstant()),
|
make_pair("constant", _node.isConstant()),
|
||||||
make_pair("stateVariable", _node.isStateVariable()),
|
make_pair("stateVariable", _node.isStateVariable()),
|
||||||
make_pair("storageLocation", location(_node.referenceLocation())),
|
make_pair("storageLocation", location(_node.referenceLocation())),
|
||||||
make_pair("visibility", visibility(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
|
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
|
||||||
make_pair("scope", idOrNull(_node.scope())),
|
make_pair("scope", idOrNull(_node.scope())),
|
||||||
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type))
|
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type))
|
||||||
@ -361,7 +361,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node)
|
|||||||
{
|
{
|
||||||
setJsonNode(_node, "ModifierDefinition", {
|
setJsonNode(_node, "ModifierDefinition", {
|
||||||
make_pair("name", _node.name()),
|
make_pair("name", _node.name()),
|
||||||
make_pair("visibility", visibility(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair("parameters", toJson(_node.parameterList())),
|
make_pair("parameters", toJson(_node.parameterList())),
|
||||||
make_pair("body", toJson(_node.body()))
|
make_pair("body", toJson(_node.body()))
|
||||||
});
|
});
|
||||||
@ -418,7 +418,7 @@ bool ASTJsonConverter::visit(FunctionTypeName const& _node)
|
|||||||
{
|
{
|
||||||
setJsonNode(_node, "FunctionTypeName", {
|
setJsonNode(_node, "FunctionTypeName", {
|
||||||
make_pair("payable", _node.isPayable()),
|
make_pair("payable", _node.isPayable()),
|
||||||
make_pair("visibility", visibility(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
|
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
|
||||||
make_pair("parameterTypes", toJson(*_node.parameterTypeList())),
|
make_pair("parameterTypes", toJson(*_node.parameterTypeList())),
|
||||||
make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())),
|
make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())),
|
||||||
@ -730,23 +730,6 @@ void ASTJsonConverter::endVisit(EventDefinition const&)
|
|||||||
m_inEvent = false;
|
m_inEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ASTJsonConverter::visibility(Declaration::Visibility const& _visibility)
|
|
||||||
{
|
|
||||||
switch (_visibility)
|
|
||||||
{
|
|
||||||
case Declaration::Visibility::Private:
|
|
||||||
return "private";
|
|
||||||
case Declaration::Visibility::Internal:
|
|
||||||
return "internal";
|
|
||||||
case Declaration::Visibility::Public:
|
|
||||||
return "public";
|
|
||||||
case Declaration::Visibility::External:
|
|
||||||
return "external";
|
|
||||||
default:
|
|
||||||
solAssert(false, "Unknown declaration visibility.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string ASTJsonConverter::location(VariableDeclaration::Location _location)
|
string ASTJsonConverter::location(VariableDeclaration::Location _location)
|
||||||
{
|
{
|
||||||
switch (_location)
|
switch (_location)
|
||||||
|
@ -128,7 +128,6 @@ private:
|
|||||||
return _node ? toJson(*_node) : Json::nullValue;
|
return _node ? toJson(*_node) : Json::nullValue;
|
||||||
}
|
}
|
||||||
Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info);
|
Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info);
|
||||||
std::string visibility(Declaration::Visibility const& _visibility);
|
|
||||||
std::string location(VariableDeclaration::Location _location);
|
std::string location(VariableDeclaration::Location _location);
|
||||||
std::string contractKind(ContractDefinition::ContractKind _kind);
|
std::string contractKind(ContractDefinition::ContractKind _kind);
|
||||||
std::string functionCallKind(FunctionCallKind _kind);
|
std::string functionCallKind(FunctionCallKind _kind);
|
||||||
|
@ -354,7 +354,11 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN
|
|||||||
{
|
{
|
||||||
if (result.visibility != Declaration::Visibility::Default)
|
if (result.visibility != Declaration::Visibility::Default)
|
||||||
{
|
{
|
||||||
parserError(string("Multiple visibility specifiers."));
|
parserError(string(
|
||||||
|
"Visibility already specified as \"" +
|
||||||
|
Declaration::visibilityToString(result.visibility) +
|
||||||
|
"\"."
|
||||||
|
));
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -512,7 +516,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 \"" +
|
||||||
|
Declaration::visibilityToString(visibility) +
|
||||||
|
"\"."
|
||||||
|
));
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -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);
|
||||||
|
@ -898,7 +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"(
|
||||||
|
contract c {
|
||||||
|
function f() private external {}
|
||||||
|
})";
|
||||||
|
CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multiple_payable_specifiers)
|
BOOST_AUTO_TEST_CASE(multiple_payable_specifiers)
|
||||||
|
Loading…
Reference in New Issue
Block a user