aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast/AST.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/ast/AST.cpp')
-rw-r--r--libsolidity/ast/AST.cpp189
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);
}