Merge pull request #8618 from mijovic/nextConstructorRefactor

Refactoring nextConstructor by moving it from CompilerContext to ContractDefinition
This commit is contained in:
chriseth 2020-04-06 19:31:12 +02:00 committed by GitHub
commit 398c515982
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 40 deletions

View File

@ -217,6 +217,37 @@ ContractDefinitionAnnotation& ContractDefinition::annotation() const
return initAnnotation<ContractDefinitionAnnotation>(); return initAnnotation<ContractDefinitionAnnotation>();
} }
ContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const
{
auto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts;
auto it = find(hierarchy.begin(), hierarchy.end(), this);
solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy.");
++it;
if (it == hierarchy.end())
return nullptr;
else
{
solAssert(*it != this, "");
return *it;
}
}
FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const
{
ContractDefinition const* next = superContract(_mostDerivedContract);
if (next == nullptr)
return nullptr;
for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
if (c == next || next == nullptr)
{
if (c->constructor())
return c->constructor();
next = nullptr;
}
return nullptr;
}
TypeNameAnnotation& TypeName::annotation() const TypeNameAnnotation& TypeName::annotation() const
{ {
return initAnnotation<TypeNameAnnotation>(); return initAnnotation<TypeNameAnnotation>();

View File

@ -518,6 +518,10 @@ public:
bool abstract() const { return m_abstract; } bool abstract() const { return m_abstract; }
ContractDefinition const* superContract(ContractDefinition const& _mostDerivedContract) const;
/// @returns the next constructor in the inheritance hierarchy.
FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const;
private: private:
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts; std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
std::vector<ASTPointer<ASTNode>> m_subNodes; std::vector<ASTPointer<ASTNode>> m_subNodes;

View File

@ -269,29 +269,11 @@ evmasm::AssemblyItem CompilerContext::functionEntryLabelIfExists(Declaration con
FunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base) FunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base)
{ {
solAssert(m_mostDerivedContract, "No most derived contract set."); solAssert(m_mostDerivedContract, "No most derived contract set.");
ContractDefinition const* super = superContract(_base); ContractDefinition const* super = _base.superContract(mostDerivedContract());
solAssert(super, "Super contract not available."); solAssert(super, "Super contract not available.");
return _function.resolveVirtual(mostDerivedContract(), super); return _function.resolveVirtual(mostDerivedContract(), super);
} }
FunctionDefinition const* CompilerContext::nextConstructor(ContractDefinition const& _contract) const
{
ContractDefinition const* next = superContract(_contract);
if (next == nullptr)
return nullptr;
for (ContractDefinition const* c: m_mostDerivedContract->annotation().linearizedBaseContracts)
if (next != nullptr && next != c)
continue;
else
{
next = nullptr;
if (c->constructor())
return c->constructor();
}
return nullptr;
}
ContractDefinition const& CompilerContext::mostDerivedContract() const ContractDefinition const& CompilerContext::mostDerivedContract() const
{ {
solAssert(m_mostDerivedContract, "Most derived contract not set."); solAssert(m_mostDerivedContract, "Most derived contract not set.");
@ -536,21 +518,6 @@ LinkerObject const& CompilerContext::assembledObject() const
return object; return object;
} }
ContractDefinition const* CompilerContext::superContract(ContractDefinition const& _contract) const
{
auto const& hierarchy = mostDerivedContract().annotation().linearizedBaseContracts;
auto it = find(hierarchy.begin(), hierarchy.end(), &_contract);
solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy.");
++it;
if (it == hierarchy.end())
return nullptr;
else
{
solAssert(*it != &_contract, "");
return *it;
}
}
string CompilerContext::revertReasonIfDebug(string const& _message) string CompilerContext::revertReasonIfDebug(string const& _message)
{ {
return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message); return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message);

View File

@ -117,8 +117,6 @@ public:
/// @returns the function that overrides the given declaration from the most derived class just /// @returns the function that overrides the given declaration from the most derived class just
/// above _base in the current inheritance hierarchy. /// above _base in the current inheritance hierarchy.
FunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base); FunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base);
/// @returns the next constructor in the inheritance hierarchy.
FunctionDefinition const* nextConstructor(ContractDefinition const& _contract) const;
/// Sets the contract currently being compiled - the most derived one. /// Sets the contract currently being compiled - the most derived one.
void setMostDerivedContract(ContractDefinition const& _contract) { m_mostDerivedContract = &_contract; } void setMostDerivedContract(ContractDefinition const& _contract) { m_mostDerivedContract = &_contract; }
ContractDefinition const& mostDerivedContract() const; ContractDefinition const& mostDerivedContract() const;
@ -313,8 +311,6 @@ public:
RevertStrings revertStrings() const { return m_revertStrings; } RevertStrings revertStrings() const { return m_revertStrings; }
private: private:
/// @returns a pointer to the contract directly above the given contract.
ContractDefinition const* superContract(ContractDefinition const& _contract) const;
/// Updates source location set in the assembly. /// Updates source location set in the assembly.
void updateSourceLocation(); void updateSourceLocation();

View File

@ -159,7 +159,7 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c
if (FunctionDefinition const* constructor = _contract.constructor()) if (FunctionDefinition const* constructor = _contract.constructor())
appendConstructor(*constructor); appendConstructor(*constructor);
else if (auto c = m_context.nextConstructor(_contract)) else if (auto c = _contract.nextConstructor(m_context.mostDerivedContract()))
appendBaseConstructor(*c); appendBaseConstructor(*c);
else else
appendCallValueCheck(); appendCallValueCheck();
@ -596,7 +596,9 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
appendStackVariableInitialisation(*variable); appendStackVariableInitialisation(*variable);
if (_function.isConstructor()) if (_function.isConstructor())
if (auto c = m_context.nextConstructor(dynamic_cast<ContractDefinition const&>(*_function.scope()))) if (auto c = dynamic_cast<ContractDefinition const&>(*_function.scope()).nextConstructor(
m_context.mostDerivedContract()
))
appendBaseConstructor(*c); appendBaseConstructor(*c);
solAssert(m_returnTags.empty(), ""); solAssert(m_returnTags.empty(), "");