mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implements constructor code for state variables.
This commit is contained in:
committed by
chriseth
parent
742b4271fd
commit
235638b3fc
@@ -39,6 +39,9 @@
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
@@ -177,19 +180,45 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
|
||||
|
||||
string IRGenerator::constructorCode(ContractDefinition const& _contract)
|
||||
{
|
||||
// TODO initialize state variables in base to derived order.
|
||||
// TODO base constructors
|
||||
// TODO callValueCheck if there is no constructor.
|
||||
if (FunctionDefinition const* constructor = _contract.constructor())
|
||||
// Initialization of state variables in base-to-derived order.
|
||||
solAssert(!_contract.isLibrary(), "Tried to initialize state variables of library.");
|
||||
|
||||
using boost::adaptors::reverse;
|
||||
|
||||
ostringstream out;
|
||||
|
||||
FunctionDefinition const* constructor = _contract.constructor();
|
||||
if (constructor && !constructor->isPayable())
|
||||
out << callValueCheck();
|
||||
|
||||
for (ContractDefinition const* contract: reverse(_contract.annotation().linearizedBaseContracts))
|
||||
{
|
||||
string out;
|
||||
if (!constructor->isPayable())
|
||||
out = callValueCheck();
|
||||
solUnimplementedAssert(constructor->parameters().empty(), "");
|
||||
return move(out) + m_context.functionName(*constructor) + "()\n";
|
||||
out <<
|
||||
"\n// Begin state variable initialization for contract \"" <<
|
||||
contract->name() <<
|
||||
"\" (" <<
|
||||
contract->stateVariables().size() <<
|
||||
" variables)\n";
|
||||
|
||||
IRGeneratorForStatements generator{m_context, m_utils};
|
||||
for (VariableDeclaration const* variable: contract->stateVariables())
|
||||
if (!variable->isConstant())
|
||||
generator.initializeStateVar(*variable);
|
||||
out << generator.code();
|
||||
|
||||
out << "// End state variable initialization for contract \"" << contract->name() << "\".\n";
|
||||
}
|
||||
|
||||
return {};
|
||||
if (constructor)
|
||||
{
|
||||
solUnimplementedAssert(constructor->parameters().empty(), "");
|
||||
|
||||
// TODO base constructors
|
||||
|
||||
out << m_context.functionName(*constructor) + "()\n";
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
string IRGenerator::deployCode(ContractDefinition const& _contract)
|
||||
|
||||
@@ -133,6 +133,21 @@ string IRGeneratorForStatements::code() const
|
||||
return m_code.str();
|
||||
}
|
||||
|
||||
void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
solAssert(m_context.isStateVariable(_varDecl), "Must be a state variable.");
|
||||
solAssert(!_varDecl.isConstant(), "");
|
||||
if (_varDecl.value())
|
||||
{
|
||||
_varDecl.value()->accept(*this);
|
||||
string value = m_context.newYulVariable();
|
||||
Type const& varType = *_varDecl.type();
|
||||
|
||||
m_code << "let " << value << " := " << expressionAsType(*_varDecl.value(), varType) << "\n";
|
||||
m_code << IRStorageItem{m_context, _varDecl}.storeValue(value, varType);
|
||||
}
|
||||
}
|
||||
|
||||
void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement)
|
||||
{
|
||||
for (auto const& decl: _varDeclStatement.declarations())
|
||||
|
||||
@@ -45,6 +45,9 @@ public:
|
||||
|
||||
std::string code() const;
|
||||
|
||||
/// Generates code to initialize the given state variable.
|
||||
void initializeStateVar(VariableDeclaration const& _varDecl);
|
||||
|
||||
void endVisit(VariableDeclarationStatement const& _variableDeclaration) override;
|
||||
bool visit(Assignment const& _assignment) override;
|
||||
bool visit(TupleExpression const& _tuple) override;
|
||||
|
||||
Reference in New Issue
Block a user