mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Natspec parsing @param doctags
- Plus additional work on generally parsing doctags. One important missing feature is to parse a tag midline - Adding more tests
This commit is contained in:
parent
3e803b40e1
commit
05964375f8
@ -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);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ enum docTagType
|
||||
DOCTAG_NONE = 0,
|
||||
DOCTAG_DEV,
|
||||
DOCTAG_NOTICE,
|
||||
DOCTAG_PARAM
|
||||
};
|
||||
|
||||
class InterfaceHandler
|
||||
@ -74,7 +75,14 @@ public:
|
||||
std::unique_ptr<std::string> getDevDocumentation(std::shared_ptr<ContractDefinition> _contractDef);
|
||||
|
||||
private:
|
||||
void resetUser();
|
||||
void resetDev();
|
||||
|
||||
size_t parseDocTagLine(std::string const& _string, std::string& _tagString, size_t _pos, enum docTagType _tagType);
|
||||
size_t parseDocTagParam(std::string const& _string, size_t _startPos);
|
||||
size_t appendDocTagParam(std::string const& _string, size_t _startPos);
|
||||
void parseDocString(std::string const& _string, size_t _startPos = 0);
|
||||
size_t appendDocTag(std::string const& _string, size_t _startPos);
|
||||
size_t parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos);
|
||||
|
||||
Json::StyledWriter m_writer;
|
||||
@ -83,6 +91,7 @@ private:
|
||||
enum docTagType m_lastTag;
|
||||
std::string m_notice;
|
||||
std::string m_dev;
|
||||
std::vector<std::pair<std::string, std::string>> m_params;
|
||||
};
|
||||
|
||||
} //solidity NS
|
||||
|
Loading…
Reference in New Issue
Block a user