Browse Source

Enum Value member access should now work properly

- Also detection of duplicate enum values and tests for them have been
  added
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
5c164fb42c
  1. 14
      libsolidity/AST.cpp
  2. 27
      libsolidity/ExpressionCompiler.cpp
  3. 17
      test/SolidityNameAndTypeResolution.cpp

14
libsolidity/AST.cpp

@ -263,13 +263,15 @@ void StructDefinition::checkRecursion() const
void EnumDefinition::checkValidityOfMembers() const
{
#if 0 // LTODO: Make this work for the Declarations
vector<ASTPointer<ASTString>> members = getMembers();
sort(begin(members), end(members));
for (size_t i = 0; i < members.size(); ++i)
if (members[i] == members[i + 1])
vector<ASTPointer<EnumDeclaration>> members(getMembers());
auto compareDecls = [](ASTPointer<EnumDeclaration> a, ASTPointer<EnumDeclaration> b)
{
return a->getName() < b->getName();
};
sort(begin(members), end(members), compareDecls);
for (size_t i = 0; i < members.size() - 1; ++i)
if (members[i]->getName() == members[i + 1]->getName())
BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum"));
#endif
}
TypePointer EnumDefinition::getType(ContractDefinition const*) const

27
libsolidity/ExpressionCompiler.cpp

@ -494,20 +494,31 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
EnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.getExpression().getType());
EnumDefinition const& enumDef = type.getEnumDefinition();
m_context << enumDef.getMemberValue(_memberAccess.getMemberName());
break;
}
case Type::Category::TypeType:
{
TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType());
ContractType const* contractType;
EnumType const* enumType;
if (type.getMembers().getMemberType(member))
{
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*type.getActualType())
.getContractDefinition();
for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions())
if (function->getName() == member)
{
m_context << m_context.getFunctionEntryLabel(*function).pushTag();
return;
}
if ((contractType = dynamic_cast<ContractType const*>(type.getActualType().get())))
{
ContractDefinition const& contract = contractType->getContractDefinition();
for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions())
if (function->getName() == member)
{
m_context << m_context.getFunctionEntryLabel(*function).pushTag();
return;
}
}
else if ((enumType = dynamic_cast<EnumType const*>(type.getActualType().get())))
{
EnumDefinition const &enumDef = enumType->getEnumDefinition();
m_context << enumDef.getMemberValue(_memberAccess.getMemberName());
return;
}
}
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString()));
}

17
test/SolidityNameAndTypeResolution.cpp

@ -1056,6 +1056,23 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(enum_duplicate_values)
{
char const* text = R"(
contract test {
enum ActionChoices { GoLeft, GoRight, GoLeft, Sit };
function test()
{
a = 1;
b = 2;
}
uint256 a;
uint64 b;
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_SUITE_END()
}

Loading…
Cancel
Save