diff options
Diffstat (limited to 'libsolidity/ast/AST.cpp')
-rw-r--r-- | libsolidity/ast/AST.cpp | 189 |
1 files changed, 164 insertions, 25 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 3cd1dfbe..724a908f 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -20,21 +20,37 @@ * Solidity abstract syntax tree. */ -#include <algorithm> -#include <functional> -#include <libsolidity/interface/Utils.h> #include <libsolidity/ast/AST.h> #include <libsolidity/ast/ASTVisitor.h> -#include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/AST_accept.h> #include <libdevcore/SHA3.h> +#include <boost/algorithm/string.hpp> + +#include <algorithm> +#include <functional> + using namespace std; using namespace dev; using namespace dev::solidity; +class IDDispenser +{ +public: + static size_t next() { return ++instance(); } + static void reset() { instance() = 0; } +private: + static size_t& instance() + { + static IDDispenser dispenser; + return dispenser.id; + } + size_t id = 0; +}; + ASTNode::ASTNode(SourceLocation const& _location): + m_id(IDDispenser::next()), m_location(_location) { } @@ -44,6 +60,11 @@ ASTNode::~ASTNode() delete m_annotation; } +void ASTNode::resetID() +{ + IDDispenser::reset(); +} + ASTAnnotation& ASTNode::annotation() const { if (!m_annotation) @@ -60,7 +81,7 @@ SourceUnitAnnotation& SourceUnit::annotation() const { if (!m_annotation) m_annotation = new SourceUnitAnnotation(); - return static_cast<SourceUnitAnnotation&>(*m_annotation); + return dynamic_cast<SourceUnitAnnotation&>(*m_annotation); } string Declaration::sourceUnitName() const @@ -76,7 +97,7 @@ ImportAnnotation& ImportDirective::annotation() const { if (!m_annotation) m_annotation = new ImportAnnotation(); - return static_cast<ImportAnnotation&>(*m_annotation); + return dynamic_cast<ImportAnnotation&>(*m_annotation); } TypePointer ImportDirective::type() const @@ -109,6 +130,12 @@ FunctionDefinition const* ContractDefinition::constructor() const return nullptr; } +bool ContractDefinition::constructorIsPublic() const +{ + FunctionDefinition const* f = constructor(); + return !f || f->isPublic(); +} + FunctionDefinition const* ContractDefinition::fallbackFunction() const { for (ContractDefinition const* contract: annotation().linearizedBaseContracts) @@ -189,7 +216,6 @@ void ContractDefinition::setUserDocumentation(Json::Value const& _userDocumentat m_userDocumentation = _userDocumentation; } - vector<Declaration const*> const& ContractDefinition::inheritableMembers() const { if (!m_inheritableMembers) @@ -217,6 +243,9 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const for (EnumDefinition const* e: definedEnums()) addInheritableMember(e); + + for (EventDefinition const* e: events()) + addInheritableMember(e); } return *m_inheritableMembers; } @@ -230,14 +259,14 @@ ContractDefinitionAnnotation& ContractDefinition::annotation() const { if (!m_annotation) m_annotation = new ContractDefinitionAnnotation(); - return static_cast<ContractDefinitionAnnotation&>(*m_annotation); + return dynamic_cast<ContractDefinitionAnnotation&>(*m_annotation); } TypeNameAnnotation& TypeName::annotation() const { if (!m_annotation) m_annotation = new TypeNameAnnotation(); - return static_cast<TypeNameAnnotation&>(*m_annotation); + return dynamic_cast<TypeNameAnnotation&>(*m_annotation); } TypePointer StructDefinition::type() const @@ -249,7 +278,7 @@ TypeDeclarationAnnotation& StructDefinition::annotation() const { if (!m_annotation) m_annotation = new TypeDeclarationAnnotation(); - return static_cast<TypeDeclarationAnnotation&>(*m_annotation); + return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation); } TypePointer EnumValue::type() const @@ -268,7 +297,46 @@ TypeDeclarationAnnotation& EnumDefinition::annotation() const { if (!m_annotation) m_annotation = new TypeDeclarationAnnotation(); - return static_cast<TypeDeclarationAnnotation&>(*m_annotation); + return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation); +} + +shared_ptr<FunctionType> FunctionDefinition::functionType(bool _internal) const +{ + if (_internal) + { + switch (visibility()) + { + case Declaration::Visibility::Default: + solAssert(false, "visibility() should not return Default"); + case Declaration::Visibility::Private: + case Declaration::Visibility::Internal: + case Declaration::Visibility::Public: + return make_shared<FunctionType>(*this, _internal); + case Declaration::Visibility::External: + return {}; + default: + solAssert(false, "visibility() should not return a Visibility"); + } + } + else + { + switch (visibility()) + { + case Declaration::Visibility::Default: + solAssert(false, "visibility() should not return Default"); + case Declaration::Visibility::Private: + case Declaration::Visibility::Internal: + return {}; + case Declaration::Visibility::Public: + case Declaration::Visibility::External: + return make_shared<FunctionType>(*this, _internal); + default: + solAssert(false, "visibility() should not return a Visibility"); + } + } + + // To make the compiler happy + return {}; } TypePointer FunctionDefinition::type() const @@ -285,7 +353,7 @@ FunctionDefinitionAnnotation& FunctionDefinition::annotation() const { if (!m_annotation) m_annotation = new FunctionDefinitionAnnotation(); - return static_cast<FunctionDefinitionAnnotation&>(*m_annotation); + return dynamic_cast<FunctionDefinitionAnnotation&>(*m_annotation); } TypePointer ModifierDefinition::type() const @@ -297,7 +365,7 @@ ModifierDefinitionAnnotation& ModifierDefinition::annotation() const { if (!m_annotation) m_annotation = new ModifierDefinitionAnnotation(); - return static_cast<ModifierDefinitionAnnotation&>(*m_annotation); + return dynamic_cast<ModifierDefinitionAnnotation&>(*m_annotation); } TypePointer EventDefinition::type() const @@ -305,18 +373,26 @@ TypePointer EventDefinition::type() const return make_shared<FunctionType>(*this); } +std::shared_ptr<FunctionType> EventDefinition::functionType(bool _internal) const +{ + if (_internal) + return make_shared<FunctionType>(*this); + else + return {}; +} + EventDefinitionAnnotation& EventDefinition::annotation() const { if (!m_annotation) m_annotation = new EventDefinitionAnnotation(); - return static_cast<EventDefinitionAnnotation&>(*m_annotation); + return dynamic_cast<EventDefinitionAnnotation&>(*m_annotation); } UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const { if (!m_annotation) m_annotation = new UserDefinedTypeNameAnnotation(); - return static_cast<UserDefinedTypeNameAnnotation&>(*m_annotation); + return dynamic_cast<UserDefinedTypeNameAnnotation&>(*m_annotation); } bool VariableDeclaration::isLValue() const @@ -340,6 +416,23 @@ bool VariableDeclaration::isCallableParameter() const return false; } +bool VariableDeclaration::isLocalOrReturn() const +{ + return isReturnParameter() || (isLocalVariable() && !isCallableParameter()); +} + +bool VariableDeclaration::isReturnParameter() const +{ + auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()); + if (!callable) + return false; + if (callable->returnParameterList()) + for (auto const& variable: callable->returnParameterList()->parameters()) + if (variable.get() == this) + return true; + return false; +} + bool VariableDeclaration::isExternalCallableParameter() const { auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()); @@ -362,72 +455,118 @@ TypePointer VariableDeclaration::type() const return annotation().type; } +shared_ptr<FunctionType> VariableDeclaration::functionType(bool _internal) const +{ + if (_internal) + return {}; + switch (visibility()) + { + case Declaration::Visibility::Default: + solAssert(false, "visibility() should not return Default"); + case Declaration::Visibility::Private: + case Declaration::Visibility::Internal: + return {}; + case Declaration::Visibility::Public: + case Declaration::Visibility::External: + return make_shared<FunctionType>(*this); + default: + solAssert(false, "visibility() should not return a Visibility"); + } + + // To make the compiler happy + return {}; +} + VariableDeclarationAnnotation& VariableDeclaration::annotation() const { if (!m_annotation) m_annotation = new VariableDeclarationAnnotation(); - return static_cast<VariableDeclarationAnnotation&>(*m_annotation); + return dynamic_cast<VariableDeclarationAnnotation&>(*m_annotation); } StatementAnnotation& Statement::annotation() const { if (!m_annotation) m_annotation = new StatementAnnotation(); - return static_cast<StatementAnnotation&>(*m_annotation); + return dynamic_cast<StatementAnnotation&>(*m_annotation); } InlineAssemblyAnnotation& InlineAssembly::annotation() const { if (!m_annotation) m_annotation = new InlineAssemblyAnnotation(); - return static_cast<InlineAssemblyAnnotation&>(*m_annotation); + return dynamic_cast<InlineAssemblyAnnotation&>(*m_annotation); } ReturnAnnotation& Return::annotation() const { if (!m_annotation) m_annotation = new ReturnAnnotation(); - return static_cast<ReturnAnnotation&>(*m_annotation); + return dynamic_cast<ReturnAnnotation&>(*m_annotation); } VariableDeclarationStatementAnnotation& VariableDeclarationStatement::annotation() const { if (!m_annotation) m_annotation = new VariableDeclarationStatementAnnotation(); - return static_cast<VariableDeclarationStatementAnnotation&>(*m_annotation); + return dynamic_cast<VariableDeclarationStatementAnnotation&>(*m_annotation); } ExpressionAnnotation& Expression::annotation() const { if (!m_annotation) m_annotation = new ExpressionAnnotation(); - return static_cast<ExpressionAnnotation&>(*m_annotation); + return dynamic_cast<ExpressionAnnotation&>(*m_annotation); } MemberAccessAnnotation& MemberAccess::annotation() const { if (!m_annotation) m_annotation = new MemberAccessAnnotation(); - return static_cast<MemberAccessAnnotation&>(*m_annotation); + return dynamic_cast<MemberAccessAnnotation&>(*m_annotation); } BinaryOperationAnnotation& BinaryOperation::annotation() const { if (!m_annotation) m_annotation = new BinaryOperationAnnotation(); - return static_cast<BinaryOperationAnnotation&>(*m_annotation); + return dynamic_cast<BinaryOperationAnnotation&>(*m_annotation); } FunctionCallAnnotation& FunctionCall::annotation() const { if (!m_annotation) m_annotation = new FunctionCallAnnotation(); - return static_cast<FunctionCallAnnotation&>(*m_annotation); + return dynamic_cast<FunctionCallAnnotation&>(*m_annotation); } IdentifierAnnotation& Identifier::annotation() const { if (!m_annotation) m_annotation = new IdentifierAnnotation(); - return static_cast<IdentifierAnnotation&>(*m_annotation); + return dynamic_cast<IdentifierAnnotation&>(*m_annotation); +} + +bool Literal::isHexNumber() const +{ + if (token() != Token::Number) + return false; + return boost::starts_with(value(), "0x"); +} + +bool Literal::looksLikeAddress() const +{ + if (subDenomination() != SubDenomination::None) + return false; + + if (!isHexNumber()) + return false; + + return abs(int(value().length()) - 42) <= 1; +} + +bool Literal::passesAddressChecksum() const +{ + solAssert(isHexNumber(), "Expected hex number"); + return dev::passesAddressChecksum(value(), true); } |