diff options
author | chriseth <c@ethdev.com> | 2016-10-11 05:06:44 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-11-16 21:37:17 +0800 |
commit | 97a3588701edafe9112f35272b5d4c6e23e574b9 (patch) | |
tree | ae688346b781554764aa15b638f076847af82504 /libsolidity | |
parent | dd173f83e3a6a9046d1aa7e64cb171598a73b272 (diff) | |
download | dexon-solidity-97a3588701edafe9112f35272b5d4c6e23e574b9.tar.gz dexon-solidity-97a3588701edafe9112f35272b5d4c6e23e574b9.tar.zst dexon-solidity-97a3588701edafe9112f35272b5d4c6e23e574b9.zip |
Function type state variables.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 97 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 2 |
2 files changed, 68 insertions, 31 deletions
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 421e358f..e844861b 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -217,7 +217,9 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) if (currentTokenValue == Token::RBrace) break; else if (currentTokenValue == Token::Function) - subNodes.push_back(parseFunctionDefinition(name.get())); + // This can be a function or a state variable of function type (especially + // complicated to distinguish fallback function from function type state variable) + subNodes.push_back(parseFunctionDefinitionOrFunctionTypeStateVariable(name.get())); else if (currentTokenValue == Token::Struct) subNodes.push_back(parseStructDefinition()); else if (currentTokenValue == Token::Enum) @@ -334,7 +336,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN return result; } -ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* _contractName) +ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName) { ASTNodeFactory nodeFactory(*this); ASTPointer<ASTString> docstring; @@ -343,28 +345,55 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* FunctionHeaderParserResult header = parseFunctionHeader(false, true); - ASTPointer<Block> block = ASTPointer<Block>(); - nodeFactory.markEndPosition(); - if (m_scanner->currentToken() != Token::Semicolon) + if ( + !header.modifiers.empty() || + !header.name->empty() || + m_scanner->currentToken() == Token::Semicolon || + m_scanner->currentToken() == Token::LBrace + ) { - block = parseBlock(); - nodeFactory.setEndPositionFromNode(block); + // this has to be a function + ASTPointer<Block> block = ASTPointer<Block>(); + nodeFactory.markEndPosition(); + if (m_scanner->currentToken() != Token::Semicolon) + { + block = parseBlock(); + nodeFactory.setEndPositionFromNode(block); + } + else + m_scanner->next(); // just consume the ';' + bool const c_isConstructor = (_contractName && *header.name == *_contractName); + return nodeFactory.createNode<FunctionDefinition>( + header.name, + header.visibility, + c_isConstructor, + docstring, + header.parameters, + header.isDeclaredConst, + header.modifiers, + header.returnParameters, + header.isPayable, + block + ); } else - m_scanner->next(); // just consume the ';' - bool const c_isConstructor = (_contractName && *header.name == *_contractName); - return nodeFactory.createNode<FunctionDefinition>( - header.name, - header.visibility, - c_isConstructor, - docstring, - header.parameters, - header.isDeclaredConst, - header.modifiers, - header.returnParameters, - header.isPayable, - block - ); + { + // this has to be a state variable + ASTPointer<TypeName> type = nodeFactory.createNode<FunctionTypeName>( + header.parameters, + header.returnParameters, + header.visibility, + header.isDeclaredConst, + header.isPayable + ); + type = parseTypeNameSuffix(type, nodeFactory); + VarDeclParserOptions options; + options.isStateVariable = true; + options.allowInitialValue = true; + auto node = parseVariableDeclaration(options, type); + expectToken(Token::Semicolon); + return node; + } } ASTPointer<StructDefinition> Parser::parseStructDefinition() @@ -613,6 +642,21 @@ ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName() return nodeFactory.createNode<UserDefinedTypeName>(identifierPath); } +ASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory) +{ + while (m_scanner->currentToken() == Token::LBrack) + { + m_scanner->next(); + ASTPointer<Expression> length; + if (m_scanner->currentToken() != Token::RBrack) + length = parseExpression(); + nodeFactory.markEndPosition(); + expectToken(Token::RBrack); + type = nodeFactory.createNode<ArrayTypeName>(type, length); + } + return type; +} + ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) { ASTNodeFactory nodeFactory(*this); @@ -644,16 +688,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) if (type) // Parse "[...]" postfixes for arrays. - while (m_scanner->currentToken() == Token::LBrack) - { - m_scanner->next(); - ASTPointer<Expression> length; - if (m_scanner->currentToken() != Token::RBrack) - length = parseExpression(); - nodeFactory.markEndPosition(); - expectToken(Token::RBrack); - type = nodeFactory.createNode<ArrayTypeName>(type, length); - } + type = parseTypeNameSuffix(type, nodeFactory); return type; } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index a59d2688..9295a7fa 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -73,6 +73,7 @@ private: ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier(); Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers); + ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName); ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<StructDefinition> parseStructDefinition(); ASTPointer<EnumDefinition> parseEnumDefinition(); @@ -87,6 +88,7 @@ private: ASTPointer<ModifierInvocation> parseModifierInvocation(); ASTPointer<Identifier> parseIdentifier(); ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName(); + ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory); ASTPointer<TypeName> parseTypeName(bool _allowVar); ASTPointer<FunctionTypeName> parseFunctionType(); ASTPointer<Mapping> parseMapping(); |