Type resolution for function modifiers.

This commit is contained in:
Christian 2015-01-22 01:02:38 +01:00
parent dabf947679
commit c86a46b84d
3 changed files with 113 additions and 0 deletions

View File

@ -1650,6 +1650,26 @@ BOOST_AUTO_TEST_CASE(constructor_argument_overriding)
BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3)); BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3));
} }
BOOST_AUTO_TEST_CASE(function_modifier)
{
char const* sourceCode = R"(
contract BaseBase {
uint m_a;
function BaseBase(uint a) {
m_a = a;
}
}
contract Base is BaseBase(2) { }
contract Derived is Base, BaseBase(3) {
function getA() returns (uint r) { return m_a; }
}
)";
compileAndRun(sourceCode, 0, "Derived");
BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3));
}
// modifier overriding
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -479,6 +479,7 @@ BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion)
)"; )";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
} }
BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
{ {
char const* text = R"( char const* text = R"(
@ -490,6 +491,88 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
} }
BOOST_AUTO_TEST_CASE(function_modifier_invocation)
{
char const* text = R"(
contract B {
function f() mod1(2, true) mod2("0123456") { }
modifier mod1(uint a, bool b) { if (b) _ }
modifier mod2(string7 a) { while (a == "1234567") _ }
}
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
{
char const* text = R"(
contract B {
function f() mod1(true) { }
modifier mod1(uint a) { if (a > 0) _ }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
{
char const* text = R"(
contract B {
function f(uint8 a) mod1(a, true) mod2(r) returns (string7 r) { }
modifier mod1(uint a, bool b) { if (b) _ }
modifier mod2(string7 a) { while (a == "1234567") _ }
}
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
{
char const* text = R"(
contract B {
function f() mod(x) { uint x = 7; }
modifier mod(uint a) { if (a > 0) _ }
}
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(legal_modifier_override)
{
char const* text = R"(
contract A { modifier mod(uint a) {} }
contract B is A { modifier mod(uint a) {} }
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(illegal_modifier_override)
{
char const* text = R"(
contract A { modifier mod(uint a) {} }
contract B is A { modifier mod(uint8 a) {} }
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(modifier_overrides_function)
{
char const* text = R"(
contract A { modifier mod(uint a) {} }
contract B is A { function mod(uint a) {} }
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
{
char const* text = R"(
contract A { function mod(uint a) {} }
contract B is A { modifier mod(uint a) {} }
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -567,6 +567,16 @@ BOOST_AUTO_TEST_CASE(modifier_arguments)
BOOST_CHECK_NO_THROW(parseText(text)); BOOST_CHECK_NO_THROW(parseText(text));
} }
BOOST_AUTO_TEST_CASE(modifier_invocation)
{
char const* text = "contract c {\n"
" modifier mod1(uint a) { if (msg.sender == a) _ }\n"
" modifier mod2 { if (msg.sender == 2) _ }\n"
" function f() mod1(7) mod2 { }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseText(text));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }