Using for with global binding.

This commit is contained in:
chriseth
2022-03-14 17:39:14 +01:00
parent 7f360e61fc
commit 9188519f11
26 changed files with 307 additions and 6 deletions
+13 -2
View File
@@ -641,6 +641,10 @@ private:
* For version 3, T has to be implicitly convertible to the first parameter type of
* all functions, and this is checked at the point of the using statement. For versions 1 and
* 2, this check is only done when a function is called.
*
* Finally, `using {f1, f2, ..., fn} for T global` is also valid at file level, as long as T is
* a user-defined type defined in the same file at file level. In this case, the methods are
* attached to all objects of that type regardless of scope.
*/
class UsingForDirective: public ASTNode
{
@@ -650,9 +654,14 @@ public:
SourceLocation const& _location,
std::vector<ASTPointer<IdentifierPath>> _functions,
bool _usesBraces,
ASTPointer<TypeName> _typeName
ASTPointer<TypeName> _typeName,
bool _global
):
ASTNode(_id, _location), m_functions(_functions), m_usesBraces(_usesBraces), m_typeName(std::move(_typeName))
ASTNode(_id, _location),
m_functions(_functions),
m_usesBraces(_usesBraces),
m_typeName(std::move(_typeName)),
m_global{_global}
{
}
@@ -665,12 +674,14 @@ public:
/// @returns a list of functions or the single library.
std::vector<ASTPointer<IdentifierPath>> const& functionsOrLibrary() const { return m_functions; }
bool usesBraces() const { return m_usesBraces; }
bool global() const { return m_global; }
private:
/// Either the single library or a list of functions.
std::vector<ASTPointer<IdentifierPath>> m_functions;
bool m_usesBraces;
ASTPointer<TypeName> m_typeName;
bool m_global = false;
};
class StructDefinition: public Declaration, public ScopeOpener
+1
View File
@@ -328,6 +328,7 @@ bool ASTJsonConverter::visit(UsingForDirective const& _node)
}
else
attributes.emplace_back("libraryName", toJson(*_node.functionsOrLibrary().front()));
attributes.emplace_back("global", _node.global());
setJsonNode(_node, "UsingForDirective", move(attributes));
+2 -1
View File
@@ -359,7 +359,8 @@ ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Val
_node,
move(functions),
!_node.isMember("libraryName"),
_node["typeName"].isNull() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"])
_node["typeName"].isNull() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"]),
memberAsBool(_node, "global")
);
}
+7
View File
@@ -342,6 +342,13 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
solAssert(sourceUnit, "");
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes());
if (Declaration const* typeDefinition = _type.typeDefinition())
if (auto const* sourceUnit = dynamic_cast<SourceUnit const*>(typeDefinition->scope()))
for (auto usingFor: ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes()))
// We do not yet compare the type name because of normalization.
if (usingFor->global() && usingFor->typeName())
usingForDirectives.emplace_back(usingFor);
// Normalise data location of type.
DataLocation typeLocation = DataLocation::Storage;
if (auto refType = dynamic_cast<ReferenceType const*>(&_type))