aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/parsing
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/parsing')
-rw-r--r--libsolidity/parsing/Parser.cpp97
-rw-r--r--libsolidity/parsing/Parser.h2
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();