Merge pull request #1338 from LianaHus/sol_ConvertContractTypesToAddress

Solidity: Convert contract types to addresses
This commit is contained in:
chriseth 2015-03-27 15:14:40 +01:00
commit d2b5407502

View File

@ -28,6 +28,7 @@
#include <libsolidity/Parser.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <libsolidity/GlobalContext.h>
#include "TestHelper.h"
using namespace std;
@ -48,16 +49,28 @@ ASTPointer<SourceUnit> parseTextAndResolveNames(std::string const& _source)
ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
NameAndTypeResolver resolver({});
resolver.registerDeclarations(*sourceUnit);
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
globalContext->setCurrentContract(*contract);
resolver.updateDeclaration(*globalContext->getCurrentThis());
resolver.updateDeclaration(*globalContext->getCurrentSuper());
resolver.resolveNamesAndTypes(*contract);
}
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
globalContext->setCurrentContract(*contract);
resolver.updateDeclaration(*globalContext->getCurrentThis());
resolver.checkTypeRequirements(*contract);
}
return sourceUnit;
}
static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source, unsigned index)
{
ContractDefinition* contract;
@ -359,7 +372,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
BOOST_CHECK_EQUAL("foo(uint256,uint64,bool)", functions[0]->getCanonicalSignature());
BOOST_CHECK_EQUAL("foo(uint256,uint64,bool)", functions[0]->externalSignature());
}
}
@ -376,10 +389,95 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->getCanonicalSignature());
if (functions.empty())
continue;
BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->externalSignature());
}
}
BOOST_AUTO_TEST_CASE(function_external_types)
{
ASTPointer<SourceUnit> sourceUnit;
char const* text = R"(
contract C {
uint a;
}
contract Test {
function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg) external returns (uint ret) {
ret = 5;
}
})";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
if (functions.empty())
continue;
BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address)", functions[0]->externalSignature());
}
}
BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
{
char const* text = R"(
contract C {}
contract Test {
function externalCall() {
C arg;
this.g(arg);
}
function g (C c) external {}
})";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
{
char const* text = R"(
contract C {}
contract Test {
function externalCall() {
address arg;
this.g(arg);
}
function g (C c) external {}
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
{
char const* text = R"(
contract C {
uint a;
}
contract Test {
C a;
function g (C c) {}
function internalCall() {
g(a);
}
})";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
{
char const* text = R"(
contract C {
uint a;
}
contract Test {
address a;
function g (C c) {}
function internalCall() {
g(a);
}
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
{
char const* text = "contract test {\n"