aboutsummaryrefslogtreecommitdiffstats
path: root/InterfaceHandler.cpp
diff options
context:
space:
mode:
authorLefteris Karapetsas <lefteris@refu.co>2014-12-05 00:19:47 +0800
committerLefteris Karapetsas <lefteris@refu.co>2014-12-05 00:19:47 +0800
commit05964375f888e8b8a3ccf5bc01d9cfff8fd00566 (patch)
treea210bf1abee81bf7193a26414f6e5ae635d03eed /InterfaceHandler.cpp
parent3e803b40e1b22daf8e3ac45593aec6798d365ccb (diff)
downloaddexon-solidity-05964375f888e8b8a3ccf5bc01d9cfff8fd00566.tar.gz
dexon-solidity-05964375f888e8b8a3ccf5bc01d9cfff8fd00566.tar.zst
dexon-solidity-05964375f888e8b8a3ccf5bc01d9cfff8fd00566.zip
Natspec parsing @param doctags
- Plus additional work on generally parsing doctags. One important missing feature is to parse a tag midline - Adding more tests
Diffstat (limited to 'InterfaceHandler.cpp')
-rw-r--r--InterfaceHandler.cpp158
1 files changed, 115 insertions, 43 deletions
diff --git a/InterfaceHandler.cpp b/InterfaceHandler.cpp
index e7da5e6d..222711e6 100644
--- a/InterfaceHandler.cpp
+++ b/InterfaceHandler.cpp
@@ -1,3 +1,4 @@
+
#include <libsolidity/InterfaceHandler.h>
#include <libsolidity/AST.h>
#include <libsolidity/CompilerStack.h>
@@ -72,7 +73,7 @@ std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(std::shared_
auto strPtr = f->getDocumentation();
if (strPtr)
{
- m_notice.clear();
+ resetUser();
parseDocString(*strPtr);
user["notice"] = Json::Value(m_notice);
methods[f->getName()] = user;
@@ -94,10 +95,16 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_p
auto strPtr = f->getDocumentation();
if (strPtr)
{
- m_dev.clear();
+ resetDev();
parseDocString(*strPtr);
method["details"] = Json::Value(m_dev);
+ Json::Value params(Json::objectValue);
+ for (auto const& pair: m_params)
+ {
+ params[pair.first] = pair.second;
+ }
+ method["params"] = params;
methods[f->getName()] = method;
}
}
@@ -107,86 +114,151 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_p
}
/* -- private -- */
+void InterfaceHandler::resetUser()
+{
+ m_notice.clear();
+}
+
+void InterfaceHandler::resetDev()
+{
+ m_dev.clear();
+ m_params.clear();
+}
+
+size_t skipLineOrEOS(std::string const& _string, size_t _nlPos)
+{
+ return (_nlPos == std::string::npos) ? _string.length() : _nlPos + 1;
+}
+
+size_t InterfaceHandler::parseDocTagLine(std::string const& _string,
+ std::string& _tagString,
+ size_t _pos,
+ enum docTagType _tagType)
+{
+ size_t nlPos = _string.find("\n", _pos);
+ _tagString += _string.substr(_pos,
+ nlPos == std::string::npos ?
+ _string.length() :
+ nlPos - _pos);
+ m_lastTag = _tagType;
+ return skipLineOrEOS(_string, nlPos);
+}
+
+size_t InterfaceHandler::parseDocTagParam(std::string const& _string, size_t _startPos)
+{
+ // find param name
+ size_t currPos = _string.find(" ", _startPos);
+ if (currPos == std::string::npos)
+ {
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("End of param name not found"));
+ return currPos; //no end of tag found
+ }
+
+ auto paramName = _string.substr(_startPos, currPos - _startPos);
+
+ currPos += 1;
+ size_t nlPos = _string.find("\n", currPos);
+ auto paramDesc = _string.substr(currPos,
+ nlPos == std::string::npos ?
+ _string.length() :
+ nlPos - currPos);
+
+ m_params.push_back(std::make_pair(paramName, paramDesc));
+
+ m_lastTag = DOCTAG_PARAM;
+ return skipLineOrEOS(_string, nlPos);
+}
+
+size_t InterfaceHandler::appendDocTagParam(std::string const& _string, size_t _startPos)
+{
+ // Should never be called with an empty vector
+ assert(!m_params.empty());
+
+ auto pair = m_params.back();
+ size_t nlPos = _string.find("\n", _startPos);
+ pair.second += _string.substr(_startPos,
+ nlPos == std::string::npos ?
+ _string.length() :
+ nlPos - _startPos);
+
+ m_params.at(m_params.size() - 1) = pair;
+
+ return skipLineOrEOS(_string, nlPos);
+}
+
size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos)
{
- //TODO: This is pretty naive at the moment. e.g. need to check for
- // '@' between _pos and \n, remove redundancy e.t.c.
+ //TODO: need to check for @(start of a tag) between here and the end of line
+ // for all cases
size_t nlPos = _pos;
if (m_lastTag == DOCTAG_NONE || _tag != "")
{
if (_tag == "dev")
- {
- nlPos = _string.find("\n", _pos);
- m_dev += _string.substr(_pos,
- nlPos == std::string::npos ?
- _string.length() :
- nlPos - _pos);
- m_lastTag = DOCTAG_DEV;
- }
+ nlPos = parseDocTagLine(_string, m_dev, _pos, DOCTAG_DEV);
else if (_tag == "notice")
- {
- nlPos = _string.find("\n", _pos);
- m_notice += _string.substr(_pos,
- nlPos == std::string::npos ?
- _string.length() :
- nlPos - _pos);
- m_lastTag = DOCTAG_NOTICE;
- }
+ nlPos = parseDocTagLine(_string, m_notice, _pos, DOCTAG_NOTICE);
+ else if (_tag == "param")
+ nlPos = parseDocTagParam(_string, _pos);
else
{
//TODO: Some form of warning
}
}
else
+ appendDocTag(_string, _pos);
+
+ return nlPos;
+}
+
+size_t InterfaceHandler::appendDocTag(std::string const& _string, size_t _startPos)
+{
+ size_t newPos = _startPos;
+ switch(m_lastTag)
{
- switch(m_lastTag)
- {
case DOCTAG_DEV:
- nlPos = _string.find("\n", _pos);
- m_dev += _string.substr(_pos,
- nlPos == std::string::npos ?
- _string.length() :
- nlPos - _pos);
+ m_dev += " ";
+ newPos = parseDocTagLine(_string, m_dev, _startPos, DOCTAG_DEV);
break;
case DOCTAG_NOTICE:
- nlPos = _string.find("\n", _pos);
- m_notice += _string.substr(_pos,
- nlPos == std::string::npos ?
- _string.length() :
- nlPos - _pos);
+ m_notice += " ";
+ newPos = parseDocTagLine(_string, m_notice, _startPos, DOCTAG_NOTICE);
+ break;
+ case DOCTAG_PARAM:
+ newPos = appendDocTagParam(_string, _startPos);
break;
default:
break;
}
- }
-
- return nlPos;
+ return newPos;
}
void InterfaceHandler::parseDocString(std::string const& _string, size_t _startPos)
{
size_t pos2;
size_t newPos = _startPos;
- size_t pos1 = _string.find("@", _startPos);
+ size_t tagPos = _string.find("@", _startPos);
+ size_t nlPos = _string.find("\n", _startPos);
- if (pos1 != std::string::npos)
+ if (tagPos != std::string::npos && tagPos < nlPos)
{
// we found a tag
- pos2 = _string.find(" ", pos1);
+ pos2 = _string.find(" ", tagPos);
if (pos2 == std::string::npos)
{
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("End of tag not found"));
return; //no end of tag found
}
- newPos = parseDocTag(_string, _string.substr(pos1 + 1, pos2 - pos1 - 1), pos2 + 1);
+ newPos = parseDocTag(_string, _string.substr(tagPos + 1, pos2 - tagPos - 1), pos2 + 1);
}
- else
+ else if (m_lastTag != DOCTAG_NONE) // continuation of the previous tag
+ newPos = appendDocTag(_string, _startPos + 1);
+ else // skip the line if a newline was found
{
- newPos = parseDocTag(_string, "", _startPos + 1);
+ if (newPos != std::string::npos)
+ newPos = nlPos + 1;
}
-
- if (newPos == std::string::npos)
+ if (newPos == std::string::npos || newPos == _string.length())
return; // EOS
parseDocString(_string, newPos);
}