diff --git a/libsolidity/AST.h b/libsolidity/AST.h index dc34e3695..81a12ad1a 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -173,8 +173,9 @@ private: class FunctionDefinition: public Declaration { public: - FunctionDefinition(Location const& _location, ASTPointer const& _name, bool _isPublic, - std::string const& _documentation, + FunctionDefinition(Location const& _location, ASTPointer const& _name, + bool _isPublic, + ASTPointer const& _documentation, ASTPointer const& _parameters, bool _isDeclaredConst, ASTPointer const& _returnParameters, @@ -184,7 +185,9 @@ public: m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters), m_body(_body), - m_documentation(_documentation) {} + m_documentation(_documentation) + {} + virtual void accept(ASTVisitor& _visitor) override; bool isPublic() const { return m_isPublic; } @@ -194,7 +197,9 @@ public: std::vector> const& getReturnParameters() const { return m_returnParameters->getParameters(); } ASTPointer const& getReturnParameterList() const { return m_returnParameters; } Block& getBody() { return *m_body; } - std::string& getDocumentation() { return m_documentation; } + /// @return A shared pointer of an ASTString. + /// Can contain a nullptr in which case indicates absence of documentation + ASTPointer const& getDocumentation() { return m_documentation; } void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); } std::vector const& getLocalVariables() const { return m_localVariables; } @@ -208,7 +213,7 @@ private: bool m_isDeclaredConst; ASTPointer m_returnParameters; ASTPointer m_body; - std::string m_documentation; + ASTPointer m_documentation; std::vector m_localVariables; }; diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 17fd2d78c..72921623a 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -117,9 +117,13 @@ ASTPointer Parser::parseContractDefinition() ASTPointer Parser::parseFunctionDefinition(bool _isPublic) { ASTNodeFactory nodeFactory(*this); + ASTPointer docstring; expectToken(Token::FUNCTION); - std::string docstring = m_scanner->getCurrentCommentLiteral(); - m_scanner->clearCurrentCommentLiteral(); + if (m_scanner->getCurrentCommentLiteral() != "") + { + docstring = std::make_shared(m_scanner->getCurrentCommentLiteral()); + m_scanner->clearCurrentCommentLiteral(); + } ASTPointer name(expectIdentifierToken()); ASTPointer parameters(parseParameterList()); bool isDeclaredConst = false; diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index 3a95ec065..89ef0ac0f 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) BOOST_CHECK_NO_THROW(contract = parseText(text)); auto functions = contract->getDefinedFunctions(); BOOST_CHECK_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(function->getDocumentation(), " This is a test function"); + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is a test function"); } BOOST_AUTO_TEST_CASE(function_normal_comments) @@ -119,7 +119,8 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) BOOST_CHECK_NO_THROW(contract = parseText(text)); auto functions = contract->getDefinedFunctions(); BOOST_CHECK_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(function->getDocumentation(), ""); + BOOST_CHECK_MESSAGE(function->getDocumentation().get() == nullptr, + "Should not have gotten a Natspect comment for this function"); } BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) @@ -141,16 +142,17 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) auto functions = contract->getDefinedFunctions(); BOOST_CHECK_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(function->getDocumentation(), " This is test function 1"); + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is test function 1"); BOOST_CHECK_NO_THROW(function = functions.at(1)); - BOOST_CHECK_EQUAL(function->getDocumentation(), " This is test function 2"); + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is test function 2"); BOOST_CHECK_NO_THROW(function = functions.at(2)); - BOOST_CHECK_EQUAL(function->getDocumentation(), ""); + BOOST_CHECK_MESSAGE(function->getDocumentation().get() == nullptr, + "Should not have gotten natspec comment for functionName3()"); BOOST_CHECK_NO_THROW(function = functions.at(3)); - BOOST_CHECK_EQUAL(function->getDocumentation(), " This is test function 4"); + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is test function 4"); } BOOST_AUTO_TEST_CASE(multiline_function_documentation) @@ -167,7 +169,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) auto functions = contract->getDefinedFunctions(); BOOST_CHECK_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(function->getDocumentation(), + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is a test function\n" " and it has 2 lines"); } @@ -194,10 +196,10 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) auto functions = contract->getDefinedFunctions(); BOOST_CHECK_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(function->getDocumentation(), " fun1 description"); + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " fun1 description"); BOOST_CHECK_NO_THROW(function = functions.at(1)); - BOOST_CHECK_EQUAL(function->getDocumentation(), + BOOST_CHECK_EQUAL(*function->getDocumentation().get(), " This is a test function\n" " and it has 2 lines"); }