Browse Source

Using iterators in Natspec comment parsing

- Used iterators in the entirety of the InterfaceHandler natspec comment
  parsing pipeline

- Fixed issue where @param continuing in new line would not get a space
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
4bbb9eb264
  1. 138
      libsolidity/InterfaceHandler.cpp
  2. 20
      libsolidity/InterfaceHandler.h
  3. 6
      test/solidityNatspecJSON.cpp

138
libsolidity/InterfaceHandler.cpp

@ -137,143 +137,135 @@ void InterfaceHandler::resetDev()
m_params.clear();
}
size_t skipLineOrEOS(std::string const& _string, size_t _nlPos)
std::string::const_iterator skipLineOrEOS(std::string::const_iterator _nlPos,
std::string::const_iterator _end)
{
return (_nlPos == std::string::npos) ? _string.length() : _nlPos + 1;
return (_nlPos == _end) ? _end : ++_nlPos;
}
size_t InterfaceHandler::parseDocTagLine(std::string const& _string,
std::string& _tagString,
size_t _pos,
enum DocTagType _tagType)
std::string::const_iterator InterfaceHandler::parseDocTagLine(std::string::const_iterator _pos,
std::string::const_iterator _end,
std::string& _tagString,
enum DocTagType _tagType)
{
size_t nlPos = _string.find('\n', _pos);
_tagString += _string.substr(_pos,
nlPos == std::string::npos ?
_string.length() - _pos:
nlPos - _pos);
auto nlPos = std::find(_pos, _end, '\n');
std::copy(_pos, nlPos, back_inserter(_tagString));
m_lastTag = _tagType;
return skipLineOrEOS(_string, nlPos);
return skipLineOrEOS(nlPos, _end);
}
size_t InterfaceHandler::parseDocTagParam(std::string const& _string, size_t _startPos)
std::string::const_iterator InterfaceHandler::parseDocTagParam(std::string::const_iterator _pos,
std::string::const_iterator _end)
{
// find param name
size_t currPos = _string.find(' ', _startPos);
if (currPos == std::string::npos)
auto currPos = std::find(_pos, _end, ' ');
if (currPos == _end)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("End of param name not found"));
auto paramName = _string.substr(_startPos, currPos - _startPos);
auto paramName = std::string(_pos, currPos);
currPos += 1;
size_t nlPos = _string.find('\n', currPos);
auto paramDesc = _string.substr(currPos,
nlPos == std::string::npos ?
_string.length() - currPos :
nlPos - currPos);
auto nlPos = std::find(currPos, _end, '\n');
auto paramDesc = std::string(currPos, nlPos);
m_params.push_back(std::make_pair(paramName, paramDesc));
m_lastTag = DOCTAG_PARAM;
return skipLineOrEOS(_string, nlPos);
return skipLineOrEOS(nlPos, _end);
}
size_t InterfaceHandler::appendDocTagParam(std::string const& _string, size_t _startPos)
std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::const_iterator _pos,
std::string::const_iterator _end)
{
// Should never be called with an empty vector
if (asserts(!m_params.empty()))
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Internal: Tried to append to empty parameter"));
auto pair = m_params.back();
size_t nlPos = _string.find('\n', _startPos);
pair.second += _string.substr(_startPos,
nlPos == std::string::npos ?
_string.length() - _startPos :
nlPos - _startPos);
pair.second += " ";
auto nlPos = std::find(_pos, _end, '\n');
std::copy(_pos, nlPos, back_inserter(pair.second));
m_params.at(m_params.size() - 1) = pair;
return skipLineOrEOS(_string, nlPos);
return skipLineOrEOS(nlPos, _end);
}
size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos)
std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_iterator _pos,
std::string::const_iterator _end,
std::string const& _tag)
{
// LTODO: 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 = parseDocTagLine(_string, m_dev, _pos, DOCTAG_DEV);
return parseDocTagLine(_pos, _end, m_dev, DOCTAG_DEV);
else if (_tag == "notice")
nlPos = parseDocTagLine(_string, m_notice, _pos, DOCTAG_NOTICE);
return parseDocTagLine(_pos, _end, m_notice, DOCTAG_NOTICE);
else if (_tag == "return")
nlPos = parseDocTagLine(_string, m_return, _pos, DOCTAG_RETURN);
return parseDocTagLine(_pos, _end, m_return, DOCTAG_RETURN);
else if (_tag == "param")
nlPos = parseDocTagParam(_string, _pos);
return parseDocTagParam(_pos, _end);
else
{
// LTODO: Unknown tas, throw some form of warning
// LTODO: Unknown tag, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Unknown tag encountered"));
}
}
else
appendDocTag(_string, _pos);
return nlPos;
return appendDocTag(_pos, _end);
}
size_t InterfaceHandler::appendDocTag(std::string const& _string, size_t _startPos)
std::string::const_iterator InterfaceHandler::appendDocTag(std::string::const_iterator _pos,
std::string::const_iterator _end)
{
size_t newPos = _startPos;
switch (m_lastTag)
{
case DOCTAG_DEV:
m_dev += " ";
newPos = parseDocTagLine(_string, m_dev, _startPos, DOCTAG_DEV);
break;
return parseDocTagLine(_pos, _end, m_dev, DOCTAG_DEV);
case DOCTAG_NOTICE:
m_notice += " ";
newPos = parseDocTagLine(_string, m_notice, _startPos, DOCTAG_NOTICE);
break;
return parseDocTagLine(_pos, _end, m_notice, DOCTAG_NOTICE);
case DOCTAG_RETURN:
m_return += " ";
newPos = parseDocTagLine(_string, m_return, _startPos, DOCTAG_RETURN);
break;
return parseDocTagLine(_pos, _end, m_return, DOCTAG_RETURN);
case DOCTAG_PARAM:
newPos = appendDocTagParam(_string, _startPos);
break;
return appendDocTagParam(_pos, _end);
default:
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Internal: Illegal documentation tag"));
break;
}
return newPos;
}
}
void InterfaceHandler::parseDocString(std::string const& _string, size_t _startPos)
void InterfaceHandler::parseDocString(std::string const& _string)
{
size_t pos2;
size_t newPos = _startPos;
size_t tagPos = _string.find('@', _startPos);
size_t nlPos = _string.find('\n', _startPos);
auto currPos = _string.begin();
auto end = _string.end();
if (tagPos != std::string::npos && tagPos < nlPos)
while (currPos != end)
{
// we found a tag
pos2 = _string.find(' ', tagPos);
if (pos2 == std::string::npos)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("End of tag not found"));
auto tagPos = std::find(currPos, end, '@');
auto nlPos = std::find(currPos, end, '\n');
newPos = parseDocTag(_string, _string.substr(tagPos + 1, pos2 - tagPos - 1), pos2 + 1);
}
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
{
if (newPos != std::string::npos)
newPos = nlPos + 1;
if (tagPos != end && tagPos < nlPos)
{
// we found a tag
auto tagNameEndPos = std::find(tagPos, end, ' ');
if (tagNameEndPos == end)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("End of tag not found"));
currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos +1, tagNameEndPos));
}
else if (m_lastTag != DOCTAG_NONE) // continuation of the previous tag
currPos = appendDocTag(currPos + 1, end);
else // skip the line if a newline was found
{
if (currPos != end)
currPos = nlPos + 1;
}
}
if (newPos == std::string::npos || newPos == _string.length())
return; // EOS
parseDocString(_string, newPos);
}
} //solidity NS

20
libsolidity/InterfaceHandler.h

@ -81,12 +81,20 @@ 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);
std::string::const_iterator parseDocTagLine(std::string::const_iterator _pos,
std::string::const_iterator _end,
std::string& _tagString,
enum DocTagType _tagType);
std::string::const_iterator parseDocTagParam(std::string::const_iterator _pos,
std::string::const_iterator _end);
std::string::const_iterator appendDocTagParam(std::string::const_iterator _pos,
std::string::const_iterator _end);
void parseDocString(std::string const& _string);
std::string::const_iterator appendDocTag(std::string::const_iterator _pos,
std::string::const_iterator _end);
std::string::const_iterator parseDocTag(std::string::const_iterator _pos,
std::string::const_iterator _end,
std::string const& _tag);
Json::StyledWriter m_writer;

6
test/solidityNatspecJSON.cpp

@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(dev_mutiline_param_description)
" \"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"
" \"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"
" }\n"
@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE(dev_return)
" \"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"
" \"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"
@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return)
" \"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"
" \"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"

Loading…
Cancel
Save