mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Replace isFullyImplemented with unimplementedFunctions in ASTAnnotations
This commit is contained in:
parent
dc0f85c4fb
commit
c835bcec62
@ -113,7 +113,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function->isImplemented())
|
if (!function->isImplemented())
|
||||||
_contract.annotation().isFullyImplemented = false;
|
_contract.annotation().unimplementedFunctions.push_back(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& n: _contract.subNodes())
|
for (auto const& n: _contract.subNodes())
|
||||||
@ -188,7 +188,6 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
|
|||||||
using FunTypeAndFlag = std::pair<FunctionTypePointer, bool>;
|
using FunTypeAndFlag = std::pair<FunctionTypePointer, bool>;
|
||||||
map<string, vector<FunTypeAndFlag>> functions;
|
map<string, vector<FunTypeAndFlag>> functions;
|
||||||
|
|
||||||
bool allBaseConstructorsImplemented = true;
|
|
||||||
// Search from base to derived
|
// Search from base to derived
|
||||||
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
|
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
|
||||||
for (FunctionDefinition const* function: contract->definedFunctions())
|
for (FunctionDefinition const* function: contract->definedFunctions())
|
||||||
@ -199,7 +198,7 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
|
|||||||
if (!function->isImplemented())
|
if (!function->isImplemented())
|
||||||
// Base contract's constructor is not fully implemented, no way to get
|
// Base contract's constructor is not fully implemented, no way to get
|
||||||
// out of this.
|
// out of this.
|
||||||
allBaseConstructorsImplemented = false;
|
_contract.annotation().unimplementedFunctions.push_back(function);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto& overloads = functions[function->name()];
|
auto& overloads = functions[function->name()];
|
||||||
@ -219,16 +218,15 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
|
|||||||
it->second = true;
|
it->second = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allBaseConstructorsImplemented)
|
|
||||||
_contract.annotation().isFullyImplemented = false;
|
|
||||||
|
|
||||||
// Set to not fully implemented if at least one flag is false.
|
// Set to not fully implemented if at least one flag is false.
|
||||||
for (auto const& it: functions)
|
for (auto const& it: functions)
|
||||||
for (auto const& funAndFlag: it.second)
|
for (auto const& funAndFlag: it.second)
|
||||||
if (!funAndFlag.second)
|
if (!funAndFlag.second)
|
||||||
{
|
{
|
||||||
_contract.annotation().isFullyImplemented = false;
|
FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(&funAndFlag.first->declaration());
|
||||||
return;
|
solAssert(function, "");
|
||||||
|
_contract.annotation().unimplementedFunctions.push_back(function);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +264,8 @@ void TypeChecker::checkContractAbstractConstructors(ContractDefinition const& _c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!argumentsNeeded.empty())
|
if (!argumentsNeeded.empty())
|
||||||
_contract.annotation().isFullyImplemented = false;
|
for (ContractDefinition const* contract: argumentsNeeded)
|
||||||
|
_contract.annotation().unimplementedFunctions.push_back(contract->constructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contract)
|
void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contract)
|
||||||
@ -1523,7 +1522,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
|
|||||||
|
|
||||||
if (!contract)
|
if (!contract)
|
||||||
m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract.");
|
m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract.");
|
||||||
if (!contract->annotation().isFullyImplemented)
|
if (!contract->annotation().unimplementedFunctions.empty())
|
||||||
m_errorReporter.typeError(_newExpression.location(), "Trying to create an instance of an abstract contract.");
|
m_errorReporter.typeError(_newExpression.location(), "Trying to create an instance of an abstract contract.");
|
||||||
if (!contract->constructorIsPublic())
|
if (!contract->constructorIsPublic())
|
||||||
m_errorReporter.typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly.");
|
m_errorReporter.typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly.");
|
||||||
|
@ -79,8 +79,9 @@ struct TypeDeclarationAnnotation: ASTAnnotation
|
|||||||
|
|
||||||
struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnotation
|
struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnotation
|
||||||
{
|
{
|
||||||
/// Whether all functions are implemented.
|
/// List of functions without a body. Can also contain functions from base classes,
|
||||||
bool isFullyImplemented = true;
|
/// especially constructors.
|
||||||
|
std::vector<FunctionDefinition const*> unimplementedFunctions;
|
||||||
/// List of all (direct and indirect) base contracts in order from derived to
|
/// List of all (direct and indirect) base contracts in order from derived to
|
||||||
/// base, including the contract itself.
|
/// base, including the contract itself.
|
||||||
std::vector<ContractDefinition const*> linearizedBaseContracts;
|
std::vector<ContractDefinition const*> linearizedBaseContracts;
|
||||||
|
@ -253,7 +253,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node)
|
|||||||
make_pair("name", _node.name()),
|
make_pair("name", _node.name()),
|
||||||
make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue),
|
make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue),
|
||||||
make_pair("contractKind", contractKind(_node.contractKind())),
|
make_pair("contractKind", contractKind(_node.contractKind())),
|
||||||
make_pair("fullyImplemented", _node.annotation().isFullyImplemented),
|
make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()),
|
||||||
make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)),
|
make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)),
|
||||||
make_pair("baseContracts", toJson(_node.baseContracts())),
|
make_pair("baseContracts", toJson(_node.baseContracts())),
|
||||||
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies)),
|
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies)),
|
||||||
|
@ -639,7 +639,7 @@ void CompilerStack::compileContract(
|
|||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
_compiledContracts.count(&_contract) ||
|
_compiledContracts.count(&_contract) ||
|
||||||
!_contract.annotation().isFullyImplemented ||
|
!_contract.annotation().unimplementedFunctions.empty() ||
|
||||||
!_contract.constructorIsPublic()
|
!_contract.constructorIsPublic()
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user