diff options
author | chriseth <c@ethdev.com> | 2016-09-28 03:37:32 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-11-16 21:37:17 +0800 |
commit | cc8583ec7d6fd86ca7e129475fde32b76d102e79 (patch) | |
tree | a2df35174d6d95734207add361db5d894fe8592f /libsolidity/parsing | |
parent | c811691861eb51520d9fd51d56770f14990b0320 (diff) | |
download | dexon-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.cpp | 83 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 14 |
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, |