Add back StructType::recursive()

This commit is contained in:
Mathias Baumann 2019-03-19 11:47:58 +01:00
parent 8e899a0d32
commit 7d809df91a
2 changed files with 17 additions and 5 deletions

View File

@ -2142,9 +2142,10 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
if (!_inLibrary && m_interfaceType.is_initialized()) if (!_inLibrary && m_interfaceType.is_initialized())
return *m_interfaceType; return *m_interfaceType;
bool recursion = false;
TypeResult result{TypePointer{}}; TypeResult result{TypePointer{}};
m_recursive = false;
auto visitor = [&]( auto visitor = [&](
StructDefinition const& _struct, StructDefinition const& _struct,
CycleDetector<StructDefinition>& _cycleDetector, CycleDetector<StructDefinition>& _cycleDetector,
@ -2175,7 +2176,7 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
_cycleDetector.run(innerStruct->structDefinition()) _cycleDetector.run(innerStruct->structDefinition())
) )
{ {
recursion = true; m_recursive = true;
if (_inLibrary && location() == DataLocation::Storage) if (_inLibrary && location() == DataLocation::Storage)
continue; continue;
else else
@ -2195,7 +2196,7 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
} }
}; };
recursion = recursion || (CycleDetector<StructDefinition>(visitor).run(structDefinition()) != nullptr); m_recursive = m_recursive.get() || (CycleDetector<StructDefinition>(visitor).run(structDefinition()) != nullptr);
std::string const recursiveErrMsg = "Recursive type not allowed for public or external contract functions."; std::string const recursiveErrMsg = "Recursive type not allowed for public or external contract functions.";
@ -2208,13 +2209,13 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
else else
m_interfaceType_library = copyForLocation(DataLocation::Memory, true); m_interfaceType_library = copyForLocation(DataLocation::Memory, true);
if (recursion) if (m_recursive.get())
m_interfaceType = TypeResult::err(recursiveErrMsg); m_interfaceType = TypeResult::err(recursiveErrMsg);
return *m_interfaceType_library; return *m_interfaceType_library;
} }
if (recursion) if (m_recursive.get())
m_interfaceType = TypeResult::err(recursiveErrMsg); m_interfaceType = TypeResult::err(recursiveErrMsg);
else if (!result.message().empty()) else if (!result.message().empty())
m_interfaceType = result; m_interfaceType = result;

View File

@ -844,6 +844,16 @@ public:
} }
TypeResult interfaceType(bool _inLibrary) const override; TypeResult interfaceType(bool _inLibrary) const override;
bool recursive() const
{
if (m_recursive.is_initialized())
return m_recursive.get();
interfaceType(false);
return m_recursive.get();
}
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override; TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
std::string canonicalName() const override; std::string canonicalName() const override;
@ -868,6 +878,7 @@ private:
// Caches for interfaceType(bool) // Caches for interfaceType(bool)
mutable boost::optional<TypeResult> m_interfaceType; mutable boost::optional<TypeResult> m_interfaceType;
mutable boost::optional<TypeResult> m_interfaceType_library; mutable boost::optional<TypeResult> m_interfaceType_library;
mutable boost::optional<bool> m_recursive;
}; };
/** /**