mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Modifiers for constructors.
This commit is contained in:
parent
ccaa81fbe7
commit
35908c602b
@ -639,7 +639,6 @@ string IRGenerator::initStateVariables(ContractDefinition const& _contract)
|
|||||||
|
|
||||||
void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contract)
|
void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contract)
|
||||||
{
|
{
|
||||||
// TODO reset local variables somewhere here.
|
|
||||||
auto listAllParams = [&](
|
auto listAllParams = [&](
|
||||||
map<ContractDefinition const*, vector<string>> const& baseParams) -> vector<string>
|
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];
|
ContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i];
|
||||||
baseConstructorParams.erase(contract);
|
baseConstructorParams.erase(contract);
|
||||||
|
|
||||||
|
m_context.resetLocalVariables();
|
||||||
m_context.functionCollector().createFunction(IRNames::implicitConstructor(*contract), [&]() {
|
m_context.functionCollector().createFunction(IRNames::implicitConstructor(*contract), [&]() {
|
||||||
Whiskers t(R"(
|
Whiskers t(R"(
|
||||||
function <functionName>(<params><comma><baseParams>) {
|
function <functionName>(<params><comma><baseParams>) {
|
||||||
@ -667,16 +667,8 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
|
|||||||
)");
|
)");
|
||||||
vector<string> params;
|
vector<string> params;
|
||||||
if (contract->constructor())
|
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())
|
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
|
||||||
params += m_context.addLocalVariable(*varDecl).stackSlots();
|
params += m_context.addLocalVariable(*varDecl).stackSlots();
|
||||||
}
|
|
||||||
t("params", joinHumanReadable(params));
|
t("params", joinHumanReadable(params));
|
||||||
vector<string> baseParams = listAllParams(baseConstructorParams);
|
vector<string> baseParams = listAllParams(baseConstructorParams);
|
||||||
t("baseParams", joinHumanReadable(baseParams));
|
t("baseParams", joinHumanReadable(baseParams));
|
||||||
@ -695,7 +687,37 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
|
|||||||
else
|
else
|
||||||
t("hasNextConstructor", false);
|
t("hasNextConstructor", false);
|
||||||
t("initStateVariables", initStateVariables(*contract));
|
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();
|
return t.render();
|
||||||
});
|
});
|
||||||
|
@ -45,5 +45,7 @@ contract C is A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// getData() -> 0x4300
|
// getData() -> 0x4300
|
||||||
|
@ -22,6 +22,7 @@ contract C is A {
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// getData() -> 6
|
// getData() -> 6
|
||||||
|
Loading…
Reference in New Issue
Block a user