Browse Source

Fixing detection of abstract contract

cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
cad916a00d
  1. 41
      libsolidity/AST.cpp

41
libsolidity/AST.cpp

@ -155,45 +155,40 @@ void ContractDefinition::checkAbstractFunctions()
void ContractDefinition::checkAbstractConstructors() void ContractDefinition::checkAbstractConstructors()
{ {
set<FunctionDefinition const*> argumentsNeeded; set<ContractDefinition const*> argumentsNeeded;
set<FunctionDefinition const*> argumentsProvided;
// check that we get arguments for all base constructors that need it. // check that we get arguments for all base constructors that need it.
// If not mark the contract as abstract (not fully implemented) // If not mark the contract as abstract (not fully implemented)
vector<ContractDefinition const*> const& bases = getLinearizedBaseContracts(); vector<ContractDefinition const*> const& bases = getLinearizedBaseContracts();
for (ContractDefinition const* contract: bases)
if (FunctionDefinition const* constructor = contract->getConstructor())
if (contract != this && !constructor->getParameters().empty())
argumentsNeeded.insert(contract);
for (ContractDefinition const* contract: bases) for (ContractDefinition const* contract: bases)
{ {
FunctionDefinition const* constructor = contract->getConstructor(); if (FunctionDefinition const* constructor = contract->getConstructor())
if (constructor)
{
if (!constructor->getParameters().empty())
argumentsNeeded.insert(constructor);
for (auto const& modifier: constructor->getModifiers()) for (auto const& modifier: constructor->getModifiers())
{ {
auto baseContract = dynamic_cast<ContractDefinition const*>( auto baseContract = dynamic_cast<ContractDefinition const*>(
modifier->getName()->getReferencedDeclaration()); modifier->getName()->getReferencedDeclaration()
);
if (baseContract) if (baseContract)
{ argumentsNeeded.erase(baseContract);
FunctionDefinition const* baseConstructor = baseContract->getConstructor();
if (argumentsNeeded.count(baseConstructor) == 1)
argumentsProvided.insert(baseConstructor);
}
} }
}
for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts()) for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
{ {
ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>( auto baseContract = dynamic_cast<ContractDefinition const*>(
base->getName()->getReferencedDeclaration()); base->getName()->getReferencedDeclaration()
);
solAssert(baseContract, ""); solAssert(baseContract, "");
FunctionDefinition const* baseConstructor = baseContract->getConstructor(); if (!base->getArguments().empty())
if (argumentsNeeded.count(baseConstructor) == 1) argumentsNeeded.erase(baseContract);
argumentsProvided.insert(baseConstructor);
} }
} }
// add this contract's constructor to the provided too if (!argumentsNeeded.empty())
if (getConstructor() && !getConstructor()->getParameters().empty())
argumentsProvided.insert(getConstructor());
if (argumentsProvided != argumentsNeeded)
setFullyImplemented(false); setFullyImplemented(false);
} }

Loading…
Cancel
Save