aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-30 00:51:57 +0800
committerchriseth <chris@ethereum.org>2018-11-30 23:30:19 +0800
commit57a62429c9d0be4b3a8a9cc98fa7eb46a6015165 (patch)
tree96ddfc01a0f6ffb4780bf96cd44d25de35d232ec
parent89cf6a5a38b02c3da1377279fcd98d690a58a978 (diff)
downloaddexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar.gz
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar.bz2
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar.lz
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar.xz
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.tar.zst
dexon-solidity-57a62429c9d0be4b3a8a9cc98fa7eb46a6015165.zip
Move abstract function check.
-rw-r--r--libsolidity/analysis/ContractLevelChecker.cpp45
-rw-r--r--libsolidity/analysis/ContractLevelChecker.h1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp45
-rw-r--r--libsolidity/analysis/TypeChecker.h1
4 files changed, 46 insertions, 46 deletions
diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp
index bf132d63..74ac665f 100644
--- a/libsolidity/analysis/ContractLevelChecker.cpp
+++ b/libsolidity/analysis/ContractLevelChecker.cpp
@@ -24,6 +24,8 @@
#include <liblangutil/ErrorReporter.h>
+#include <boost/range/adaptor/reversed.hpp>
+
using namespace std;
using namespace dev;
@@ -36,6 +38,7 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract)
checkContractDuplicateFunctions(_contract);
checkContractDuplicateEvents(_contract);
checkContractIllegalOverrides(_contract);
+ checkContractAbstractFunctions(_contract);
return Error::containsOnlyWarnings(m_errorReporter.errors());
}
@@ -203,3 +206,45 @@ void ContractLevelChecker::overrideError(FunctionDefinition const& function, Fun
);
}
+void ContractLevelChecker::checkContractAbstractFunctions(ContractDefinition const& _contract)
+{
+ // Mapping from name to function definition (exactly one per argument type equality class) and
+ // flag to indicate whether it is fully implemented.
+ using FunTypeAndFlag = std::pair<FunctionTypePointer, bool>;
+ map<string, vector<FunTypeAndFlag>> functions;
+
+ // Search from base to derived
+ for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
+ for (FunctionDefinition const* function: contract->definedFunctions())
+ {
+ // Take constructors out of overload hierarchy
+ if (function->isConstructor())
+ continue;
+ auto& overloads = functions[function->name()];
+ FunctionTypePointer funType = make_shared<FunctionType>(*function)->asCallableFunction(false);
+ auto it = find_if(overloads.begin(), overloads.end(), [&](FunTypeAndFlag const& _funAndFlag)
+ {
+ return funType->hasEqualParameterTypes(*_funAndFlag.first);
+ });
+ if (it == overloads.end())
+ overloads.push_back(make_pair(funType, function->isImplemented()));
+ else if (it->second)
+ {
+ if (!function->isImplemented())
+ m_errorReporter.typeError(function->location(), "Redeclaring an already implemented function as abstract");
+ }
+ else if (function->isImplemented())
+ it->second = true;
+ }
+
+ // Set to not fully implemented if at least one flag is false.
+ for (auto const& it: functions)
+ for (auto const& funAndFlag: it.second)
+ if (!funAndFlag.second)
+ {
+ FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(&funAndFlag.first->declaration());
+ solAssert(function, "");
+ _contract.annotation().unimplementedFunctions.push_back(function);
+ break;
+ }
+}
diff --git a/libsolidity/analysis/ContractLevelChecker.h b/libsolidity/analysis/ContractLevelChecker.h
index 400979c0..1746153b 100644
--- a/libsolidity/analysis/ContractLevelChecker.h
+++ b/libsolidity/analysis/ContractLevelChecker.h
@@ -63,6 +63,7 @@ private:
/// Also stores the direct super function in the AST annotations.
void checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super);
void overrideError(FunctionDefinition const& function, FunctionDefinition const& super, std::string message);
+ void checkContractAbstractFunctions(ContractDefinition const& _contract);
langutil::ErrorReporter& m_errorReporter;
};
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 07d32563..2b79e29b 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -35,7 +35,6 @@
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/join.hpp>
-#include <boost/range/adaptor/reversed.hpp>
#include <memory>
#include <vector>
@@ -96,7 +95,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
ASTNode::listAccept(_contract.definedStructs(), *this);
ASTNode::listAccept(_contract.baseContracts(), *this);
- checkContractAbstractFunctions(_contract);
checkContractBaseConstructorArguments(_contract);
FunctionDefinition const* function = _contract.constructor();
@@ -159,49 +157,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
return false;
}
-void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _contract)
-{
- // Mapping from name to function definition (exactly one per argument type equality class) and
- // flag to indicate whether it is fully implemented.
- using FunTypeAndFlag = std::pair<FunctionTypePointer, bool>;
- map<string, vector<FunTypeAndFlag>> functions;
-
- // Search from base to derived
- for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
- for (FunctionDefinition const* function: contract->definedFunctions())
- {
- // Take constructors out of overload hierarchy
- if (function->isConstructor())
- continue;
- auto& overloads = functions[function->name()];
- FunctionTypePointer funType = make_shared<FunctionType>(*function)->asCallableFunction(false);
- auto it = find_if(overloads.begin(), overloads.end(), [&](FunTypeAndFlag const& _funAndFlag)
- {
- return funType->hasEqualParameterTypes(*_funAndFlag.first);
- });
- if (it == overloads.end())
- overloads.push_back(make_pair(funType, function->isImplemented()));
- else if (it->second)
- {
- if (!function->isImplemented())
- m_errorReporter.typeError(function->location(), "Redeclaring an already implemented function as abstract");
- }
- else if (function->isImplemented())
- it->second = true;
- }
-
- // Set to not fully implemented if at least one flag is false.
- for (auto const& it: functions)
- for (auto const& funAndFlag: it.second)
- if (!funAndFlag.second)
- {
- FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(&funAndFlag.first->declaration());
- solAssert(function, "");
- _contract.annotation().unimplementedFunctions.push_back(function);
- break;
- }
-}
-
void TypeChecker::checkContractBaseConstructorArguments(ContractDefinition const& _contract)
{
vector<ContractDefinition const*> const& bases = _contract.annotation().linearizedBaseContracts;
diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h
index 7d718ff9..61eee386 100644
--- a/libsolidity/analysis/TypeChecker.h
+++ b/libsolidity/analysis/TypeChecker.h
@@ -66,7 +66,6 @@ public:
private:
bool visit(ContractDefinition const& _contract) override;
- void checkContractAbstractFunctions(ContractDefinition const& _contract);
void checkContractBaseConstructorArguments(ContractDefinition const& _contract);
void annotateBaseConstructorArguments(
ContractDefinition const& _currentContract,