Browse Source

Natspec @return tag parsing

- Also omitting tags from the output JSON file if they are missing
  instead of providing an empty string for their value
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
69bb2a38b9
  1. 32
      libsolidity/InterfaceHandler.cpp
  2. 4
      libsolidity/InterfaceHandler.h
  3. 74
      test/solidityNatspecJSON.cpp

32
libsolidity/InterfaceHandler.cpp

@ -75,8 +75,11 @@ std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(std::shared_
{ {
resetUser(); resetUser();
parseDocString(*strPtr); parseDocString(*strPtr);
user["notice"] = Json::Value(m_notice); if (!m_notice.empty())
methods[f->getName()] = user; {// since @notice is the only user tag if missing function should not appear
user["notice"] = Json::Value(m_notice);
methods[f->getName()] = user;
}
} }
} }
doc["methods"] = methods; doc["methods"] = methods;
@ -86,6 +89,8 @@ std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(std::shared_
std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_ptr<ContractDefinition> _contractDef) std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_ptr<ContractDefinition> _contractDef)
{ {
// LTODO: Somewhere in this function warnings for mismatch of param names
// should be thrown
Json::Value doc; Json::Value doc;
Json::Value methods(Json::objectValue); Json::Value methods(Json::objectValue);
@ -98,14 +103,20 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_p
resetDev(); resetDev();
parseDocString(*strPtr); parseDocString(*strPtr);
method["details"] = Json::Value(m_dev); if (!m_dev.empty())
method["details"] = Json::Value(m_dev);
Json::Value params(Json::objectValue); Json::Value params(Json::objectValue);
for (auto const& pair: m_params) for (auto const& pair: m_params)
{ {
params[pair.first] = pair.second; params[pair.first] = pair.second;
} }
method["params"] = params; if (!m_params.empty())
methods[f->getName()] = method; method["params"] = params;
if (!m_return.empty())
method["return"] = m_return;
if (!method.empty()) // add the function, only if we have any documentation to add
methods[f->getName()] = method;
} }
} }
doc["methods"] = methods; doc["methods"] = methods;
@ -122,6 +133,7 @@ void InterfaceHandler::resetUser()
void InterfaceHandler::resetDev() void InterfaceHandler::resetDev()
{ {
m_dev.clear(); m_dev.clear();
m_return.clear();
m_params.clear(); m_params.clear();
} }
@ -188,7 +200,7 @@ size_t InterfaceHandler::appendDocTagParam(std::string const& _string, size_t _s
size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos) size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos)
{ {
//TODO: need to check for @(start of a tag) between here and the end of line // LTODO: need to check for @(start of a tag) between here and the end of line
// for all cases // for all cases
size_t nlPos = _pos; size_t nlPos = _pos;
if (m_lastTag == DOCTAG_NONE || _tag != "") if (m_lastTag == DOCTAG_NONE || _tag != "")
@ -197,11 +209,13 @@ size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string con
nlPos = parseDocTagLine(_string, m_dev, _pos, DOCTAG_DEV); nlPos = parseDocTagLine(_string, m_dev, _pos, DOCTAG_DEV);
else if (_tag == "notice") else if (_tag == "notice")
nlPos = parseDocTagLine(_string, m_notice, _pos, DOCTAG_NOTICE); nlPos = parseDocTagLine(_string, m_notice, _pos, DOCTAG_NOTICE);
else if (_tag == "return")
nlPos = parseDocTagLine(_string, m_return, _pos, DOCTAG_RETURN);
else if (_tag == "param") else if (_tag == "param")
nlPos = parseDocTagParam(_string, _pos); nlPos = parseDocTagParam(_string, _pos);
else else
{ {
//TODO: Some form of warning // LTODO: Unknown tas, throw some form of warning
} }
} }
else else
@ -223,6 +237,10 @@ size_t InterfaceHandler::appendDocTag(std::string const& _string, size_t _startP
m_notice += " "; m_notice += " ";
newPos = parseDocTagLine(_string, m_notice, _startPos, DOCTAG_NOTICE); newPos = parseDocTagLine(_string, m_notice, _startPos, DOCTAG_NOTICE);
break; break;
case DOCTAG_RETURN:
m_return += " ";
newPos = parseDocTagLine(_string, m_return, _startPos, DOCTAG_RETURN);
break;
case DOCTAG_PARAM: case DOCTAG_PARAM:
newPos = appendDocTagParam(_string, _startPos); newPos = appendDocTagParam(_string, _startPos);
break; break;

4
libsolidity/InterfaceHandler.h

@ -42,7 +42,8 @@ enum docTagType
DOCTAG_NONE = 0, DOCTAG_NONE = 0,
DOCTAG_DEV, DOCTAG_DEV,
DOCTAG_NOTICE, DOCTAG_NOTICE,
DOCTAG_PARAM DOCTAG_PARAM,
DOCTAG_RETURN
}; };
class InterfaceHandler class InterfaceHandler
@ -91,6 +92,7 @@ private:
enum docTagType m_lastTag; enum docTagType m_lastTag;
std::string m_notice; std::string m_notice;
std::string m_dev; std::string m_dev;
std::string m_return;
std::vector<std::pair<std::string, std::string>> m_params; std::vector<std::pair<std::string, std::string>> m_params;
}; };

74
test/solidityNatspecJSON.cpp

@ -100,8 +100,7 @@ BOOST_AUTO_TEST_CASE(dev_and_user_basic_test)
char const* devNatspec = "{" char const* devNatspec = "{"
"\"methods\":{" "\"methods\":{"
" \"mul\":{ \n" " \"mul\":{ \n"
" \"details\": \"Multiplies a number by 7\",\n" " \"details\": \"Multiplies a number by 7\"\n"
" \"params\": {}\n"
" }\n" " }\n"
" }\n" " }\n"
"}}"; "}}";
@ -175,6 +174,24 @@ BOOST_AUTO_TEST_CASE(user_empty_contract)
checkNatspec(sourceCode, natspec, true); checkNatspec(sourceCode, natspec, true);
} }
BOOST_AUTO_TEST_CASE(dev_and_user_no_doc)
{
char const* sourceCode = "contract test {\n"
" function mul(uint a) returns(uint d) { return a * 7; }\n"
" function sub(int input) returns(int d)\n"
" {\n"
" return input - 3;\n"
" }\n"
"}\n";
char const* devNatspec = "{\"methods\":{}}";
char const* userNatspec = "{\"methods\":{}}";
checkNatspec(sourceCode, devNatspec, false);
checkNatspec(sourceCode, userNatspec, true);
}
BOOST_AUTO_TEST_CASE(dev_multiple_params) BOOST_AUTO_TEST_CASE(dev_multiple_params)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
@ -272,6 +289,59 @@ BOOST_AUTO_TEST_CASE(dev_multiple_functions)
checkNatspec(sourceCode, natspec, false); checkNatspec(sourceCode, natspec, false);
} }
BOOST_AUTO_TEST_CASE(dev_return)
{
char const* sourceCode = "contract test {\n"
" /// @dev Multiplies a number by 7 and adds second parameter\n"
" /// @param a Documentation for the first parameter starts here.\n"
" /// Since it's a really complicated parameter we need 2 lines\n"
" /// @param second Documentation for the second parameter\n"
" /// @return The result of the multiplication\n"
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
"}\n";
char const* natspec = "{"
"\"methods\":{"
" \"mul\":{ \n"
" \"details\": \"Multiplies a number by 7 and adds second parameter\",\n"
" \"params\": {\n"
" \"a\": \"Documentation for the first parameter starts here.Since it's a really complicated parameter we need 2 lines\",\n"
" \"second\": \"Documentation for the second parameter\"\n"
" },\n"
" \"return\": \"The result of the multiplication\"\n"
" }\n"
"}}";
checkNatspec(sourceCode, natspec, false);
}
BOOST_AUTO_TEST_CASE(dev_multiline_return)
{
char const* sourceCode = "contract test {\n"
" /// @dev Multiplies a number by 7 and adds second parameter\n"
" /// @param a Documentation for the first parameter starts here.\n"
" /// Since it's a really complicated parameter we need 2 lines\n"
" /// @param second Documentation for the second parameter\n"
" /// @return The result of the multiplication\n"
" /// and cookies with nutella\n"
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
"}\n";
char const* natspec = "{"
"\"methods\":{"
" \"mul\":{ \n"
" \"details\": \"Multiplies a number by 7 and adds second parameter\",\n"
" \"params\": {\n"
" \"a\": \"Documentation for the first parameter starts here.Since it's a really complicated parameter we need 2 lines\",\n"
" \"second\": \"Documentation for the second parameter\"\n"
" },\n"
" \"return\": \"The result of the multiplication and cookies with nutella\"\n"
" }\n"
"}}";
checkNatspec(sourceCode, natspec, false);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save