Merge pull request #1243 from ethereum/1131

Add enums as inheritable members
This commit is contained in:
chriseth 2016-10-21 15:29:58 +02:00 committed by GitHub
commit 3e13e59ff9
4 changed files with 88 additions and 0 deletions

View File

@ -12,6 +12,7 @@ Bugfixes:
* Disallow unknown options in ``solc``.
* Proper type checking for bound functions.
* Code Generator: expect zero stack increase after `super` as an expression.
* Allow inheritance of ``enum`` definitions.
* Inline assembly: support the ``address`` opcode.
* Inline assembly: fix parsing of assignment after a label.
* Inline assembly: external variables of unsupported type (such as ``this``, ``super``, etc.)

View File

@ -189,6 +189,7 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const
m_inheritableMembers.reset(new vector<Declaration const*>());
auto addInheritableMember = [&](Declaration const* _decl)
{
solAssert(_decl, "addInheritableMember got a nullpointer.");
if (memberSeen.count(_decl->name()) == 0 && _decl->isVisibleInDerivedContracts())
{
memberSeen.insert(_decl->name());
@ -204,6 +205,9 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const
for (StructDefinition const* s: definedStructs())
addInheritableMember(s);
for (EnumDefinition const* e: definedEnums())
addInheritableMember(e);
}
return *m_inheritableMembers;
}

View File

@ -3314,6 +3314,57 @@ BOOST_AUTO_TEST_CASE(using_enums)
BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2));
}
BOOST_AUTO_TEST_CASE(using_contract_enums_with_explicit_contract_name)
{
char const* sourceCode = R"(
contract test {
enum Choice { A, B, C }
function answer () returns (test.Choice _ret)
{
_ret = test.Choice.B;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1));
}
BOOST_AUTO_TEST_CASE(using_inherited_enum)
{
char const* sourceCode = R"(
contract base {
enum Choice { A, B, C }
}
contract test is base {
function answer () returns (Choice _ret)
{
_ret = Choice.B;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1));
}
BOOST_AUTO_TEST_CASE(using_inherited_enum_excplicitly)
{
char const* sourceCode = R"(
contract base {
enum Choice { A, B, C }
}
contract test is base {
function answer () returns (base.Choice _ret)
{
_ret = base.Choice.B;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1));
}
BOOST_AUTO_TEST_CASE(constructing_enums_from_ints)
{
char const* sourceCode = R"(

View File

@ -1439,6 +1439,21 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access)
BOOST_CHECK(expectError(text) == Error::Type::TypeError);
}
BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access)
{
char const* text = R"(
contract test {
enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
function test()
{
choices = Sit;
}
ActionChoices choices;
}
)";
BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
}
BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
{
char const* text = R"(
@ -1500,6 +1515,23 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values)
BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
}
BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name)
{
char const* text = R"(
contract A {
enum Foo {
First,
Second
}
function a() {
A.Foo;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(private_visibility)
{
char const* sourceCode = R"(