mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10212 from ethereum/testfileparser
Refactor and simplify TestFileParser
This commit is contained in:
commit
3db94fbc48
@ -36,11 +36,9 @@
|
|||||||
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::langutil;
|
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::frontend::test;
|
using namespace solidity::frontend::test;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace soltest;
|
|
||||||
|
|
||||||
bytes BytesUtils::alignLeft(bytes _bytes)
|
bytes BytesUtils::alignLeft(bytes _bytes)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,6 @@ using namespace solidity::util;
|
|||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
using namespace solidity::frontend::test;
|
using namespace solidity::frontend::test;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace soltest;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include <libsolutil/AnsiColorized.h>
|
#include <libsolutil/AnsiColorized.h>
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
#include <libsolidity/ast/Types.h>
|
|
||||||
|
|
||||||
namespace solidity::frontend::test
|
namespace solidity::frontend::test
|
||||||
{
|
{
|
||||||
|
@ -34,11 +34,11 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::langutil;
|
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::frontend::test;
|
using namespace solidity::frontend::test;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace soltest;
|
|
||||||
|
using Token = soltest::Token;
|
||||||
|
|
||||||
char TestFileParser::Scanner::peek() const noexcept
|
char TestFileParser::Scanner::peek() const noexcept
|
||||||
{
|
{
|
||||||
@ -158,7 +158,7 @@ vector<solidity::frontend::test::FunctionCall> TestFileParser::parseFunctionCall
|
|||||||
return calls;
|
return calls;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestFileParser::accept(soltest::Token _token, bool const _expect)
|
bool TestFileParser::accept(Token _token, bool const _expect)
|
||||||
{
|
{
|
||||||
if (m_scanner.currentToken() != _token)
|
if (m_scanner.currentToken() != _token)
|
||||||
return false;
|
return false;
|
||||||
@ -167,7 +167,7 @@ bool TestFileParser::accept(soltest::Token _token, bool const _expect)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestFileParser::expect(soltest::Token _token, bool const _advance)
|
bool TestFileParser::expect(Token _token, bool const _advance)
|
||||||
{
|
{
|
||||||
if (m_scanner.currentToken() != _token || m_scanner.currentToken() == Token::Invalid)
|
if (m_scanner.currentToken() != _token || m_scanner.currentToken() == Token::Invalid)
|
||||||
throw TestParserError(
|
throw TestParserError(
|
||||||
@ -484,31 +484,31 @@ void TestFileParser::Scanner::readStream(istream& _stream)
|
|||||||
|
|
||||||
void TestFileParser::Scanner::scanNextToken()
|
void TestFileParser::Scanner::scanNextToken()
|
||||||
{
|
{
|
||||||
using namespace langutil;
|
|
||||||
|
|
||||||
// Make code coverage happy.
|
// Make code coverage happy.
|
||||||
assert(formatToken(Token::NUM_TOKENS) == "");
|
assert(formatToken(Token::NUM_TOKENS) == "");
|
||||||
|
|
||||||
auto detectKeyword = [](std::string const& _literal = "") -> TokenDesc {
|
auto detectKeyword = [](std::string const& _literal = "") -> std::pair<Token, std::string> {
|
||||||
if (_literal == "true") return TokenDesc{Token::Boolean, _literal};
|
if (_literal == "true") return {Token::Boolean, "true"};
|
||||||
if (_literal == "false") return TokenDesc{Token::Boolean, _literal};
|
if (_literal == "false") return {Token::Boolean, "false"};
|
||||||
if (_literal == "ether") return TokenDesc{Token::Ether, _literal};
|
if (_literal == "ether") return {Token::Ether, ""};
|
||||||
if (_literal == "wei") return TokenDesc{Token::Wei, _literal};
|
if (_literal == "wei") return {Token::Wei, ""};
|
||||||
if (_literal == "left") return TokenDesc{Token::Left, _literal};
|
if (_literal == "left") return {Token::Left, ""};
|
||||||
if (_literal == "library") return TokenDesc{Token::Library, _literal};
|
if (_literal == "library") return {Token::Library, ""};
|
||||||
if (_literal == "right") return TokenDesc{Token::Right, _literal};
|
if (_literal == "right") return {Token::Right, ""};
|
||||||
if (_literal == "hex") return TokenDesc{Token::Hex, _literal};
|
if (_literal == "hex") return {Token::Hex, ""};
|
||||||
if (_literal == "FAILURE") return TokenDesc{Token::Failure, _literal};
|
if (_literal == "FAILURE") return {Token::Failure, ""};
|
||||||
if (_literal == "storage") return TokenDesc{Token::Storage, _literal};
|
if (_literal == "storage") return {Token::Storage, ""};
|
||||||
return TokenDesc{Token::Identifier, _literal};
|
return {Token::Identifier, _literal};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto selectToken = [this](Token _token, std::optional<std::string> _literal = std::nullopt) -> TokenDesc {
|
auto selectToken = [this](Token _token, std::string const& _literal = "") {
|
||||||
advance();
|
advance();
|
||||||
return make_pair(_token, _literal.has_value() ? *_literal : formatToken(_token));
|
m_currentToken = _token;
|
||||||
|
m_currentLiteral = _literal;
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenDesc token = make_pair(Token::Unknown, "");
|
m_currentToken = Token::Unknown;
|
||||||
|
m_currentLiteral = "";
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
switch(current())
|
switch(current())
|
||||||
@ -516,71 +516,73 @@ void TestFileParser::Scanner::scanNextToken()
|
|||||||
case '/':
|
case '/':
|
||||||
advance();
|
advance();
|
||||||
if (current() == '/')
|
if (current() == '/')
|
||||||
token = selectToken(Token::Newline);
|
selectToken(Token::Newline);
|
||||||
else
|
else
|
||||||
token = selectToken(Token::Invalid);
|
selectToken(Token::Invalid);
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (peek() == '>')
|
if (peek() == '>')
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
token = selectToken(Token::Arrow);
|
selectToken(Token::Arrow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
token = selectToken(Token::Sub);
|
selectToken(Token::Sub);
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
token = selectToken(Token::Colon);
|
selectToken(Token::Colon);
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
token = selectToken(Token::Comment, scanComment());
|
selectToken(Token::Comment, scanComment());
|
||||||
break;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
token = selectToken(Token::Comma);
|
selectToken(Token::Comma);
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
token = selectToken(Token::LParen);
|
selectToken(Token::LParen);
|
||||||
break;
|
break;
|
||||||
case ')':
|
case ')':
|
||||||
token = selectToken(Token::RParen);
|
selectToken(Token::RParen);
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
token = selectToken(Token::LBrack);
|
selectToken(Token::LBrack);
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
token = selectToken(Token::RBrack);
|
selectToken(Token::RBrack);
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"':
|
||||||
token = selectToken(Token::String, scanString());
|
selectToken(Token::String, scanString());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (isIdentifierStart(current()))
|
if (langutil::isIdentifierStart(current()))
|
||||||
{
|
{
|
||||||
TokenDesc detectedToken = detectKeyword(scanIdentifierOrKeyword());
|
std::tie(m_currentToken, m_currentLiteral) = detectKeyword(scanIdentifierOrKeyword());
|
||||||
token = selectToken(detectedToken.first, detectedToken.second);
|
advance();
|
||||||
}
|
}
|
||||||
else if (isDecimalDigit(current()))
|
else if (langutil::isDecimalDigit(current()))
|
||||||
{
|
{
|
||||||
if (current() == '0' && peek() == 'x')
|
if (current() == '0' && peek() == 'x')
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
advance();
|
advance();
|
||||||
token = selectToken(Token::HexNumber, "0x" + scanHexNumber());
|
selectToken(Token::HexNumber, "0x" + scanHexNumber());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
token = selectToken(Token::Number, scanDecimalNumber());
|
selectToken(Token::Number, scanDecimalNumber());
|
||||||
}
|
}
|
||||||
else if (isWhiteSpace(current()))
|
else if (langutil::isWhiteSpace(current()))
|
||||||
token = selectToken(Token::Whitespace);
|
selectToken(Token::Whitespace);
|
||||||
else if (isEndOfLine())
|
else if (isEndOfLine())
|
||||||
token = make_pair(Token::EOS, "EOS");
|
{
|
||||||
|
m_currentToken = Token::EOS;
|
||||||
|
m_currentLiteral = "";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw TestParserError("Unexpected character: '" + string{current()} + "'");
|
throw TestParserError("Unexpected character: '" + string{current()} + "'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (token.first == Token::Whitespace);
|
while (m_currentToken == Token::Whitespace);
|
||||||
m_currentToken = token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string TestFileParser::Scanner::scanComment()
|
string TestFileParser::Scanner::scanComment()
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
#include <libsolidity/ast/Types.h>
|
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
#include <test/libsolidity/util/SoltestTypes.h>
|
#include <test/libsolidity/util/SoltestTypes.h>
|
||||||
|
|
||||||
@ -64,7 +63,6 @@ public:
|
|||||||
std::vector<FunctionCall> parseFunctionCalls(std::size_t _lineOffset);
|
std::vector<FunctionCall> parseFunctionCalls(std::size_t _lineOffset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Token = soltest::Token;
|
|
||||||
/**
|
/**
|
||||||
* Token scanner that is used internally to abstract away character traversal.
|
* Token scanner that is used internally to abstract away character traversal.
|
||||||
*/
|
*/
|
||||||
@ -81,8 +79,8 @@ private:
|
|||||||
/// Reads character stream and creates token.
|
/// Reads character stream and creates token.
|
||||||
void scanNextToken();
|
void scanNextToken();
|
||||||
|
|
||||||
soltest::Token currentToken() { return m_currentToken.first; }
|
soltest::Token currentToken() { return m_currentToken; }
|
||||||
std::string currentLiteral() { return m_currentToken.second; }
|
std::string currentLiteral() { return m_currentLiteral; }
|
||||||
|
|
||||||
std::string scanComment();
|
std::string scanComment();
|
||||||
std::string scanIdentifierOrKeyword();
|
std::string scanIdentifierOrKeyword();
|
||||||
@ -92,8 +90,6 @@ private:
|
|||||||
char scanHexPart();
|
char scanHexPart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using TokenDesc = std::pair<Token, std::string>;
|
|
||||||
|
|
||||||
/// Advances current position in the input stream.
|
/// Advances current position in the input stream.
|
||||||
void advance(unsigned n = 1)
|
void advance(unsigned n = 1)
|
||||||
{
|
{
|
||||||
@ -120,7 +116,8 @@ private:
|
|||||||
std::string m_line;
|
std::string m_line;
|
||||||
std::string::const_iterator m_char;
|
std::string::const_iterator m_char;
|
||||||
|
|
||||||
TokenDesc m_currentToken;
|
std::string m_currentLiteral;
|
||||||
|
soltest::Token m_currentToken = soltest::Token::Unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool accept(soltest::Token _token, bool const _expect = false);
|
bool accept(soltest::Token _token, bool const _expect = false);
|
||||||
|
@ -30,6 +30,8 @@ using namespace solidity::util;
|
|||||||
using namespace solidity::frontend::test;
|
using namespace solidity::frontend::test;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
using Token = soltest::Token;
|
||||||
|
|
||||||
string TestFunctionCall::format(
|
string TestFunctionCall::format(
|
||||||
ErrorReporter& _errorReporter,
|
ErrorReporter& _errorReporter,
|
||||||
string const& _linePrefix,
|
string const& _linePrefix,
|
||||||
@ -37,9 +39,6 @@ string TestFunctionCall::format(
|
|||||||
bool const _highlight
|
bool const _highlight
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
using namespace soltest;
|
|
||||||
using Token = soltest::Token;
|
|
||||||
|
|
||||||
stringstream stream;
|
stringstream stream;
|
||||||
|
|
||||||
bool highlight = !matchesExpectation() && _highlight;
|
bool highlight = !matchesExpectation() && _highlight;
|
||||||
@ -279,8 +278,6 @@ string TestFunctionCall::formatFailure(
|
|||||||
bool _highlight
|
bool _highlight
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
using Token = soltest::Token;
|
|
||||||
|
|
||||||
stringstream os;
|
stringstream os;
|
||||||
|
|
||||||
os << formatToken(Token::Failure);
|
os << formatToken(Token::Failure);
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include <test/libsolidity/util/TestFileParser.h>
|
#include <test/libsolidity/util/TestFileParser.h>
|
||||||
#include <test/libsolidity/util/SoltestErrors.h>
|
#include <test/libsolidity/util/SoltestErrors.h>
|
||||||
|
|
||||||
#include <libsolidity/ast/Types.h>
|
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
#include <libsolutil/AnsiColorized.h>
|
#include <libsolutil/AnsiColorized.h>
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user