mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allowing abstract contracts constructor to have no args
- If a constructor is part of an abstract contract we can omit its arguments - IF a contract is abstract make sure to not create and/or request Assembly code about it since it's not compiled
This commit is contained in:
parent
6e5de4832d
commit
d997dc55d1
14
AST.cpp
14
AST.cpp
@ -281,7 +281,7 @@ void InheritanceSpecifier::checkTypeRequirements()
|
||||
ContractDefinition const* base = dynamic_cast<ContractDefinition const*>(m_baseName->getReferencedDeclaration());
|
||||
solAssert(base, "Base contract not available.");
|
||||
TypePointers parameterTypes = ContractType(*base).getConstructorType()->getParameterTypes();
|
||||
if (parameterTypes.size() != m_arguments.size())
|
||||
if (m_arguments.size() != 0 && parameterTypes.size() != m_arguments.size())
|
||||
BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for constructor call."));
|
||||
for (size_t i = 0; i < m_arguments.size(); ++i)
|
||||
if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]))
|
||||
@ -348,8 +348,8 @@ void FunctionDefinition::checkTypeRequirements()
|
||||
}
|
||||
for (ASTPointer<ModifierInvocation> const& modifier: m_functionModifiers)
|
||||
modifier->checkTypeRequirements(isConstructor() ?
|
||||
dynamic_cast<ContractDefinition const&>(*getScope()).getBaseContracts() :
|
||||
vector<ASTPointer<InheritanceSpecifier>>());
|
||||
dynamic_cast<ContractDefinition const&>(*getScope()).getLinearizedBaseContracts() :
|
||||
vector<ContractDefinition const*>());
|
||||
if (m_body)
|
||||
m_body->checkTypeRequirements();
|
||||
}
|
||||
@ -426,7 +426,7 @@ void ModifierDefinition::checkTypeRequirements()
|
||||
m_body->checkTypeRequirements();
|
||||
}
|
||||
|
||||
void ModifierInvocation::checkTypeRequirements(vector<ASTPointer<InheritanceSpecifier>> const& _bases)
|
||||
void ModifierInvocation::checkTypeRequirements(vector<ContractDefinition const*> const& _bases)
|
||||
{
|
||||
m_modifierName->checkTypeRequirements();
|
||||
for (ASTPointer<Expression> const& argument: m_arguments)
|
||||
@ -439,10 +439,10 @@ void ModifierInvocation::checkTypeRequirements(vector<ASTPointer<InheritanceSpec
|
||||
parameters = &modifier->getParameters();
|
||||
else
|
||||
// check parameters for Base constructors
|
||||
for (auto const& base: _bases)
|
||||
if (declaration == base->getName()->getReferencedDeclaration())
|
||||
for (auto const* base: _bases)
|
||||
if (declaration == base)
|
||||
{
|
||||
if (auto referencedConstructor = dynamic_cast<ContractDefinition const&>(*declaration).getConstructor())
|
||||
if (auto referencedConstructor = base->getConstructor())
|
||||
parameters = &referencedConstructor->getParameters();
|
||||
else
|
||||
parameters = &emptyParameterList;
|
||||
|
2
AST.h
2
AST.h
@ -566,7 +566,7 @@ public:
|
||||
std::vector<ASTPointer<Expression>> const& getArguments() const { return m_arguments; }
|
||||
|
||||
/// @param _bases is the list of base contracts for base constructor calls. For modifiers an empty vector should be passed.
|
||||
void checkTypeRequirements(std::vector<ASTPointer<InheritanceSpecifier>> const& _bases);
|
||||
void checkTypeRequirements(std::vector<ContractDefinition const*> const& _bases);
|
||||
|
||||
private:
|
||||
ASTPointer<Identifier> m_modifierName;
|
||||
|
@ -136,6 +136,7 @@ void Compiler::appendBaseConstructor(FunctionDefinition const& _constructor)
|
||||
FunctionType constructorType(_constructor);
|
||||
if (!constructorType.getParameterTypes().empty())
|
||||
{
|
||||
solAssert(m_baseArguments.count(&_constructor), "");
|
||||
std::vector<ASTPointer<Expression>> const* arguments = m_baseArguments[&_constructor];
|
||||
solAssert(arguments, "");
|
||||
for (unsigned i = 0; i < arguments->size(); ++i)
|
||||
|
@ -157,14 +157,16 @@ bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize)
|
||||
return getBytecode();
|
||||
}
|
||||
|
||||
eth::AssemblyItems const& CompilerStack::getAssemblyItems(string const& _contractName) const
|
||||
eth::AssemblyItems const* CompilerStack::getAssemblyItems(string const& _contractName) const
|
||||
{
|
||||
return getContract(_contractName).compiler->getAssemblyItems();
|
||||
Contract const& contract = getContract(_contractName);
|
||||
return contract.compiler ? &getContract(_contractName).compiler->getAssemblyItems() : nullptr;
|
||||
}
|
||||
|
||||
eth::AssemblyItems const& CompilerStack::getRuntimeAssemblyItems(string const& _contractName) const
|
||||
eth::AssemblyItems const* CompilerStack::getRuntimeAssemblyItems(string const& _contractName) const
|
||||
{
|
||||
return getContract(_contractName).compiler->getRuntimeAssemblyItems();
|
||||
Contract const& contract = getContract(_contractName);
|
||||
return contract.compiler ? &getContract(_contractName).compiler->getRuntimeAssemblyItems() : nullptr;
|
||||
}
|
||||
|
||||
bytes const& CompilerStack::getBytecode(string const& _contractName) const
|
||||
@ -184,7 +186,11 @@ dev::h256 CompilerStack::getContractCodeHash(string const& _contractName) const
|
||||
|
||||
void CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName, StringMap _sourceCodes) const
|
||||
{
|
||||
getContract(_contractName).compiler->streamAssembly(_outStream, _sourceCodes);
|
||||
Contract const& contract = getContract(_contractName);
|
||||
if (contract.compiler)
|
||||
getContract(_contractName).compiler->streamAssembly(_outStream, _sourceCodes);
|
||||
else
|
||||
_outStream << "Contract not fully implemented" << endl;
|
||||
}
|
||||
|
||||
string const& CompilerStack::getInterface(string const& _contractName) const
|
||||
|
@ -94,9 +94,9 @@ public:
|
||||
/// @returns the runtime bytecode for the contract, i.e. the code that is returned by the constructor.
|
||||
bytes const& getRuntimeBytecode(std::string const& _contractName = "") const;
|
||||
/// @returns normal contract assembly items
|
||||
eth::AssemblyItems const& getAssemblyItems(std::string const& _contractName = "") const;
|
||||
eth::AssemblyItems const* getAssemblyItems(std::string const& _contractName = "") const;
|
||||
/// @returns runtime contract assembly items
|
||||
eth::AssemblyItems const& getRuntimeAssemblyItems(std::string const& _contractName = "") const;
|
||||
eth::AssemblyItems const* getRuntimeAssemblyItems(std::string const& _contractName = "") const;
|
||||
/// @returns hash of the runtime bytecode for the contract, i.e. the code that is returned by the constructor.
|
||||
dev::h256 getContractCodeHash(std::string const& _contractName = "") const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user