diff options
author | Lefteris Karapetsas <lefteris@refu.co> | 2015-02-14 05:52:04 +0800 |
---|---|---|
committer | Lefteris Karapetsas <lefteris@refu.co> | 2015-02-14 06:16:14 +0800 |
commit | b2575b4bcbd15ec8353a01ae53133f6e71115cce (patch) | |
tree | ba14d6c97ca00ddc6d77876e6876c16eb7664803 | |
parent | b20ce4451bb4c2b64b112b8654b36502ae654a24 (diff) | |
download | dexon-solidity-b2575b4bcbd15ec8353a01ae53133f6e71115cce.tar.gz dexon-solidity-b2575b4bcbd15ec8353a01ae53133f6e71115cce.tar.zst dexon-solidity-b2575b4bcbd15ec8353a01ae53133f6e71115cce.zip |
Addressing issues with Enums in Solidity
-rw-r--r-- | AST.cpp | 3 | ||||
-rw-r--r-- | AST.h | 30 | ||||
-rw-r--r-- | ExpressionCompiler.cpp | 36 | ||||
-rw-r--r-- | Parser.cpp | 17 | ||||
-rw-r--r-- | Parser.h | 3 | ||||
-rw-r--r-- | Types.h | 2 |
6 files changed, 41 insertions, 50 deletions
@@ -209,6 +209,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn TypePointer EnumValue::getType(ContractDefinition const*) const { EnumDefinition const* parentDef = dynamic_cast<EnumDefinition const*>(getScope()); + solAssert(parentDef, "Enclosing Scope of EnumValue was not set"); return make_shared<EnumType>(*parentDef); } @@ -271,7 +272,7 @@ void EnumDefinition::checkValidityOfMembers() const 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")); + BOOST_THROW_EXCEPTION(members[i]->createTypeError("Duplicate member detected in Enum")); } TypePointer EnumDefinition::getType(ContractDefinition const*) const @@ -166,21 +166,6 @@ private: }; /** - * 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. */ class VariableScope @@ -360,6 +345,21 @@ private: }; /** + * 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. * None of the parameters is allowed to contain mappings (not even recursively * inside structs). diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 4e72aca5..00c2dafd 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -501,26 +501,26 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType()); ContractType const* contractType; 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()) - 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; - } + ContractDefinition const& contract = contractType->getContractDefinition(); + for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions()) + if (function->getName() == member) + { + m_context << m_context.getFunctionEntryLabel(*function).pushTag(); + 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: { @@ -266,12 +266,11 @@ ASTPointer<StructDefinition> Parser::parseStructDefinition() return nodeFactory.createNode<StructDefinition>(name, members); } -ASTPointer<EnumValue> Parser::parseEnumDeclaration() +ASTPointer<EnumValue> Parser::parseEnumValue() { ASTNodeFactory nodeFactory(*this); - ASTPointer<ASTString> name = expectIdentifierToken(); nodeFactory.markEndPosition(); - return nodeFactory.createNode<EnumValue>(name); + return nodeFactory.createNode<EnumValue>(expectIdentifierToken()); } ASTPointer<EnumDefinition> Parser::parseEnumDefinition() @@ -284,13 +283,12 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition() while (m_scanner->getCurrentToken() != Token::RBrace) { - members.push_back(parseEnumDeclaration()); + members.push_back(parseEnumValue()); if (m_scanner->getCurrentToken() == Token::RBrace) break; expectToken(Token::Comma); - if (m_scanner->getCurrentToken() != Token::Identifier) { + if (m_scanner->getCurrentToken() != Token::Identifier) BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','")); - } } nodeFactory.markEndPosition(); @@ -859,13 +857,6 @@ ASTPointer<ASTString> Parser::expectIdentifierToken() return getLiteralAndAdvance(); } -ASTPointer<ASTString> Parser::peekIdentifierToken() -{ - if (m_scanner->getCurrentToken() != Token::Identifier) - return nullptr; - return getLiteralAndAdvance(); -} - ASTPointer<ASTString> Parser::getLiteralAndAdvance() { ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->getCurrentLiteral()); @@ -62,7 +62,7 @@ private: ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<StructDefinition> parseStructDefinition(); ASTPointer<EnumDefinition> parseEnumDefinition(); - ASTPointer<EnumValue> parseEnumDeclaration(); + ASTPointer<EnumValue> parseEnumValue(); ASTPointer<VariableDeclaration> parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer<ModifierDefinition> parseModifierDefinition(); ASTPointer<EventDefinition> parseEventDefinition(); @@ -98,7 +98,6 @@ private: void expectToken(Token::Value _value); Token::Value expectAssignmentOperator(); ASTPointer<ASTString> expectIdentifierToken(); - ASTPointer<ASTString> peekIdentifierToken(); ASTPointer<ASTString> getLiteralAndAdvance(); ///@} @@ -377,7 +377,7 @@ public: explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} virtual TypePointer unaryOperatorResult(Token::Value _operator) 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 bool isValueType() const override { return true; } |