Modifiers for constructors.

This commit is contained in:
chriseth 2020-12-02 18:00:04 +01:00
parent ccaa81fbe7
commit 35908c602b
3 changed files with 36 additions and 11 deletions

View File

@ -639,7 +639,6 @@ string IRGenerator::initStateVariables(ContractDefinition const& _contract)
void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contract)
{
// TODO reset local variables somewhere here.
auto listAllParams = [&](
map<ContractDefinition const*, vector<string>> const& baseParams) -> vector<string>
{
@ -656,6 +655,7 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
ContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i];
baseConstructorParams.erase(contract);
m_context.resetLocalVariables();
m_context.functionCollector().createFunction(IRNames::implicitConstructor(*contract), [&]() {
Whiskers t(R"(
function <functionName>(<params><comma><baseParams>) {
@ -667,16 +667,8 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
)");
vector<string> params;
if (contract->constructor())
{
for (auto const& modifierInvocation: contract->constructor()->modifiers())
// This can be ContractDefinition too for super arguments. That is supported.
solUnimplementedAssert(
!dynamic_cast<ModifierDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration),
"Modifiers not implemented yet."
);
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
}
t("params", joinHumanReadable(params));
vector<string> baseParams = listAllParams(baseConstructorParams);
t("baseParams", joinHumanReadable(baseParams));
@ -695,7 +687,37 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
else
t("hasNextConstructor", false);
t("initStateVariables", initStateVariables(*contract));
t("userDefinedConstructorBody", contract->constructor() ? generate(contract->constructor()->body()) : "");
string body;
if (FunctionDefinition const* constructor = contract->constructor())
{
vector<ModifierInvocation*> realModifiers;
for (auto const& modifierInvocation: constructor->modifiers())
// Filter out the base constructor calls
if (dynamic_cast<ModifierDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration))
realModifiers.emplace_back(modifierInvocation.get());
if (realModifiers.empty())
body = generate(constructor->body());
else
{
for (size_t i = 0; i < realModifiers.size(); ++i)
{
ModifierInvocation const& modifier = *realModifiers.at(i);
string next =
i + 1 < realModifiers.size() ?
IRNames::modifierInvocation(*realModifiers.at(i + 1)) :
IRNames::functionWithModifierInner(*constructor);
generateModifier(modifier, *constructor, next);
}
body =
IRNames::modifierInvocation(*constructor->modifiers().at(0)) +
"(" +
joinHumanReadable(params) +
")";
// Now generate the actual inner function.
generateFunctionWithModifierInner(*constructor);
}
}
t("userDefinedConstructorBody", move(body));
return t.render();
});

View File

@ -45,5 +45,7 @@ contract C is A {
}
}
// ====
// compileViaYul: also
// ----
// getData() -> 0x4300

View File

@ -22,6 +22,7 @@ contract C is A {
_;
}
}
// ====
// compileViaYul: also
// ----
// getData() -> 6