aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/parsing
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-09-28 03:37:32 +0800
committerchriseth <c@ethdev.com>2016-11-16 21:37:17 +0800
commitcc8583ec7d6fd86ca7e129475fde32b76d102e79 (patch)
treea2df35174d6d95734207add361db5d894fe8592f /libsolidity/parsing
parentc811691861eb51520d9fd51d56770f14990b0320 (diff)
downloaddexon-solidity-cc8583ec7d6fd86ca7e129475fde32b76d102e79.tar.gz
dexon-solidity-cc8583ec7d6fd86ca7e129475fde32b76d102e79.tar.zst
dexon-solidity-cc8583ec7d6fd86ca7e129475fde32b76d102e79.zip
Function types.
Diffstat (limited to 'libsolidity/parsing')
-rw-r--r--libsolidity/parsing/Parser.cpp83
-rw-r--r--libsolidity/parsing/Parser.h14
2 files changed, 64 insertions, 33 deletions
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index df3ed7b2..421e358f 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -288,59 +288,61 @@ Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
return visibility;
}
-ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* _contractName)
+Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers)
{
- ASTNodeFactory nodeFactory(*this);
- ASTPointer<ASTString> docstring;
- if (m_scanner->currentCommentLiteral() != "")
- docstring = make_shared<ASTString>(m_scanner->currentCommentLiteral());
-
+ FunctionHeaderParserResult result;
expectToken(Token::Function);
- ASTPointer<ASTString> name;
- if (m_scanner->currentToken() == Token::LParen)
- name = make_shared<ASTString>(); // anonymous function
+ if (_forceEmptyName || m_scanner->currentToken() == Token::LParen)
+ result.name = make_shared<ASTString>(); // anonymous function
else
- name = expectIdentifierToken();
+ result.name = expectIdentifierToken();
VarDeclParserOptions options;
options.allowLocationSpecifier = true;
- ASTPointer<ParameterList> parameters(parseParameterList(options));
- bool isDeclaredConst = false;
- bool isPayable = false;
- Declaration::Visibility visibility(Declaration::Visibility::Default);
- vector<ASTPointer<ModifierInvocation>> modifiers;
+ result.parameters = parseParameterList(options);
while (true)
{
Token::Value token = m_scanner->currentToken();
if (token == Token::Const)
{
- isDeclaredConst = true;
+ result.isDeclaredConst = true;
m_scanner->next();
}
else if (m_scanner->currentToken() == Token::Payable)
{
- isPayable = true;
+ result.isPayable = true;
m_scanner->next();
}
- else if (token == Token::Identifier)
- modifiers.push_back(parseModifierInvocation());
+ else if (_allowModifiers && token == Token::Identifier)
+ result.modifiers.push_back(parseModifierInvocation());
else if (Token::isVisibilitySpecifier(token))
{
- if (visibility != Declaration::Visibility::Default)
+ if (result.visibility != Declaration::Visibility::Default)
fatalParserError(string("Multiple visibility specifiers."));
- visibility = parseVisibilitySpecifier(token);
+ result.visibility = parseVisibilitySpecifier(token);
}
else
break;
}
- ASTPointer<ParameterList> returnParameters;
if (m_scanner->currentToken() == Token::Returns)
{
bool const permitEmptyParameterList = false;
m_scanner->next();
- returnParameters = parseParameterList(options, permitEmptyParameterList);
+ result.returnParameters = parseParameterList(options, permitEmptyParameterList);
}
else
- returnParameters = createEmptyParameterList();
+ result.returnParameters = createEmptyParameterList();
+ return result;
+}
+
+ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* _contractName)
+{
+ ASTNodeFactory nodeFactory(*this);
+ ASTPointer<ASTString> docstring;
+ if (m_scanner->currentCommentLiteral() != "")
+ docstring = make_shared<ASTString>(m_scanner->currentCommentLiteral());
+
+ FunctionHeaderParserResult header = parseFunctionHeader(false, true);
+
ASTPointer<Block> block = ASTPointer<Block>();
nodeFactory.markEndPosition();
if (m_scanner->currentToken() != Token::Semicolon)
@@ -350,17 +352,17 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const*
}
else
m_scanner->next(); // just consume the ';'
- bool const c_isConstructor = (_contractName && *name == *_contractName);
+ bool const c_isConstructor = (_contractName && *header.name == *_contractName);
return nodeFactory.createNode<FunctionDefinition>(
- name,
- visibility,
+ header.name,
+ header.visibility,
c_isConstructor,
docstring,
- parameters,
- isDeclaredConst,
- modifiers,
- returnParameters,
- isPayable,
+ header.parameters,
+ header.isDeclaredConst,
+ header.modifiers,
+ header.returnParameters,
+ header.isPayable,
block
);
}
@@ -631,6 +633,8 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
fatalParserError(string("Expected explicit type name."));
m_scanner->next();
}
+ else if (token == Token::Function)
+ type = parseFunctionType();
else if (token == Token::Mapping)
type = parseMapping();
else if (token == Token::Identifier)
@@ -653,6 +657,19 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
return type;
}
+ASTPointer<FunctionTypeName> Parser::parseFunctionType()
+{
+ ASTNodeFactory nodeFactory(*this);
+ FunctionHeaderParserResult header = parseFunctionHeader(true, false);
+ return nodeFactory.createNode<FunctionTypeName>(
+ header.parameters,
+ header.returnParameters,
+ header.visibility,
+ header.isDeclaredConst,
+ header.isPayable
+ );
+}
+
ASTPointer<Mapping> Parser::parseMapping()
{
ASTNodeFactory nodeFactory(*this);
@@ -1278,7 +1295,7 @@ Parser::LookAheadInfo Parser::peekStatementType() const
Token::Value token(m_scanner->currentToken());
bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier);
- if (token == Token::Mapping || token == Token::Var)
+ if (token == Token::Mapping || token == Token::Function || token == Token::Var)
return LookAheadInfo::VariableDeclarationStatement;
if (mightBeTypeName)
{
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index 26f347cb..a59d2688 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -53,6 +53,18 @@ private:
bool allowLocationSpecifier = false;
};
+ /// This struct is shared for parsing a function header and a function type.
+ struct FunctionHeaderParserResult
+ {
+ ASTPointer<ASTString> name;
+ ASTPointer<ParameterList> parameters;
+ ASTPointer<ParameterList> returnParameters;
+ Declaration::Visibility visibility = Declaration::Visibility::Default;
+ bool isDeclaredConst = false;
+ bool isPayable = false;
+ std::vector<ASTPointer<ModifierInvocation>> modifiers;
+ };
+
///@{
///@name Parsing functions for the AST nodes
ASTPointer<PragmaDirective> parsePragmaDirective();
@@ -60,6 +72,7 @@ private:
ASTPointer<ContractDefinition> parseContractDefinition(bool _isLibrary);
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Declaration::Visibility parseVisibilitySpecifier(Token::Value _token);
+ FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers);
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);
ASTPointer<StructDefinition> parseStructDefinition();
ASTPointer<EnumDefinition> parseEnumDefinition();
@@ -75,6 +88,7 @@ private:
ASTPointer<Identifier> parseIdentifier();
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
ASTPointer<TypeName> parseTypeName(bool _allowVar);
+ ASTPointer<FunctionTypeName> parseFunctionType();
ASTPointer<Mapping> parseMapping();
ASTPointer<ParameterList> parseParameterList(
VarDeclParserOptions const& _options,