Skip to content

Commit 261e819

Browse files
chrisethcameel
authored andcommitted
Type: Extract usingForDirectivesForType() helper
1 parent edb4bfa commit 261e819

File tree

1 file changed

+29
-23
lines changed

1 file changed

+29
-23
lines changed

libsolidity/ast/Types.cpp

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <range/v3/view/reverse.hpp>
4949
#include <range/v3/view/tail.hpp>
5050
#include <range/v3/view/transform.hpp>
51+
#include <range/v3/view/filter.hpp>
5152

5253
#include <limits>
5354
#include <unordered_set>
@@ -337,7 +338,10 @@ Type const* Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
337338
return encodingType;
338339
}
339340

340-
MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope)
341+
namespace
342+
{
343+
344+
vector<UsingForDirective const*> usingForDirectivesForType(Type const& _type, ASTNode const& _scope)
341345
{
342346
vector<UsingForDirective const*> usingForDirectives;
343347
SourceUnit const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope);
@@ -362,6 +366,25 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
362366
if (auto refType = dynamic_cast<ReferenceType const*>(&_type))
363367
typeLocation = refType->location();
364368

369+
return usingForDirectives | ranges::views::filter([&](UsingForDirective const* _directive) -> bool {
370+
// Convert both types to pointers for comparison to see if the `using for` directive applies.
371+
// Note that at this point we don't yet know if the functions are actually usable with the type.
372+
// `_type` may not be convertible to the function parameter type.
373+
return
374+
!_directive->typeName() ||
375+
*TypeProvider::withLocationIfReference(typeLocation, &_type, true) ==
376+
*TypeProvider::withLocationIfReference(
377+
typeLocation,
378+
_directive->typeName()->annotation().type,
379+
true
380+
);
381+
}) | ranges::to<vector<UsingForDirective const*>>;
382+
}
383+
384+
}
385+
386+
MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope)
387+
{
365388
MemberList::MemberMap members;
366389

367390
set<pair<string, Declaration const*>> seenFunctions;
@@ -381,27 +404,11 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
381404
members.emplace_back(&_function, asBoundFunction, *_name);
382405
};
383406

384-
for (UsingForDirective const* ufd: usingForDirectives)
385-
{
386-
// Convert both types to pointers for comparison to see if the `using for`
387-
// directive applies.
388-
// Further down, we check more detailed for each function if `_type` is
389-
// convertible to the function parameter type.
390-
if (
391-
ufd->typeName() &&
392-
*TypeProvider::withLocationIfReference(typeLocation, &_type, true) !=
393-
*TypeProvider::withLocationIfReference(
394-
typeLocation,
395-
ufd->typeName()->annotation().type,
396-
true
397-
)
398-
)
399-
continue;
400-
401-
for (auto const& pathPointer: ufd->functionsOrLibrary())
407+
for (UsingForDirective const* ufd: usingForDirectivesForType(_type, _scope))
408+
for (auto const& identifierPath: ufd->functionsOrLibrary())
402409
{
403-
solAssert(pathPointer);
404-
Declaration const* declaration = pathPointer->annotation().referencedDeclaration;
410+
solAssert(identifierPath);
411+
Declaration const* declaration = identifierPath->annotation().referencedDeclaration;
405412
solAssert(declaration);
406413

407414
if (ContractDefinition const* library = dynamic_cast<ContractDefinition const*>(declaration))
@@ -417,10 +424,9 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
417424
else
418425
addFunction(
419426
dynamic_cast<FunctionDefinition const&>(*declaration),
420-
pathPointer->path().back()
427+
identifierPath->path().back()
421428
);
422429
}
423-
}
424430

425431
return members;
426432
}

0 commit comments

Comments
 (0)