From 5659ed1238d15b024294039414221ee683f92191 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Feb 2015 15:19:04 +0100 Subject: [PATCH] Correcting and testing enum member access --- libsolidity/Types.cpp | 20 +++++++------------- libsolidity/Types.h | 3 ++- test/SolidityNameAndTypeResolution.cpp | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 418d6b17e..f25431605 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -682,19 +682,6 @@ string EnumType::toString() const return string("enum ") + m_enum.getName(); } -MemberList const& EnumType::getMembers() const -{ - // We need to lazy-initialize it because of recursive references. - if (!m_members) - { - map> members; - for (ASTPointer const& enumValue: m_enum.getMembers()) - members.insert(make_pair(enumValue->getName(), make_shared(m_enum))); - m_members.reset(new MemberList(members)); - } - return *m_members; -} - FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), @@ -957,6 +944,13 @@ MemberList const& TypeType::getMembers() const if (!f->isConstructor() && !f->getName().empty()) members[f->getName()] = make_shared(*f); } + else if (m_actualType->getCategory() == Category::Enum) + { + EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); + for (ASTPointer const& enumValue: enumDef.getMembers()) + members.insert(make_pair(enumValue->getName(), make_shared(enumDef))); + m_members.reset(new MemberList(members)); + } m_members.reset(new MemberList(members)); } return *m_members; diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 70703938d..0b576bd3f 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -379,8 +379,9 @@ public: virtual bool operator==(Type const& _other) const override; virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ } virtual std::string toString() const override; + virtual bool isValueType() const override { return true; } - virtual MemberList const& getMembers() const override; + EnumDefinition const& getEnumDefinition() const { return m_enum; } private: EnumDefinition const& m_enum; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 490ab3be5..34f51a4ce 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -991,11 +991,11 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) })"; BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } + BOOST_AUTO_TEST_CASE(enum_member_access) { char const* text = R"( contract test { - struct foo { uint256 x;} enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; function test() { @@ -1007,6 +1007,21 @@ BOOST_AUTO_TEST_CASE(enum_member_access) BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); } +BOOST_AUTO_TEST_CASE(enum_invalid_member_access) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; + function test() + { + choices = ActionChoices.RunAroundWavingYourHands; + } + ActionChoices choices; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() }