mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Addressing issues with Enums in Solidity
This commit is contained in:
parent
b20ce4451b
commit
b2575b4bcb
3
AST.cpp
3
AST.cpp
@ -209,6 +209,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
|
|||||||
TypePointer EnumValue::getType(ContractDefinition const*) const
|
TypePointer EnumValue::getType(ContractDefinition const*) const
|
||||||
{
|
{
|
||||||
EnumDefinition const* parentDef = dynamic_cast<EnumDefinition const*>(getScope());
|
EnumDefinition const* parentDef = dynamic_cast<EnumDefinition const*>(getScope());
|
||||||
|
solAssert(parentDef, "Enclosing Scope of EnumValue was not set");
|
||||||
return make_shared<EnumType>(*parentDef);
|
return make_shared<EnumType>(*parentDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +272,7 @@ void EnumDefinition::checkValidityOfMembers() const
|
|||||||
sort(begin(members), end(members), compareDecls);
|
sort(begin(members), end(members), compareDecls);
|
||||||
for (size_t i = 0; i < members.size() - 1; ++i)
|
for (size_t i = 0; i < members.size() - 1; ++i)
|
||||||
if (members[i]->getName() == members[i + 1]->getName())
|
if (members[i]->getName() == members[i + 1]->getName())
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum"));
|
BOOST_THROW_EXCEPTION(members[i]->createTypeError("Duplicate member detected in Enum"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer EnumDefinition::getType(ContractDefinition const*) const
|
TypePointer EnumDefinition::getType(ContractDefinition const*) const
|
||||||
|
30
AST.h
30
AST.h
@ -165,21 +165,6 @@ private:
|
|||||||
Declaration const* m_scope;
|
Declaration const* m_scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Declaration of an Enum Value
|
|
||||||
*/
|
|
||||||
class EnumValue: public Declaration
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EnumValue(Location const& _location,
|
|
||||||
ASTPointer<ASTString> const& _name):
|
|
||||||
Declaration(_location, _name) {}
|
|
||||||
|
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
|
||||||
TypePointer getType(ContractDefinition const* = nullptr) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class that is added to each AST node that can store local variables.
|
* Abstract class that is added to each AST node that can store local variables.
|
||||||
*/
|
*/
|
||||||
@ -359,6 +344,21 @@ private:
|
|||||||
std::vector<ASTPointer<EnumValue>> m_members;
|
std::vector<ASTPointer<EnumValue>> m_members;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declaration of an Enum Value
|
||||||
|
*/
|
||||||
|
class EnumValue: public Declaration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnumValue(Location const& _location,
|
||||||
|
ASTPointer<ASTString> const& _name):
|
||||||
|
Declaration(_location, _name) {}
|
||||||
|
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
TypePointer getType(ContractDefinition const* = nullptr) const;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter list, used as function parameter list and return list.
|
* Parameter list, used as function parameter list and return list.
|
||||||
* None of the parameters is allowed to contain mappings (not even recursively
|
* None of the parameters is allowed to contain mappings (not even recursively
|
||||||
|
@ -501,26 +501,26 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
|
|||||||
TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType());
|
TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType());
|
||||||
ContractType const* contractType;
|
ContractType const* contractType;
|
||||||
EnumType const* enumType;
|
EnumType const* enumType;
|
||||||
if (type.getMembers().getMemberType(member))
|
if (!type.getMembers().getMemberType(member))
|
||||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString()));
|
||||||
|
|
||||||
|
if ((contractType = dynamic_cast<ContractType const*>(type.getActualType().get())))
|
||||||
{
|
{
|
||||||
if ((contractType = dynamic_cast<ContractType const*>(type.getActualType().get())))
|
ContractDefinition const& contract = contractType->getContractDefinition();
|
||||||
{
|
for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions())
|
||||||
ContractDefinition const& contract = contractType->getContractDefinition();
|
if (function->getName() == member)
|
||||||
for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions())
|
{
|
||||||
if (function->getName() == member)
|
m_context << m_context.getFunctionEntryLabel(*function).pushTag();
|
||||||
{
|
return;
|
||||||
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()));
|
else if ((enumType = dynamic_cast<EnumType const*>(type.getActualType().get())))
|
||||||
|
{
|
||||||
|
EnumDefinition const &enumDef = enumType->getEnumDefinition();
|
||||||
|
m_context << enumDef.getMemberValue(_memberAccess.getMemberName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
case Type::Category::ByteArray:
|
case Type::Category::ByteArray:
|
||||||
{
|
{
|
||||||
|
17
Parser.cpp
17
Parser.cpp
@ -266,12 +266,11 @@ ASTPointer<StructDefinition> Parser::parseStructDefinition()
|
|||||||
return nodeFactory.createNode<StructDefinition>(name, members);
|
return nodeFactory.createNode<StructDefinition>(name, members);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<EnumValue> Parser::parseEnumDeclaration()
|
ASTPointer<EnumValue> Parser::parseEnumValue()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
return nodeFactory.createNode<EnumValue>(name);
|
return nodeFactory.createNode<EnumValue>(expectIdentifierToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
||||||
@ -284,13 +283,12 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
|||||||
|
|
||||||
while (m_scanner->getCurrentToken() != Token::RBrace)
|
while (m_scanner->getCurrentToken() != Token::RBrace)
|
||||||
{
|
{
|
||||||
members.push_back(parseEnumDeclaration());
|
members.push_back(parseEnumValue());
|
||||||
if (m_scanner->getCurrentToken() == Token::RBrace)
|
if (m_scanner->getCurrentToken() == Token::RBrace)
|
||||||
break;
|
break;
|
||||||
expectToken(Token::Comma);
|
expectToken(Token::Comma);
|
||||||
if (m_scanner->getCurrentToken() != Token::Identifier) {
|
if (m_scanner->getCurrentToken() != Token::Identifier)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','"));
|
BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
@ -859,13 +857,6 @@ ASTPointer<ASTString> Parser::expectIdentifierToken()
|
|||||||
return getLiteralAndAdvance();
|
return getLiteralAndAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<ASTString> Parser::peekIdentifierToken()
|
|
||||||
{
|
|
||||||
if (m_scanner->getCurrentToken() != Token::Identifier)
|
|
||||||
return nullptr;
|
|
||||||
return getLiteralAndAdvance();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPointer<ASTString> Parser::getLiteralAndAdvance()
|
ASTPointer<ASTString> Parser::getLiteralAndAdvance()
|
||||||
{
|
{
|
||||||
ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||||
|
3
Parser.h
3
Parser.h
@ -62,7 +62,7 @@ private:
|
|||||||
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);
|
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);
|
||||||
ASTPointer<StructDefinition> parseStructDefinition();
|
ASTPointer<StructDefinition> parseStructDefinition();
|
||||||
ASTPointer<EnumDefinition> parseEnumDefinition();
|
ASTPointer<EnumDefinition> parseEnumDefinition();
|
||||||
ASTPointer<EnumValue> parseEnumDeclaration();
|
ASTPointer<EnumValue> parseEnumValue();
|
||||||
ASTPointer<VariableDeclaration> parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions());
|
ASTPointer<VariableDeclaration> parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions());
|
||||||
ASTPointer<ModifierDefinition> parseModifierDefinition();
|
ASTPointer<ModifierDefinition> parseModifierDefinition();
|
||||||
ASTPointer<EventDefinition> parseEventDefinition();
|
ASTPointer<EventDefinition> parseEventDefinition();
|
||||||
@ -98,7 +98,6 @@ private:
|
|||||||
void expectToken(Token::Value _value);
|
void expectToken(Token::Value _value);
|
||||||
Token::Value expectAssignmentOperator();
|
Token::Value expectAssignmentOperator();
|
||||||
ASTPointer<ASTString> expectIdentifierToken();
|
ASTPointer<ASTString> expectIdentifierToken();
|
||||||
ASTPointer<ASTString> peekIdentifierToken();
|
|
||||||
ASTPointer<ASTString> getLiteralAndAdvance();
|
ASTPointer<ASTString> getLiteralAndAdvance();
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
2
Types.h
2
Types.h
@ -377,7 +377,7 @@ public:
|
|||||||
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
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; }
|
||||||
virtual std::string toString() const override;
|
virtual std::string toString() const override;
|
||||||
virtual bool isValueType() const override { return true; }
|
virtual bool isValueType() const override { return true; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user