diff options
-rw-r--r-- | AST.cpp | 42 | ||||
-rw-r--r-- | AST.h | 3 |
2 files changed, 44 insertions, 1 deletions
@@ -54,6 +54,7 @@ void ContractDefinition::checkTypeRequirements() checkIllegalOverrides(); checkAbstractFunctions(); + checkAbstractConstructors(); FunctionDefinition const* constructor = getConstructor(); if (constructor && !constructor->getReturnParameters().empty()) @@ -152,6 +153,47 @@ void ContractDefinition::checkAbstractFunctions() } } +void ContractDefinition::checkAbstractConstructors() +{ + set<FunctionDefinition const*> argumentsNeeded; + set<FunctionDefinition const*> argumentsProvided; + // check that we get arguments for all base constructors that need it. + // If not mark the contract as abstract (not fully implemented) + vector<ContractDefinition const*> const& bases = getLinearizedBaseContracts(); + for (ContractDefinition const* contract: bases) + { + FunctionDefinition const* constructor = contract->getConstructor(); + if (constructor) + { + if (!constructor->getParameters().empty()) + argumentsProvided.insert(constructor); + for (auto const& modifier: constructor->getModifiers()) + { + auto baseContract = dynamic_cast<ContractDefinition const*>( + modifier->getName()->getReferencedDeclaration()); + if (baseContract) + { + FunctionDefinition const* baseConstructor = baseContract->getConstructor(); + if (argumentsProvided.count(baseConstructor) == 1) + argumentsNeeded.insert(baseConstructor); + } + } + } + + for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts()) + { + ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>( + base->getName()->getReferencedDeclaration()); + solAssert(baseContract, ""); + FunctionDefinition const* baseConstructor = baseContract->getConstructor(); + if (argumentsProvided.count(baseConstructor) == 1) + argumentsNeeded.insert(baseConstructor); + } + } + if (argumentsProvided != argumentsNeeded) + setFullyImplemented(false); +} + void ContractDefinition::checkIllegalOverrides() const { // TODO unify this at a later point. for this we need to put the constness and the access specifier @@ -284,6 +284,7 @@ public: private: void checkIllegalOverrides() const; void checkAbstractFunctions(); + void checkAbstractConstructors(); std::vector<std::pair<FixedHash<4>, FunctionTypePointer>> const& getInterfaceFunctionList() const; @@ -376,7 +377,7 @@ class EnumValue: public Declaration virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - TypePointer getType(ContractDefinition const* = nullptr) const; + TypePointer getType(ContractDefinition const* = nullptr) const override; }; /** |