Simplifying scanning for natspec documentation

- Scanner no longer remembers the last natspect comment until
  a new one is encountered. It remembers it only until the next
  scan()
This commit is contained in:
Lefteris Karapetsas 2014-11-30 22:43:40 +01:00
parent db7b118ece
commit a595464739
3 changed files with 19 additions and 37 deletions

View File

@ -119,10 +119,8 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
ASTPointer<ASTString> docstring; ASTPointer<ASTString> docstring;
if (m_scanner->getCurrentCommentLiteral() != "") if (m_scanner->getCurrentCommentLiteral() != "")
{
docstring = std::make_shared<ASTString>(m_scanner->getCurrentCommentLiteral()); docstring = std::make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
m_scanner->clearCurrentCommentLiteral();
}
expectToken(Token::FUNCTION); expectToken(Token::FUNCTION);
ASTPointer<ASTString> name(expectIdentifierToken()); ASTPointer<ASTString> name(expectIdentifierToken());
ASTPointer<ParameterList> parameters(parseParameterList()); ASTPointer<ParameterList> parameters(parseParameterList());

View File

@ -104,16 +104,14 @@ int hexValue(char c)
void Scanner::reset(CharStream const& _source) void Scanner::reset(CharStream const& _source)
{ {
bool foundDocComment;
m_source = _source; m_source = _source;
m_char = m_source.get(); m_char = m_source.get();
skipWhitespace(); skipWhitespace();
foundDocComment = scanToken(); scanToken();
// special version of Scanner:next() taking the previous scanToken() result into account
m_currentToken = m_nextToken; m_currentToken = m_nextToken;
if (scanToken() || foundDocComment) m_skippedComment = m_nextSkippedComment;
m_skippedComment = m_nextSkippedComment; scanToken();
} }
@ -142,8 +140,9 @@ BOOST_STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
Token::Value Scanner::next() Token::Value Scanner::next()
{ {
m_currentToken = m_nextToken; m_currentToken = m_nextToken;
if (scanToken()) m_skippedComment = m_nextSkippedComment;
m_skippedComment = m_nextSkippedComment; scanToken();
return m_currentToken.token; return m_currentToken.token;
} }
@ -188,13 +187,13 @@ Token::Value Scanner::scanDocumentationComment()
{ {
// check if next line is also a documentation comment // check if next line is also a documentation comment
skipWhitespace(); skipWhitespace();
if (m_source.get(0) == '/' && if (!m_source.isPastEndOfInput(3) &&
m_source.get(0) == '/' &&
m_source.get(1) == '/' && m_source.get(1) == '/' &&
m_source.get(2) == '/' && m_source.get(2) == '/')
!m_source.isPastEndOfInput(3))
{ {
addCommentLiteralChar('\n'); addCommentLiteralChar('\n');
m_char = m_source.advanceBy(3); m_char = m_source.advanceAndGet(3);
} }
else else
break; // next line is not a documentation comment, we are done break; // next line is not a documentation comment, we are done
@ -230,10 +229,10 @@ Token::Value Scanner::skipMultiLineComment()
return Token::ILLEGAL; return Token::ILLEGAL;
} }
bool Scanner::scanToken() void Scanner::scanToken()
{ {
bool foundDocComment = false;
m_nextToken.literal.clear(); m_nextToken.literal.clear();
m_nextSkippedComment.literal.clear();
Token::Value token; Token::Value token;
do do
{ {
@ -345,7 +344,6 @@ bool Scanner::scanToken()
m_nextSkippedComment.location.end = getSourcePos(); m_nextSkippedComment.location.end = getSourcePos();
m_nextSkippedComment.token = comment; m_nextSkippedComment.token = comment;
token = Token::WHITESPACE; token = Token::WHITESPACE;
foundDocComment = true;
} }
else else
token = skipSingleLineComment(); token = skipSingleLineComment();
@ -441,8 +439,6 @@ bool Scanner::scanToken()
while (token == Token::WHITESPACE); while (token == Token::WHITESPACE);
m_nextToken.location.end = getSourcePos(); m_nextToken.location.end = getSourcePos();
m_nextToken.token = token; m_nextToken.token = token;
return foundDocComment;
} }
bool Scanner::scanEscape() bool Scanner::scanEscape()
@ -783,23 +779,13 @@ Token::Value Scanner::scanIdentifierOrKeyword()
return KeywordOrIdentifierToken(m_nextToken.literal); return KeywordOrIdentifierToken(m_nextToken.literal);
} }
char CharStream::advanceAndGet() char CharStream::advanceAndGet(size_t _chars)
{ {
if (isPastEndOfInput()) if (isPastEndOfInput())
return 0; return 0;
++m_pos;
if (isPastEndOfInput())
return 0;
return get();
}
char CharStream::advanceBy(size_t _chars)
{
if (asserts(!isPastEndOfInput(_chars)))
BOOST_THROW_EXCEPTION(InternalCompilerError());
m_pos += _chars; m_pos += _chars;
if (isPastEndOfInput())
return 0;
return m_source[m_pos]; return m_source[m_pos];
} }

View File

@ -76,8 +76,7 @@ public:
int getPos() const { return m_pos; } int getPos() const { return m_pos; }
bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_pos + _charsForward) >= m_source.size(); } bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_pos + _charsForward) >= m_source.size(); }
char get(size_t _charsForward = 0) const { return m_source[m_pos + _charsForward]; } char get(size_t _charsForward = 0) const { return m_source[m_pos + _charsForward]; }
char advanceAndGet(); char advanceAndGet(size_t _chars=1);
char advanceBy(size_t _chars);
char rollback(size_t _amount); char rollback(size_t _amount);
///@{ ///@{
@ -213,9 +212,8 @@ private:
bool scanHexByte(char& o_scannedByte); bool scanHexByte(char& o_scannedByte);
/// Scans a single Solidity token. Returns true if the scanned token was /// Scans a single Solidity token.
/// a skipped documentation comment. False in all other cases. void scanToken();
bool scanToken();
/// Skips all whitespace and @returns true if something was skipped. /// Skips all whitespace and @returns true if something was skipped.
bool skipWhitespace(); bool skipWhitespace();