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(
|
BOOST_THROW_EXCEPTION(constructor->getReturnParameterList()->createTypeError(
|
||||||
"Non-empty \"returns\" directive for constructor."));
|
"Non-empty \"returns\" directive for constructor."));
|
||||||
|
|
||||||
FunctionDefinition const* fallbackFunction = getFallbackFunction();
|
FunctionDefinition const* fallbackFunction = nullptr;
|
||||||
if (fallbackFunction && fallbackFunction->getScope() == this && !fallbackFunction->getParameters().empty())
|
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
|
||||||
BOOST_THROW_EXCEPTION(fallbackFunction->getParameterList().createTypeError(
|
{
|
||||||
"Fallback function cannot take parameters."));
|
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())
|
for (ASTPointer<ModifierDefinition> const& modifier: getFunctionModifiers())
|
||||||
modifier->checkTypeRequirements();
|
modifier->checkTypeRequirements();
|
||||||
|
2
AST.h
2
AST.h
@ -250,7 +250,7 @@ public:
|
|||||||
|
|
||||||
/// Returns the constructor or nullptr if no constructor was specified.
|
/// Returns the constructor or nullptr if no constructor was specified.
|
||||||
FunctionDefinition const* getConstructor() const;
|
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;
|
FunctionDefinition const* getFallbackFunction() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -30,6 +30,9 @@ namespace solidity
|
|||||||
|
|
||||||
bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _update)
|
bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _update)
|
||||||
{
|
{
|
||||||
|
if (_declaration.getName().empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!_update && m_declarations.find(_declaration.getName()) != m_declarations.end())
|
if (!_update && m_declarations.find(_declaration.getName()) != m_declarations.end())
|
||||||
return false;
|
return false;
|
||||||
m_declarations[_declaration.getName()] = &_declaration;
|
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
|
Declaration const* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
|
||||||
{
|
{
|
||||||
|
solAssert(!_name.empty(), "Attempt to resolve empty name.");
|
||||||
auto result = m_declarations.find(_name);
|
auto result = m_declarations.find(_name);
|
||||||
if (result != m_declarations.end())
|
if (result != m_declarations.end())
|
||||||
return result->second;
|
return result->second;
|
||||||
|
@ -42,8 +42,8 @@ public:
|
|||||||
explicit DeclarationContainer(Declaration const* _enclosingDeclaration = nullptr,
|
explicit DeclarationContainer(Declaration const* _enclosingDeclaration = nullptr,
|
||||||
DeclarationContainer const* _enclosingContainer = nullptr):
|
DeclarationContainer const* _enclosingContainer = nullptr):
|
||||||
m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {}
|
m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {}
|
||||||
/// Registers the declaration in the scope unless its name is already declared.
|
/// Registers the declaration in the scope unless its name is already declared or the name is empty.
|
||||||
/// @returns true iff it was not yet declared.
|
/// @returns false if the name was already declared.
|
||||||
bool registerDeclaration(Declaration const& _declaration, bool _update = false);
|
bool registerDeclaration(Declaration const& _declaration, bool _update = false);
|
||||||
Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const;
|
Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const;
|
||||||
Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
|
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);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ASTPointer<TypeName> type = parseTypeName(_options.allowVar);
|
ASTPointer<TypeName> type = parseTypeName(_options.allowVar);
|
||||||
bool isIndexed = false;
|
bool isIndexed = false;
|
||||||
|
ASTPointer<ASTString> identifier;
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
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)
|
if (_options.allowIndexed && token == Token::INDEXED)
|
||||||
{
|
{
|
||||||
isIndexed = true;
|
isIndexed = true;
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
Declaration::Visibility visibility(Declaration::Visibility::DEFAULT);
|
if (_options.allowEmptyName && m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||||
if (_options.isStateVariable && Token::isVisibilitySpecifier(token))
|
{
|
||||||
visibility = parseVisibilitySpecifier(token);
|
identifier = make_shared<ASTString>("");
|
||||||
|
nodeFactory.setEndPositionFromNode(type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeFactory.markEndPosition();
|
||||||
|
identifier = expectIdentifierToken();
|
||||||
|
}
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken(),
|
return nodeFactory.createNode<VariableDeclaration>(type, identifier,
|
||||||
visibility, _options.isStateVariable,
|
visibility, _options.isStateVariable,
|
||||||
isIndexed);
|
isIndexed);
|
||||||
}
|
}
|
||||||
@ -402,6 +413,7 @@ ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty, bool _all
|
|||||||
vector<ASTPointer<VariableDeclaration>> parameters;
|
vector<ASTPointer<VariableDeclaration>> parameters;
|
||||||
VarDeclParserOptions options;
|
VarDeclParserOptions options;
|
||||||
options.allowIndexed = _allowIndexed;
|
options.allowIndexed = _allowIndexed;
|
||||||
|
options.allowEmptyName = true;
|
||||||
expectToken(Token::LPAREN);
|
expectToken(Token::LPAREN);
|
||||||
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user