Browse Source

Correcting and testing enum member access

cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
5659ed1238
  1. 20
      libsolidity/Types.cpp
  2. 3
      libsolidity/Types.h
  3. 17
      test/SolidityNameAndTypeResolution.cpp

20
libsolidity/Types.cpp

@ -682,19 +682,6 @@ string EnumType::toString() const
return string("enum ") + m_enum.getName(); 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<string, shared_ptr<Type const>> members;
for (ASTPointer<EnumDeclaration> const& enumValue: m_enum.getMembers())
members.insert(make_pair(enumValue->getName(), make_shared<EnumType>(m_enum)));
m_members.reset(new MemberList(members));
}
return *m_members;
}
FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal):
m_location(_isInternal ? Location::Internal : Location::External), m_location(_isInternal ? Location::Internal : Location::External),
m_isConstant(_function.isDeclaredConst()), m_isConstant(_function.isDeclaredConst()),
@ -957,6 +944,13 @@ MemberList const& TypeType::getMembers() const
if (!f->isConstructor() && !f->getName().empty()) if (!f->isConstructor() && !f->getName().empty())
members[f->getName()] = make_shared<FunctionType>(*f); members[f->getName()] = make_shared<FunctionType>(*f);
} }
else if (m_actualType->getCategory() == Category::Enum)
{
EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).getEnumDefinition();
for (ASTPointer<EnumDeclaration> const& enumValue: enumDef.getMembers())
members.insert(make_pair(enumValue->getName(), make_shared<EnumType>(enumDef)));
m_members.reset(new MemberList(members));
}
m_members.reset(new MemberList(members)); m_members.reset(new MemberList(members));
} }
return *m_members; return *m_members;

3
libsolidity/Types.h

@ -379,8 +379,9 @@ public:
virtual bool operator==(Type const& _other) const override; virtual bool operator==(Type const& _other) const override;
virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ } virtual unsigned getSizeOnStack() const override { return 1; /*@todo*/ }
virtual std::string toString() const override; 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: private:
EnumDefinition const& m_enum; EnumDefinition const& m_enum;

17
test/SolidityNameAndTypeResolution.cpp

@ -991,11 +991,11 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
})"; })";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
} }
BOOST_AUTO_TEST_CASE(enum_member_access) BOOST_AUTO_TEST_CASE(enum_member_access)
{ {
char const* text = R"( char const* text = R"(
contract test { contract test {
struct foo { uint256 x;}
enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }; enum ActionChoices { GoLeft, GoRight, GoStraight, Sit };
function test() function test()
{ {
@ -1007,6 +1007,21 @@ BOOST_AUTO_TEST_CASE(enum_member_access)
BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); 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() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save