mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Adds line numbers to parser errors in isoltest.
This commit is contained in:
parent
579bdaddb9
commit
2a1473fd30
@ -62,16 +62,19 @@ bool TestCase::validateSettings(langutil::EVMVersion)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string TestCase::parseSourceAndSettings(istream& _stream)
|
pair<string, size_t> TestCase::parseSourceAndSettingsWithLineNumbers(istream& _stream)
|
||||||
{
|
{
|
||||||
string source;
|
string source;
|
||||||
string line;
|
string line;
|
||||||
|
size_t lineNumber = 1;
|
||||||
static string const comment("// ");
|
static string const comment("// ");
|
||||||
static string const settingsDelimiter("// ====");
|
static string const settingsDelimiter("// ====");
|
||||||
static string const delimiter("// ----");
|
static string const delimiter("// ----");
|
||||||
bool sourcePart = true;
|
bool sourcePart = true;
|
||||||
while (getline(_stream, line))
|
while (getline(_stream, line))
|
||||||
{
|
{
|
||||||
|
lineNumber++;
|
||||||
|
|
||||||
if (boost::algorithm::starts_with(line, delimiter))
|
if (boost::algorithm::starts_with(line, delimiter))
|
||||||
break;
|
break;
|
||||||
else if (boost::algorithm::starts_with(line, settingsDelimiter))
|
else if (boost::algorithm::starts_with(line, settingsDelimiter))
|
||||||
@ -92,7 +95,12 @@ string TestCase::parseSourceAndSettings(istream& _stream)
|
|||||||
else
|
else
|
||||||
throw runtime_error(string("Expected \"//\" or \"// ---\" to terminate settings and source."));
|
throw runtime_error(string("Expected \"//\" or \"// ---\" to terminate settings and source."));
|
||||||
}
|
}
|
||||||
return source;
|
return make_pair(source, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
string TestCase::parseSourceAndSettings(istream& _stream)
|
||||||
|
{
|
||||||
|
return get<0>(parseSourceAndSettingsWithLineNumbers(_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
string TestCase::parseSimpleExpectations(std::istream& _file)
|
string TestCase::parseSimpleExpectations(std::istream& _file)
|
||||||
|
@ -89,6 +89,7 @@ public:
|
|||||||
virtual bool validateSettings(langutil::EVMVersion /*_evmVersion*/);
|
virtual bool validateSettings(langutil::EVMVersion /*_evmVersion*/);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::pair<std::string, std::size_t> parseSourceAndSettingsWithLineNumbers(std::istream& _file);
|
||||||
std::string parseSourceAndSettings(std::istream& _file);
|
std::string parseSourceAndSettings(std::istream& _file);
|
||||||
static void expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c);
|
static void expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c);
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ SemanticTest::SemanticTest(string const& _filename, string const& _ipcPath, lang
|
|||||||
soltestAssert(file, "Cannot open test contract: \"" + _filename + "\".");
|
soltestAssert(file, "Cannot open test contract: \"" + _filename + "\".");
|
||||||
file.exceptions(ios::badbit);
|
file.exceptions(ios::badbit);
|
||||||
|
|
||||||
m_source = parseSourceAndSettings(file);
|
std::tie(m_source, m_lineOffset) = parseSourceAndSettingsWithLineNumbers(file);
|
||||||
|
|
||||||
if (m_settings.count("compileViaYul"))
|
if (m_settings.count("compileViaYul"))
|
||||||
{
|
{
|
||||||
if (m_settings["compileViaYul"] == "also")
|
if (m_settings["compileViaYul"] == "also")
|
||||||
@ -163,7 +164,7 @@ void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) con
|
|||||||
void SemanticTest::parseExpectations(istream& _stream)
|
void SemanticTest::parseExpectations(istream& _stream)
|
||||||
{
|
{
|
||||||
TestFileParser parser{_stream};
|
TestFileParser parser{_stream};
|
||||||
auto functionCalls = parser.parseFunctionCalls();
|
auto functionCalls = parser.parseFunctionCalls(m_lineOffset);
|
||||||
std::move(functionCalls.begin(), functionCalls.end(), back_inserter(m_tests));
|
std::move(functionCalls.begin(), functionCalls.end(), back_inserter(m_tests));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_source;
|
std::string m_source;
|
||||||
|
std::size_t m_lineOffset;
|
||||||
std::vector<TestFunctionCall> m_tests;
|
std::vector<TestFunctionCall> m_tests;
|
||||||
bool m_runWithYul = false;
|
bool m_runWithYul = false;
|
||||||
bool m_runWithoutYul = true;
|
bool m_runWithoutYul = true;
|
||||||
|
@ -48,7 +48,7 @@ char TestFileParser::Scanner::peek() const noexcept
|
|||||||
return *next;
|
return *next;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
|
vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls(size_t _lineOffset)
|
||||||
{
|
{
|
||||||
vector<FunctionCall> calls;
|
vector<FunctionCall> calls;
|
||||||
if (!accept(Token::EOS))
|
if (!accept(Token::EOS))
|
||||||
@ -70,8 +70,11 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
|
|||||||
if (calls.empty())
|
if (calls.empty())
|
||||||
expect(Token::Newline);
|
expect(Token::Newline);
|
||||||
else
|
else
|
||||||
accept(Token::Newline, true);
|
if (accept(Token::Newline, true))
|
||||||
|
m_lineNumber++;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
call.signature = parseFunctionSignature();
|
call.signature = parseFunctionSignature();
|
||||||
if (accept(Token::Comma, true))
|
if (accept(Token::Comma, true))
|
||||||
call.value = parseFunctionCallValue();
|
call.value = parseFunctionCallValue();
|
||||||
@ -79,17 +82,24 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
|
|||||||
call.arguments = parseFunctionCallArguments();
|
call.arguments = parseFunctionCallArguments();
|
||||||
|
|
||||||
if (accept(Token::Newline, true))
|
if (accept(Token::Newline, true))
|
||||||
|
{
|
||||||
call.displayMode = FunctionCall::DisplayMode::MultiLine;
|
call.displayMode = FunctionCall::DisplayMode::MultiLine;
|
||||||
|
m_lineNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
call.arguments.comment = parseComment();
|
call.arguments.comment = parseComment();
|
||||||
|
|
||||||
if (accept(Token::Newline, true))
|
if (accept(Token::Newline, true))
|
||||||
|
{
|
||||||
call.displayMode = FunctionCall::DisplayMode::MultiLine;
|
call.displayMode = FunctionCall::DisplayMode::MultiLine;
|
||||||
|
m_lineNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
expect(Token::Arrow);
|
expect(Token::Arrow);
|
||||||
call.expectations = parseFunctionCallExpectations();
|
call.expectations = parseFunctionCallExpectations();
|
||||||
|
|
||||||
accept(Token::Newline, true);
|
if (accept(Token::Newline, true))
|
||||||
|
m_lineNumber++;
|
||||||
call.expectations.comment = parseComment();
|
call.expectations.comment = parseComment();
|
||||||
|
|
||||||
if (call.signature == "constructor()")
|
if (call.signature == "constructor()")
|
||||||
@ -97,6 +107,11 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
|
|||||||
|
|
||||||
calls.emplace_back(std::move(call));
|
calls.emplace_back(std::move(call));
|
||||||
}
|
}
|
||||||
|
catch (Error const& _e)
|
||||||
|
{
|
||||||
|
throw Error{_e.type(), "Line " + to_string(_lineOffset + m_lineNumber) + ": " + _e.what()};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return calls;
|
return calls;
|
||||||
@ -207,7 +222,10 @@ Parameter TestFileParser::parseParameter()
|
|||||||
{
|
{
|
||||||
Parameter parameter;
|
Parameter parameter;
|
||||||
if (accept(Token::Newline, true))
|
if (accept(Token::Newline, true))
|
||||||
|
{
|
||||||
parameter.format.newline = true;
|
parameter.format.newline = true;
|
||||||
|
m_lineNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
bool isSigned = false;
|
bool isSigned = false;
|
||||||
|
|
||||||
|
@ -59,7 +59,9 @@ public:
|
|||||||
/// Throws an exception if a function call cannot be parsed because of its
|
/// Throws an exception if a function call cannot be parsed because of its
|
||||||
/// incorrect structure, an invalid or unsupported encoding
|
/// incorrect structure, an invalid or unsupported encoding
|
||||||
/// of its arguments or expected results.
|
/// of its arguments or expected results.
|
||||||
std::vector<FunctionCall> parseFunctionCalls();
|
/// Passes the source line offset, such that parsing errors can be enhanced
|
||||||
|
/// with a line number it occurred in.
|
||||||
|
std::vector<FunctionCall> parseFunctionCalls(std::size_t _lineOffset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Token = soltest::Token;
|
using Token = soltest::Token;
|
||||||
@ -179,6 +181,10 @@ private:
|
|||||||
|
|
||||||
/// A scanner instance
|
/// A scanner instance
|
||||||
Scanner m_scanner;
|
Scanner m_scanner;
|
||||||
|
|
||||||
|
/// The current line number. Incremented when Token::Newline (//) is found and
|
||||||
|
/// used to enhance parser error messages.
|
||||||
|
size_t m_lineNumber = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ vector<FunctionCall> parse(string const& _source)
|
|||||||
{
|
{
|
||||||
istringstream stream{_source, ios_base::out};
|
istringstream stream{_source, ios_base::out};
|
||||||
TestFileParser parser{stream};
|
TestFileParser parser{stream};
|
||||||
return parser.parseFunctionCalls();
|
return parser.parseFunctionCalls(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void testFunctionCall(
|
void testFunctionCall(
|
||||||
|
Loading…
Reference in New Issue
Block a user