diff options
-rw-r--r-- | AST.cpp | 4 | ||||
-rw-r--r-- | AST.h | 85 | ||||
-rw-r--r-- | AST_accept.h | 6 | ||||
-rw-r--r-- | Parser.cpp | 33 |
4 files changed, 89 insertions, 39 deletions
@@ -311,8 +311,8 @@ void FunctionDefinition::checkTypeRequirements() modifier->checkTypeRequirements(isConstructor() ? dynamic_cast<ContractDefinition const&>(*getScope()).getBaseContracts() : vector<ASTPointer<InheritanceSpecifier>>()); - - m_body->checkTypeRequirements(); + if (m_body) + m_body->checkTypeRequirements(); } string FunctionDefinition::getCanonicalSignature() const @@ -196,6 +196,21 @@ protected: ASTPointer<ASTString> m_documentation; }; +/** + * Abstract class that is added to AST nodes that can be marked as not being fully implemented + */ +class ImplementationOptional +{ +public: + explicit ImplementationOptional(bool _implemented): m_implemented(_implemented) {} + + /// @return whether this node is fully implemented or not + bool isFullyImplemented() const { return m_implemented; } + +protected: + bool m_implemented; +}; + /// @} /** @@ -203,20 +218,25 @@ protected: * document order. It first visits all struct declarations, then all variable declarations and * finally all function declarations. */ -class ContractDefinition: public Declaration, public Documented +class ContractDefinition: public Declaration, public Documented, public ImplementationOptional { public: - ContractDefinition(SourceLocation const& _location, - ASTPointer<ASTString> const& _name, - ASTPointer<ASTString> const& _documentation, - std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts, - std::vector<ASTPointer<StructDefinition>> const& _definedStructs, - std::vector<ASTPointer<EnumDefinition>> const& _definedEnums, - std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables, - std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions, - std::vector<ASTPointer<ModifierDefinition>> const& _functionModifiers, - std::vector<ASTPointer<EventDefinition>> const& _events): - Declaration(_location, _name), Documented(_documentation), + ContractDefinition( + SourceLocation const& _location, + ASTPointer<ASTString> const& _name, + ASTPointer<ASTString> const& _documentation, + std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts, + std::vector<ASTPointer<StructDefinition>> const& _definedStructs, + std::vector<ASTPointer<EnumDefinition>> const& _definedEnums, + std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables, + std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions, + std::vector<ASTPointer<ModifierDefinition>> const& _functionModifiers, + std::vector<ASTPointer<EventDefinition>> const& _events, + bool _isFullyImplemented + ): + Declaration(_location, _name), + Documented(_documentation), + ImplementationOptional(_isFullyImplemented), m_baseContracts(_baseContracts), m_definedStructs(_definedStructs), m_definedEnums(_definedEnums), @@ -224,7 +244,7 @@ public: m_definedFunctions(_definedFunctions), m_functionModifiers(_functionModifiers), m_events(_events) - {} + {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -378,25 +398,30 @@ private: std::vector<ASTPointer<VariableDeclaration>> m_parameters; }; -class FunctionDefinition: public Declaration, public VariableScope, public Documented +class FunctionDefinition: public Declaration, public VariableScope, public Documented, public ImplementationOptional { public: - FunctionDefinition(SourceLocation const& _location, ASTPointer<ASTString> const& _name, - Declaration::Visibility _visibility, bool _isConstructor, - ASTPointer<ASTString> const& _documentation, - ASTPointer<ParameterList> const& _parameters, - bool _isDeclaredConst, - std::vector<ASTPointer<ModifierInvocation>> const& _modifiers, - ASTPointer<ParameterList> const& _returnParameters, - ASTPointer<Block> const& _body): - Declaration(_location, _name, _visibility), Documented(_documentation), - m_isConstructor(_isConstructor), - m_parameters(_parameters), - m_isDeclaredConst(_isDeclaredConst), - m_functionModifiers(_modifiers), - m_returnParameters(_returnParameters), - m_body(_body) - {} + FunctionDefinition( + SourceLocation const& _location, + ASTPointer<ASTString> const& _name, + Declaration::Visibility _visibility, bool _isConstructor, + ASTPointer<ASTString> const& _documentation, + ASTPointer<ParameterList> const& _parameters, + bool _isDeclaredConst, + std::vector<ASTPointer<ModifierInvocation>> const& _modifiers, + ASTPointer<ParameterList> const& _returnParameters, + ASTPointer<Block> const& _body + ): + Declaration(_location, _name, _visibility), + Documented(_documentation), + ImplementationOptional(_body != nullptr), + m_isConstructor(_isConstructor), + m_parameters(_parameters), + m_isDeclaredConst(_isDeclaredConst), + m_functionModifiers(_modifiers), + m_returnParameters(_returnParameters), + m_body(_body) + {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; diff --git a/AST_accept.h b/AST_accept.h index 81ede8fc..3557f877 100644 --- a/AST_accept.h +++ b/AST_accept.h @@ -175,7 +175,8 @@ void FunctionDefinition::accept(ASTVisitor& _visitor) if (m_returnParameters) m_returnParameters->accept(_visitor); listAccept(m_functionModifiers, _visitor); - m_body->accept(_visitor); + if (m_body) + m_body->accept(_visitor); } _visitor.endVisit(*this); } @@ -188,7 +189,8 @@ void FunctionDefinition::accept(ASTConstVisitor& _visitor) const if (m_returnParameters) m_returnParameters->accept(_visitor); listAccept(m_functionModifiers, _visitor); - m_body->accept(_visitor); + if (m_body) + m_body->accept(_visitor); } _visitor.endVisit(*this); } @@ -116,6 +116,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() { ASTNodeFactory nodeFactory(*this); ASTPointer<ASTString> docString; + bool contractFullyImplemented = true; if (m_scanner->getCurrentCommentLiteral() != "") docString = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral()); expectToken(Token::Contract); @@ -141,7 +142,12 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() if (currentToken == Token::RBrace) break; else if (currentToken == Token::Function) - functions.push_back(parseFunctionDefinition(name.get())); + { + ASTPointer<FunctionDefinition> func = parseFunctionDefinition(name.get()); + functions.push_back(func); + if (!func->isFullyImplemented()) + contractFullyImplemented = false; + } else if (currentToken == Token::Struct) structs.push_back(parseStructDefinition()); else if (currentToken == Token::Enum) @@ -164,8 +170,18 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() } nodeFactory.markEndPosition(); expectToken(Token::RBrace); - return nodeFactory.createNode<ContractDefinition>(name, docString, baseContracts, structs, enums, - stateVariables, functions, modifiers, events); + return nodeFactory.createNode<ContractDefinition>( + name, + docString, + baseContracts, + structs, + enums, + stateVariables, + functions, + modifiers, + events, + contractFullyImplemented + ); } ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier() @@ -247,8 +263,15 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* } else returnParameters = createEmptyParameterList(); - ASTPointer<Block> block = parseBlock(); - nodeFactory.setEndPositionFromNode(block); + ASTPointer<Block> block = ASTPointer<Block>(); + nodeFactory.markEndPosition(); + if (m_scanner->getCurrentToken() != Token::Semicolon) + { + block = parseBlock(); + nodeFactory.setEndPositionFromNode(block); + } + else + m_scanner->next(); // just consume the ';' bool const c_isConstructor = (_contractName && *name == *_contractName); return nodeFactory.createNode<FunctionDefinition>(name, visibility, c_isConstructor, docstring, parameters, isDeclaredConst, modifiers, |