diff options
author | Lefteris Karapetsas <lefteris@refu.co> | 2015-04-02 22:56:12 +0800 |
---|---|---|
committer | Lefteris Karapetsas <lefteris@refu.co> | 2015-04-17 21:27:31 +0800 |
commit | beba2705ba2fd9f87bf76f439c4a99cec0f6a06d (patch) | |
tree | 4e68520e7aec24ea1ff1d09d028feccc84705850 /AST.cpp | |
parent | d997dc55d154c93af01175d880734b9e737d34ca (diff) | |
download | dexon-solidity-beba2705ba2fd9f87bf76f439c4a99cec0f6a06d.tar.gz dexon-solidity-beba2705ba2fd9f87bf76f439c4a99cec0f6a06d.tar.zst dexon-solidity-beba2705ba2fd9f87bf76f439c4a99cec0f6a06d.zip |
Check all constructors in inheritance chain get args
- Also add a missing override in a function of EnumValue
Diffstat (limited to 'AST.cpp')
-rw-r--r-- | AST.cpp | 42 |
1 files changed, 42 insertions, 0 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 |