aboutsummaryrefslogtreecommitdiffstats
path: root/AST.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-03-31 01:33:30 +0800
committerchriseth <c@ethdev.com>2015-03-31 01:33:30 +0800
commiteab085baf6d9953c008803b1d27e0076d51441a5 (patch)
tree5148b9e0f2ddeb880b689f9ebe944f46c5801bb5 /AST.cpp
parentf728a336b1af6ae25b5cb5282119bef8f55c08b6 (diff)
parentc6781ed38dd7c634ef8dbbbebcac582451c04ddd (diff)
downloaddexon-solidity-eab085baf6d9953c008803b1d27e0076d51441a5.tar.gz
dexon-solidity-eab085baf6d9953c008803b1d27e0076d51441a5.tar.zst
dexon-solidity-eab085baf6d9953c008803b1d27e0076d51441a5.zip
Merge pull request #1414 from LefterisJP/sol_notImplementedFuncs
Interface contracts
Diffstat (limited to 'AST.cpp')
-rw-r--r--AST.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/AST.cpp b/AST.cpp
index 1736469e..e3c9bc96 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -21,6 +21,7 @@
*/
#include <algorithm>
+#include <boost/range/adaptor/reversed.hpp>
#include <libsolidity/Utils.h>
#include <libsolidity/AST.h>
#include <libsolidity/ASTVisitor.h>
@@ -52,6 +53,7 @@ void ContractDefinition::checkTypeRequirements()
baseSpecifier->checkTypeRequirements();
checkIllegalOverrides();
+ checkAbstractFunctions();
FunctionDefinition const* constructor = getConstructor();
if (constructor && !constructor->getReturnParameters().empty())
@@ -60,6 +62,7 @@ void ContractDefinition::checkTypeRequirements()
FunctionDefinition const* fallbackFunction = nullptr;
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
+ {
if (function->getName().empty())
{
if (fallbackFunction)
@@ -71,6 +74,9 @@ void ContractDefinition::checkTypeRequirements()
BOOST_THROW_EXCEPTION(fallbackFunction->getParameterList().createTypeError("Fallback function cannot take parameters."));
}
}
+ if (!function->isFullyImplemented())
+ setFullyImplemented(false);
+ }
for (ASTPointer<ModifierDefinition> const& modifier: getFunctionModifiers())
modifier->checkTypeRequirements();
@@ -124,6 +130,28 @@ FunctionDefinition const* ContractDefinition::getFallbackFunction() const
return nullptr;
}
+void ContractDefinition::checkAbstractFunctions()
+{
+ map<string, bool> functions;
+
+ // Search from base to derived
+ for (ContractDefinition const* contract: boost::adaptors::reverse(getLinearizedBaseContracts()))
+ for (ASTPointer<FunctionDefinition> const& function: contract->getDefinedFunctions())
+ {
+ string const& name = function->getName();
+ if (!function->isFullyImplemented() && functions.count(name) && functions[name])
+ BOOST_THROW_EXCEPTION(function->createTypeError("Redeclaring an already implemented function as abstract"));
+ functions[name] = function->isFullyImplemented();
+ }
+
+ for (auto const& it: functions)
+ if (!it.second)
+ {
+ setFullyImplemented(false);
+ break;
+ }
+}
+
void ContractDefinition::checkIllegalOverrides() const
{
// TODO unify this at a later point. for this we need to put the constness and the access specifier
@@ -316,8 +344,8 @@ void FunctionDefinition::checkTypeRequirements()
modifier->checkTypeRequirements(isConstructor() ?
dynamic_cast<ContractDefinition const&>(*getScope()).getBaseContracts() :
vector<ASTPointer<InheritanceSpecifier>>());
-
- m_body->checkTypeRequirements();
+ if (m_body)
+ m_body->checkTypeRequirements();
}
string FunctionDefinition::externalSignature() const
@@ -649,6 +677,8 @@ void NewExpression::checkTypeRequirements()
m_contract = dynamic_cast<ContractDefinition const*>(m_contractName->getReferencedDeclaration());
if (!m_contract)
BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract."));
+ if (!m_contract->isFullyImplemented())
+ BOOST_THROW_EXCEPTION(m_contract->createTypeError("Trying to create an instance of an abstract contract."));
shared_ptr<ContractType const> contractType = make_shared<ContractType>(*m_contract);
TypePointers const& parameterTypes = contractType->getConstructorType()->getParameterTypes();
m_type = make_shared<FunctionType>(parameterTypes, TypePointers{contractType},