mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
AnalysisFramework: Reimplement parseAnalyseAndReturnError() with runFramework()
This commit is contained in:
parent
b766268ff3
commit
d2bfb2f737
@ -42,26 +42,20 @@ using namespace solidity::langutil;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::test;
|
||||
|
||||
std::pair<SourceUnit const*, ErrorList>
|
||||
AnalysisFramework::parseAnalyseAndReturnError(
|
||||
std::pair<SourceUnit const*, ErrorList> AnalysisFramework::runAnalysisAndExpectNoParsingErrors(
|
||||
std::string const& _source,
|
||||
bool _reportWarnings,
|
||||
bool _insertLicenseAndVersionPragma,
|
||||
bool _allowMultipleErrors
|
||||
bool _includeWarningsAndInfos,
|
||||
bool _addPreamble,
|
||||
bool _allowMultiple
|
||||
)
|
||||
{
|
||||
compiler().reset();
|
||||
compiler().setSources({{"", _insertLicenseAndVersionPragma ? withPreamble(_source) : _source}});
|
||||
compiler().setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
if (!compiler().parse())
|
||||
{
|
||||
BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors(compiler().errors()));
|
||||
}
|
||||
runFramework(_addPreamble ? withPreamble(_source) : _source, PipelineStage::Analysis);
|
||||
|
||||
compiler().analyze();
|
||||
if (!stageSuccessful(PipelineStage::Parsing))
|
||||
BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors(m_compiler->errors()));
|
||||
|
||||
ErrorList errors = filteredErrors(_reportWarnings);
|
||||
if (errors.size() > 1 && !_allowMultipleErrors)
|
||||
ErrorList errors = filteredErrors(_includeWarningsAndInfos);
|
||||
if (errors.size() > 1 && !_allowMultiple)
|
||||
BOOST_FAIL("Multiple errors found: " + formatErrors(errors));
|
||||
|
||||
return make_pair(&compiler().ast(""), std::move(errors));
|
||||
@ -173,12 +167,16 @@ bool AnalysisFramework::stageSuccessful(PipelineStage _stage) const
|
||||
unreachable();
|
||||
}
|
||||
|
||||
ErrorList AnalysisFramework::expectError(std::string const& _source, bool _warning, bool _allowMultiple)
|
||||
ErrorList AnalysisFramework::runAnalysisAndExpectError(
|
||||
std::string const& _source,
|
||||
bool _includeWarningsAndInfos,
|
||||
bool _allowMultiple
|
||||
)
|
||||
{
|
||||
auto sourceAndErrors = parseAnalyseAndReturnError(_source, _warning, true, _allowMultiple);
|
||||
BOOST_REQUIRE(!sourceAndErrors.second.empty());
|
||||
BOOST_REQUIRE_MESSAGE(!!sourceAndErrors.first, "Expected error, but no error happened.");
|
||||
return sourceAndErrors.second;
|
||||
auto [ast, errors] = runAnalysisAndExpectNoParsingErrors(_source, _includeWarningsAndInfos, true, _allowMultiple);
|
||||
BOOST_REQUIRE(!errors.empty());
|
||||
BOOST_REQUIRE_MESSAGE(ast, "Expected error, but no error happened.");
|
||||
return errors;
|
||||
}
|
||||
|
||||
std::string AnalysisFramework::formatErrors(
|
||||
|
@ -49,16 +49,37 @@ class AnalysisFramework
|
||||
{
|
||||
|
||||
protected:
|
||||
virtual std::pair<SourceUnit const*, langutil::ErrorList>
|
||||
parseAnalyseAndReturnError(
|
||||
std::string const& _source,
|
||||
bool _reportWarnings = false,
|
||||
bool _insertLicenseAndVersionPragma = true,
|
||||
bool _allowMultipleErrors = false
|
||||
);
|
||||
virtual ~AnalysisFramework() = default;
|
||||
|
||||
langutil::ErrorList expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
|
||||
/// Runs analysis via runFramework() and returns either an AST or a filtered list of errors.
|
||||
/// Uses Boost test macros to fail if errors do not occur specifically at the analysis stage.
|
||||
///
|
||||
/// @deprecated This is a legacy helper. Use runFramework() directly in new tests.
|
||||
///
|
||||
/// @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.
|
||||
/// @param _addPreamble Apply withPreamble() to @p _source.
|
||||
/// @param _allowMultiple When false, use Boost test macros to fail when there's more
|
||||
/// than one item on the error list.
|
||||
std::pair<SourceUnit const*, langutil::ErrorList> runAnalysisAndExpectNoParsingErrors(
|
||||
std::string const& _source,
|
||||
bool _includeWarningsAndInfos = false,
|
||||
bool _addPreamble = true,
|
||||
bool _allowMultiple = false
|
||||
);
|
||||
|
||||
/// Runs analysis via runAnalysisAndExpectNoParsingErrors() and returns the list of errors.
|
||||
/// Uses Boost test macros to fail if there are no errors.
|
||||
///
|
||||
/// @deprecated This is a legacy helper. Use runFramework() directly in new tests.
|
||||
///
|
||||
/// @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.
|
||||
/// @param _allowMultiple When false, use Boost test macros to fail when there's more
|
||||
/// than one item on the error list.
|
||||
langutil::ErrorList runAnalysisAndExpectError(
|
||||
std::string const& _source,
|
||||
bool _includeWarningsAndInfos = false,
|
||||
bool _allowMultiple = false
|
||||
);
|
||||
|
||||
public:
|
||||
/// Runs the full compiler pipeline on specified sources. This is the main function of the
|
||||
@ -145,15 +166,15 @@ private:
|
||||
#define CHECK_ALLOW_MULTI(text, expectations) \
|
||||
do \
|
||||
{ \
|
||||
ErrorList errors = expectError((text), true, true); \
|
||||
ErrorList errors = runAnalysisAndExpectError((text), true, true); \
|
||||
auto message = searchErrors(errors, (expectations)); \
|
||||
BOOST_CHECK_MESSAGE(message.empty(), message); \
|
||||
} while(0)
|
||||
|
||||
#define CHECK_ERROR_OR_WARNING(text, typ, substrings, warning, allowMulti) \
|
||||
#define CHECK_ERROR_OR_WARNING(text, typ, substrings, includeWarningsAndInfos, allowMulti) \
|
||||
do \
|
||||
{ \
|
||||
ErrorList errors = expectError((text), (warning), (allowMulti)); \
|
||||
ErrorList errors = runAnalysisAndExpectError((text), (includeWarningsAndInfos), (allowMulti)); \
|
||||
std::vector<std::pair<Error::Type, std::string>> expectations; \
|
||||
for (auto const& str: substrings) \
|
||||
expectations.emplace_back((Error::Type::typ), str); \
|
||||
@ -188,14 +209,14 @@ CHECK_ERROR_OR_WARNING(text, Warning, substrings, true, true)
|
||||
|
||||
// [checkSuccess(text)] asserts that the compilation down to typechecking succeeds.
|
||||
#define CHECK_SUCCESS(text) do { \
|
||||
auto [ast, errors] = parseAnalyseAndReturnError((text)); \
|
||||
auto [ast, errors] = runAnalysisAndExpectNoParsingErrors((text)); \
|
||||
BOOST_CHECK(errors.empty()); \
|
||||
} while(0)
|
||||
|
||||
#define CHECK_SUCCESS_NO_WARNINGS(text) \
|
||||
do \
|
||||
{ \
|
||||
auto [ast, errors] = parseAnalyseAndReturnError((text), true); \
|
||||
auto [ast, errors] = runAnalysisAndExpectNoParsingErrors((text), true); \
|
||||
std::string message; \
|
||||
if (!errors.empty()) \
|
||||
message = formatErrors(errors);\
|
||||
|
@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
|
||||
function functionName(bytes32 input) public virtual returns (bytes32 out);
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
|
||||
abstract contract base { function foo() public virtual; }
|
||||
contract derived is base { function foo() public override {} }
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
|
||||
abstract contract base { function foo(bool) public virtual; }
|
||||
abstract contract derived is base { function foo(uint) public {} }
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
|
||||
abstract contract base { function foo() public virtual; }
|
||||
abstract contract foo is base { constructor() {} }
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature)
|
||||
}
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
|
||||
}
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(function_external_types)
|
||||
}
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(enum_external_type)
|
||||
}
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE(external_struct_signatures)
|
||||
// Ignore analysis errors. This test only checks that correct signatures
|
||||
// are generated for external structs, but they are not yet supported
|
||||
// in code generation and therefore cause an error in the TypeChecker.
|
||||
SourceUnit const* sourceUnit = parseAnalyseAndReturnError(text, false, true, true).first;
|
||||
SourceUnit const* sourceUnit = runAnalysisAndExpectNoParsingErrors(text, false, true, true).first;
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(external_struct_signatures_in_libraries)
|
||||
// Ignore analysis errors. This test only checks that correct signatures
|
||||
// are generated for external structs, but calldata structs are not yet supported
|
||||
// in code generation and therefore cause an error in the TypeChecker.
|
||||
SourceUnit const* sourceUnit = parseAnalyseAndReturnError(text, false, true, true).first;
|
||||
SourceUnit const* sourceUnit = runAnalysisAndExpectNoParsingErrors(text, false, true, true).first;
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
@ -281,7 +281,7 @@ BOOST_AUTO_TEST_CASE(struct_with_mapping_in_library)
|
||||
function f(X storage x) external {}
|
||||
}
|
||||
)";
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
|
||||
}
|
||||
)";
|
||||
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(private_state_variable)
|
||||
}
|
||||
)";
|
||||
|
||||
auto [sourceUnit, errors] = parseAnalyseAndReturnError(text);
|
||||
auto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);
|
||||
soltestAssert(sourceUnit);
|
||||
soltestAssert(errors.empty(), "Unexpected error: " + formatErrors(errors));
|
||||
|
||||
@ -397,7 +397,7 @@ BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
contract C {}
|
||||
)";
|
||||
auto sourceAndError = parseAnalyseAndReturnError(text, true, false);
|
||||
auto sourceAndError = runAnalysisAndExpectNoParsingErrors(text, true, false);
|
||||
BOOST_REQUIRE(!sourceAndError.second.empty());
|
||||
BOOST_REQUIRE(!!sourceAndError.first);
|
||||
BOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), "Source file does not specify required compiler version!"));
|
||||
|
Loading…
Reference in New Issue
Block a user