Change type of super to TypeType

This commit is contained in:
hrkrshnn
2020-11-10 15:38:21 +01:00
parent da92fe548e
commit 9eafa1fa1a
6 changed files with 190 additions and 151 deletions
@@ -884,17 +884,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
}
else
{
ContractType const* type = dynamic_cast<ContractType const*>(memberAccess->expression().annotation().type);
if (type && type->isSuper())
else if (auto typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
if (
auto contractType = dynamic_cast<ContractType const*>(typeType->actualType());
contractType->isSuper()
)
{
ContractDefinition const* super = type->contractDefinition().superContract(m_context.mostDerivedContract());
ContractDefinition const* super = contractType->contractDefinition().superContract(m_context.mostDerivedContract());
solAssert(super, "Super contract not available.");
solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Super, "");
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract(), super);
}
}
solAssert(functionDef && functionDef->isImplemented(), "");
}
@@ -1527,19 +1527,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
{
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
if (type.isSuper())
{
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
ContractDefinition const* super = type.contractDefinition().superContract(m_context.mostDerivedContract());
solAssert(super, "Super contract not available.");
FunctionDefinition const& resolvedFunctionDef = dynamic_cast<FunctionDefinition const&>(
*_memberAccess.annotation().referencedDeclaration
).resolveVirtual(m_context.mostDerivedContract(), super);
solAssert(false, "");
define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n";
solAssert(resolvedFunctionDef.functionType(true), "");
solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, "");
m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef);
}
// ordinary contract type
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
{
@@ -1649,7 +1638,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
else if (member == "creationCode" || member == "runtimeCode")
{
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
solAssert(!contractType.isSuper(), "");
ContractDefinition const& contract = contractType.contractDefinition();
m_context.subObjectsCreated().insert(&contract);
m_code << Whiskers(R"(
let <size> := datasize("<objectName>")
@@ -1669,7 +1660,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
else if (member == "interfaceId")
{
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
solAssert(!contractType.isSuper(), "");
ContractDefinition const& contract = contractType.contractDefinition();
define(_memberAccess) << formatNumber(u256{contract.interfaceId()} << (256 - 32)) << "\n";
}
else if (member == "min" || member == "max")
@@ -1790,8 +1783,24 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
if (actualType.category() == Type::Category::Contract)
{
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
handleVariableReference(*variable, _memberAccess);
ContractType const& contractType = dynamic_cast<ContractType const&>(actualType);
if (contractType.isSuper())
{
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
ContractDefinition const* super = contractType.contractDefinition().superContract(m_context.mostDerivedContract());
solAssert(super, "Super contract not available.");
FunctionDefinition const& resolvedFunctionDef =
dynamic_cast<FunctionDefinition const&>(
*_memberAccess.annotation().referencedDeclaration
).resolveVirtual(m_context.mostDerivedContract(), super);
define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n";
solAssert(resolvedFunctionDef.functionType(true), "");
solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, "");
m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef);
}
else if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
handleVariableReference(*variable, _memberAccess);
else if (memberFunctionType)
{
switch (memberFunctionType->kind())
@@ -1812,7 +1821,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration),
"Event not found"
);
// the call will do the resolving
// the call will do the resolving
break;
case FunctionType::Kind::DelegateCall:
define(IRVariable(_memberAccess).part("address"), _memberAccess.expression());
@@ -1835,7 +1844,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
}
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))
{
// no-op
// no-op
}
else
// The old code generator had a generic "else" case here
@@ -2095,18 +2104,20 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
switch (magicVar->type()->category())
{
case Type::Category::Contract:
if (dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
solAssert(_identifier.name() == "super", "");
else
{
solAssert(_identifier.name() == "this", "");
define(_identifier) << "address()\n";
}
solAssert(_identifier.name() == "this", "");
define(_identifier) << "address()\n";
break;
case Type::Category::Integer:
solAssert(_identifier.name() == "now", "");
define(_identifier) << "timestamp()\n";
break;
case Type::Category::TypeType:
{
auto typeType = dynamic_cast<TypeType const*>(magicVar->type());
if (auto contractType = dynamic_cast<ContractType const*>(typeType->actualType()))
solAssert(!contractType->isSuper() || _identifier.name() == "super", "");
break;
}
default:
break;
}