From 60ac4d3a2c3960edec7db7b9e1328c2597c406e9 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 1 Dec 2014 17:03:04 +0100 Subject: [PATCH] Exporting Natspec documentation to a JSON interface - Adding a getDocumentation() function to solidity compiler stack so that we can obtain the natspec interface for a contract - Adding libjsoncpp as a dependency of libsolidity. This is done in a dirty way, using libjsonrpc-cpp s an intermediate dependency for the moment. Will fix soon. - Start of a test file for Natspec exporting to JSON --- libsolidity/AST.h | 2 +- libsolidity/CMakeLists.txt | 4 ++ libsolidity/CompilerStack.cpp | 26 ++++++++++++ libsolidity/CompilerStack.h | 4 ++ test/solidityNatspecJSON.cpp | 77 +++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/solidityNatspecJSON.cpp diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 81a12ad1a..4ed8489fc 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -199,7 +199,7 @@ public: Block& getBody() { return *m_body; } /// @return A shared pointer of an ASTString. /// Can contain a nullptr in which case indicates absence of documentation - ASTPointer const& getDocumentation() { return m_documentation; } + ASTPointer const& getDocumentation() const { return m_documentation; } void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); } std::vector const& getLocalVariables() const { return m_localVariables; } diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index ea2ef4b74..b5147ced3 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -16,6 +16,10 @@ endif() include_directories(..) target_link_libraries(${EXECUTABLE} evmcore devcore) +# TODO: Temporary until PR 532 https://github.com/ethereum/cpp-ethereum/pull/532 +# gets accepted. Then we can simply add jsoncpp as a dependency and not the +# whole of JSONRPC as we are doing right here +target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 6535e00d4..45d3e0b8a 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -28,6 +28,8 @@ #include #include +#include + using namespace std; namespace dev @@ -125,6 +127,30 @@ string const& CompilerStack::getInterface() return m_interface; } +string const& CompilerStack::getDocumentation() +{ + + Json::StyledWriter writer; + if (!m_parseSuccessful) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); + if (m_documentation.empty()) + { + Json::Value doc; + Json::Value methods; + + vector exportedFunctions = m_contractASTNode->getInterfaceFunctions(); + for (FunctionDefinition const* f: exportedFunctions) + { + Json::Value user; + user["user"] = Json::Value(*f->getDocumentation()); + methods[f->getName()] = user; + } + doc["methods"] = methods; + m_documentation = writer.write(doc); + } + return m_documentation; +} + bytes CompilerStack::staticCompile(std::string const& _sourceCode, bool _optimize) { CompilerStack stack; diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 6cae8660f..74784c5ef 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -62,6 +62,9 @@ public: /// Returns a string representing the contract interface in JSON. /// Prerequisite: Successful call to parse or compile. std::string const& getInterface(); + /// Returns a string representing the contract documentation in JSON. + /// Prerequisite: Successful call to parse or compile. + std::string const& getDocumentation(); /// Returns the previously used scanner, useful for counting lines during error reporting. Scanner const& getScanner() const { return *m_scanner; } @@ -77,6 +80,7 @@ private: std::shared_ptr m_contractASTNode; bool m_parseSuccessful; std::string m_interface; + std::string m_documentation; std::shared_ptr m_compiler; bytes m_bytecode; }; diff --git a/test/solidityNatspecJSON.cpp b/test/solidityNatspecJSON.cpp new file mode 100644 index 000000000..5918eec99 --- /dev/null +++ b/test/solidityNatspecJSON.cpp @@ -0,0 +1,77 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** + * @author Lefteris Karapetsas + * @date 2014 + * Unit tests for the solidity compiler JSON Interface output. + */ + +#include +#include +#include + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +class DocumentationChecker +{ +public: + void checkNatspec(std::string const& _code, std::string const& _expectedDocumentationString) + { + m_compilerStack.parse(_code); + auto generatedDocumentationString = m_compilerStack.getDocumentation(); + Json::Value generatedDocumentation; + m_reader.parse(generatedDocumentationString, generatedDocumentation); + Json::Value expectedDocumentation; + m_reader.parse(_expectedDocumentationString, expectedDocumentation); + BOOST_CHECK_MESSAGE(expectedDocumentation == generatedDocumentation, + "Expected " << _expectedDocumentationString << + "\n but got:\n" << generatedDocumentationString); + } + +private: + CompilerStack m_compilerStack; + Json::Reader m_reader; +}; + +BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker) + +BOOST_AUTO_TEST_CASE(basic_test) +{ + char const* sourceCode = "contract test {\n" + " /// Multiplies `a` by 7\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \"user\": \" Multiplies `a` by 7\"}" + "}}"; + + checkNatspec(sourceCode, natspec); +} + + +BOOST_AUTO_TEST_SUITE_END() + +} +} +}