Fix: Resolve function types of all contracts before checking types inside functions.

This commit is contained in:
Christian 2014-12-16 23:45:24 +01:00
parent 350953e598
commit 5e148ae4b6
3 changed files with 30 additions and 3 deletions

View File

@ -52,9 +52,13 @@ bytes compileContract(const string& _sourceCode)
resolver.registerDeclarations(*sourceUnit);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
Compiler compiler;
compiler.compileContract(*contract, {}, {});
// debug

View File

@ -95,8 +95,13 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
resolver.registerDeclarations(*sourceUnit);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
FirstExpressionExtractor extractor(*contract);
BOOST_REQUIRE(extractor.getExpression() != nullptr);

View File

@ -47,6 +47,9 @@ void parseTextAndResolveNames(std::string const& _source)
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.resolveNamesAndTypes(*contract);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.checkTypeRequirements(*contract);
}
}
@ -293,6 +296,21 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(forward_function_reference)
{
char const* text = "contract First {\n"
" function fun() returns (bool ret) {\n"
" return Second(1).fun(1, true, 3) > 0;\n"
" }\n"
"}\n"
"contract Second {\n"
" function fun(uint a, bool b, uint c) returns (uint ret) {\n"
" if (First(2).fun() == true) return 1;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_SUITE_END()
}