mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
- implemented Empty parameter name story. Now the name of input/return parameters of function can be not specified.
- added appropriate tests Conflicts: test/SolidityEndToEndTest.cpp test/SolidityNameAndTypeResolution.cpp
This commit is contained in:
parent
a66db516fb
commit
2a5c2578bd
19
AST.cpp
19
AST.cpp
@ -58,10 +58,21 @@ void ContractDefinition::checkTypeRequirements()
|
||||
BOOST_THROW_EXCEPTION(constructor->getReturnParameterList()->createTypeError(
|
||||
"Non-empty \"returns\" directive for constructor."));
|
||||
|
||||
FunctionDefinition const* fallbackFunction = getFallbackFunction();
|
||||
if (fallbackFunction && fallbackFunction->getScope() == this && !fallbackFunction->getParameters().empty())
|
||||
BOOST_THROW_EXCEPTION(fallbackFunction->getParameterList().createTypeError(
|
||||
"Fallback function cannot take parameters."));
|
||||
FunctionDefinition const* fallbackFunction = nullptr;
|
||||
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
|
||||
{
|
||||
if (function->getName().empty())
|
||||
{
|
||||
if (fallbackFunction)
|
||||
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_comment("Only one fallback function is allowed."));
|
||||
else
|
||||
{
|
||||
fallbackFunction = function.get();
|
||||
if (!fallbackFunction->getParameters().empty())
|
||||
BOOST_THROW_EXCEPTION(fallbackFunction->getParameterList().createTypeError("Fallback function cannot take parameters."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ASTPointer<ModifierDefinition> const& modifier: getFunctionModifiers())
|
||||
modifier->checkTypeRequirements();
|
||||
|
2
AST.h
2
AST.h
@ -250,7 +250,7 @@ public:
|
||||
|
||||
/// Returns the constructor or nullptr if no constructor was specified.
|
||||
FunctionDefinition const* getConstructor() const;
|
||||
/// Returns the fallback function or nullptr if no constructor was specified.
|
||||
/// Returns the fallback function or nullptr if no fallback function was specified.
|
||||
FunctionDefinition const* getFallbackFunction() const;
|
||||
|
||||
private:
|
||||
|
@ -30,6 +30,9 @@ namespace solidity
|
||||
|
||||
bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _update)
|
||||
{
|
||||
if (_declaration.getName().empty())
|
||||
return true;
|
||||
|
||||
if (!_update && m_declarations.find(_declaration.getName()) != m_declarations.end())
|
||||
return false;
|
||||
m_declarations[_declaration.getName()] = &_declaration;
|
||||
@ -38,6 +41,7 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration,
|
||||
|
||||
Declaration const* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
|
||||
{
|
||||
solAssert(!_name.empty(), "Attempt to resolve empty name.");
|
||||
auto result = m_declarations.find(_name);
|
||||
if (result != m_declarations.end())
|
||||
return result->second;
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
explicit DeclarationContainer(Declaration const* _enclosingDeclaration = nullptr,
|
||||
DeclarationContainer const* _enclosingContainer = nullptr):
|
||||
m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {}
|
||||
/// Registers the declaration in the scope unless its name is already declared.
|
||||
/// @returns true iff it was not yet declared.
|
||||
/// Registers the declaration in the scope unless its name is already declared or the name is empty.
|
||||
/// @returns false if the name was already declared.
|
||||
bool registerDeclaration(Declaration const& _declaration, bool _update = false);
|
||||
Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const;
|
||||
Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
|
||||
|
20
Parser.cpp
20
Parser.cpp
@ -268,17 +268,28 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(VarDeclParserOp
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ASTPointer<TypeName> type = parseTypeName(_options.allowVar);
|
||||
bool isIndexed = false;
|
||||
ASTPointer<ASTString> identifier;
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
Declaration::Visibility visibility(Declaration::Visibility::DEFAULT);
|
||||
if (_options.isStateVariable && Token::isVisibilitySpecifier(token))
|
||||
visibility = parseVisibilitySpecifier(token);
|
||||
if (_options.allowIndexed && token == Token::INDEXED)
|
||||
{
|
||||
isIndexed = true;
|
||||
m_scanner->next();
|
||||
}
|
||||
Declaration::Visibility visibility(Declaration::Visibility::DEFAULT);
|
||||
if (_options.isStateVariable && Token::isVisibilitySpecifier(token))
|
||||
visibility = parseVisibilitySpecifier(token);
|
||||
if (_options.allowEmptyName && m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||
{
|
||||
identifier = make_shared<ASTString>("");
|
||||
nodeFactory.setEndPositionFromNode(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeFactory.markEndPosition();
|
||||
identifier = expectIdentifierToken();
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken(),
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, identifier,
|
||||
visibility, _options.isStateVariable,
|
||||
isIndexed);
|
||||
}
|
||||
@ -402,6 +413,7 @@ ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty, bool _all
|
||||
vector<ASTPointer<VariableDeclaration>> parameters;
|
||||
VarDeclParserOptions options;
|
||||
options.allowIndexed = _allowIndexed;
|
||||
options.allowEmptyName = true;
|
||||
expectToken(Token::LPAREN);
|
||||
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user