mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Type: Extract usingForDirectivesForType()
helper
This commit is contained in:
parent
edb4bfa398
commit
261e819df7
@ -48,6 +48,7 @@
|
||||
#include <range/v3/view/reverse.hpp>
|
||||
#include <range/v3/view/tail.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/filter.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <unordered_set>
|
||||
@ -337,7 +338,10 @@ Type const* Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
|
||||
return encodingType;
|
||||
}
|
||||
|
||||
MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope)
|
||||
namespace
|
||||
{
|
||||
|
||||
vector<UsingForDirective const*> usingForDirectivesForType(Type const& _type, ASTNode const& _scope)
|
||||
{
|
||||
vector<UsingForDirective const*> usingForDirectives;
|
||||
SourceUnit const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope);
|
||||
@ -362,6 +366,25 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
|
||||
if (auto refType = dynamic_cast<ReferenceType const*>(&_type))
|
||||
typeLocation = refType->location();
|
||||
|
||||
return usingForDirectives | ranges::views::filter([&](UsingForDirective const* _directive) -> bool {
|
||||
// Convert both types to pointers for comparison to see if the `using for` directive applies.
|
||||
// Note that at this point we don't yet know if the functions are actually usable with the type.
|
||||
// `_type` may not be convertible to the function parameter type.
|
||||
return
|
||||
!_directive->typeName() ||
|
||||
*TypeProvider::withLocationIfReference(typeLocation, &_type, true) ==
|
||||
*TypeProvider::withLocationIfReference(
|
||||
typeLocation,
|
||||
_directive->typeName()->annotation().type,
|
||||
true
|
||||
);
|
||||
}) | ranges::to<vector<UsingForDirective const*>>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope)
|
||||
{
|
||||
MemberList::MemberMap members;
|
||||
|
||||
set<pair<string, Declaration const*>> seenFunctions;
|
||||
@ -381,27 +404,11 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
|
||||
members.emplace_back(&_function, asBoundFunction, *_name);
|
||||
};
|
||||
|
||||
for (UsingForDirective const* ufd: usingForDirectives)
|
||||
{
|
||||
// Convert both types to pointers for comparison to see if the `using for`
|
||||
// directive applies.
|
||||
// Further down, we check more detailed for each function if `_type` is
|
||||
// convertible to the function parameter type.
|
||||
if (
|
||||
ufd->typeName() &&
|
||||
*TypeProvider::withLocationIfReference(typeLocation, &_type, true) !=
|
||||
*TypeProvider::withLocationIfReference(
|
||||
typeLocation,
|
||||
ufd->typeName()->annotation().type,
|
||||
true
|
||||
)
|
||||
)
|
||||
continue;
|
||||
|
||||
for (auto const& pathPointer: ufd->functionsOrLibrary())
|
||||
for (UsingForDirective const* ufd: usingForDirectivesForType(_type, _scope))
|
||||
for (auto const& identifierPath: ufd->functionsOrLibrary())
|
||||
{
|
||||
solAssert(pathPointer);
|
||||
Declaration const* declaration = pathPointer->annotation().referencedDeclaration;
|
||||
solAssert(identifierPath);
|
||||
Declaration const* declaration = identifierPath->annotation().referencedDeclaration;
|
||||
solAssert(declaration);
|
||||
|
||||
if (ContractDefinition const* library = dynamic_cast<ContractDefinition const*>(declaration))
|
||||
@ -417,10 +424,9 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
|
||||
else
|
||||
addFunction(
|
||||
dynamic_cast<FunctionDefinition const&>(*declaration),
|
||||
pathPointer->path().back()
|
||||
identifierPath->path().back()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user