Merge pull request #14474 from ethereum/refactor-analysis-framework-error-filtering

Sane error filtering in `AnalysisFramework`
This commit is contained in:
Kamil Śliwak 2023-08-07 20:02:45 +02:00 committed by GitHub
commit e357b8bc42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 18 deletions

View File

@ -63,14 +63,14 @@ AnalysisFramework::parseAnalyseAndReturnError(
_allowMultipleErrors = _allowMultipleErrors || _allowRecoveryErrors;
if (!compiler().parse())
{
BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors());
BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors(compiler().errors()));
}
compiler().analyze();
ErrorList errors = filterErrors(compiler().errors(), _reportWarnings);
ErrorList errors = filteredErrors(_reportWarnings);
if (errors.size() > 1 && !_allowMultipleErrors)
BOOST_FAIL("Multiple errors found: " + formatErrors());
BOOST_FAIL("Multiple errors found: " + formatErrors(errors));
return make_pair(&compiler().ast(""), std::move(errors));
}
@ -128,7 +128,7 @@ SourceUnit const* AnalysisFramework::parseAndAnalyse(string const& _source)
BOOST_REQUIRE(!!sourceAndError.first);
string message;
if (!sourceAndError.second.empty())
message = "Unexpected error: " + formatErrors();
message = "Unexpected error: " + formatErrors(compiler().errors());
BOOST_REQUIRE_MESSAGE(sourceAndError.second.empty(), message);
return sourceAndError.first;
}
@ -146,17 +146,31 @@ ErrorList AnalysisFramework::expectError(std::string const& _source, bool _warni
return sourceAndErrors.second;
}
string AnalysisFramework::formatErrors() const
string AnalysisFramework::formatErrors(
langutil::ErrorList _errors,
bool _colored,
bool _withErrorIds
) const
{
string message;
for (auto const& error: compiler().errors())
message += formatError(*error);
for (auto const& error: _errors)
message += formatError(*error, _colored, _withErrorIds);
return message;
}
string AnalysisFramework::formatError(Error const& _error) const
string AnalysisFramework::formatError(
Error const& _error,
bool _colored,
bool _withErrorIds
) const
{
return SourceReferenceFormatter::formatErrorInformation(_error, *m_compiler);
return SourceReferenceFormatter::formatExceptionInformation(
_error,
_error.type(),
*m_compiler,
_colored,
_withErrorIds
);
}
ContractDefinition const* AnalysisFramework::retrieveContractByName(SourceUnit const& _source, string const& _name)

View File

@ -57,8 +57,16 @@ protected:
bool success(std::string const& _source);
langutil::ErrorList expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
std::string formatErrors() const;
std::string formatError(langutil::Error const& _error) const;
std::string formatErrors(
langutil::ErrorList _errors,
bool _colored = false,
bool _withErrorIds = false
) const;
std::string formatError(
langutil::Error const& _error,
bool _colored = false,
bool _withErrorIds = false
) const;
static ContractDefinition const* retrieveContractByName(SourceUnit const& _source, std::string const& _name);
static FunctionTypePointer retrieveFunctionBySignature(
@ -66,8 +74,12 @@ protected:
std::string const& _signature
);
// filter out the warnings in m_warningsToFilter or all warnings and infos if _includeWarningsAndInfos is false
langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarningsAndInfos) const;
/// filter out the warnings in m_warningsToFilter or all warnings and infos if _includeWarningsAndInfos is false
langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarningsAndInfos = true) const;
langutil::ErrorList filteredErrors(bool _includeWarningsAndInfos = true) const
{
return filterErrors(compiler().errors(), _includeWarningsAndInfos);
}
std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
std::vector<std::string> m_messagesToCut = {"Source file requires different compiler version (current compiler is"};
@ -151,7 +163,7 @@ do \
auto sourceAndError = parseAnalyseAndReturnError((text), true); \
std::string message; \
if (!sourceAndError.second.empty()) \
message = formatErrors();\
message = formatErrors(compiler().errors());\
BOOST_CHECK_MESSAGE(sourceAndError.second.empty(), message); \
} \
while(0)

View File

@ -118,8 +118,7 @@ TestCase::TestResult GasTest::run(ostream& _stream, string const& _linePrefix, b
if (!compiler().parseAndAnalyze() || !compiler().compile())
{
SourceReferenceFormatter{_stream, compiler(), _formatted, false}
.printErrorInformation(compiler().errors());
_stream << formatErrors(filteredErrors(), _formatted);
return TestResult::FatalError;
}

View File

@ -44,7 +44,10 @@ TestCase::TestResult MemoryGuardTest::run(ostream& _stream, string const& _lineP
compiler().setViaIR(true);
compiler().setOptimiserSettings(OptimiserSettings::none());
if (!compiler().compile())
{
_stream << formatErrors(filteredErrors(), _formatted);
return TestResult::FatalError;
}
m_obtainedResult.clear();
for (string contractName: compiler().contractNames())

View File

@ -42,7 +42,10 @@ BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions)
)";
compiler().setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
BOOST_REQUIRE(success(sourceCode));
BOOST_REQUIRE_MESSAGE(compiler().compile(), "Compiling contract failed");
BOOST_REQUIRE_MESSAGE(
compiler().compile(),
"Contract compilation failed:\n" + formatErrors(filteredErrors(), true /* _colored */)
);
bytes const& creationBytecode = solidity::test::bytecodeSansMetadata(compiler().object("C").bytecode);
bytes const& runtimeBytecode = solidity::test::bytecodeSansMetadata(compiler().runtimeObject("C").bytecode);
BOOST_CHECK(creationBytecode.size() >= 90);

View File

@ -111,7 +111,7 @@ void SyntaxTest::parseAndAnalyze()
void SyntaxTest::filterObtainedErrors()
{
for (auto const& currentError: filterErrors(compiler().errors(), true))
for (auto const& currentError: filteredErrors())
{
int locationStart = -1;
int locationEnd = -1;