17
17
18
18
#include " NameLookupImpl.h"
19
19
#include " swift/AST/ASTContext.h"
20
+ #include " swift/AST/GenericSignature.h"
20
21
#include " swift/AST/GenericSignatureBuilder.h"
21
22
#include " swift/AST/Initializer.h"
22
23
#include " swift/AST/LazyResolver.h"
23
24
#include " swift/AST/NameLookup.h"
24
25
#include " swift/AST/ProtocolConformance.h"
25
- #include " swift/AST/SubstitutionMap.h"
26
26
#include " swift/Basic/SourceManager.h"
27
27
#include " swift/Basic/STLExtras.h"
28
28
#include " swift/Sema/IDETypeChecking.h"
@@ -113,7 +113,7 @@ struct LookupState {
113
113
return Result;
114
114
}
115
115
};
116
- } // unnamed namespace
116
+ } // end anonymous namespace
117
117
118
118
static bool areTypeDeclsVisibleInLookupMode (LookupState LS) {
119
119
// Nested type declarations can be accessed only with unqualified lookup or
@@ -473,19 +473,107 @@ lookupVisibleMemberDeclsImpl(Type BaseTy, VisibleDeclConsumer &Consumer,
473
473
GenericSignatureBuilder *GSB,
474
474
VisitedSet &Visited);
475
475
476
- static void lookupVisibleProtocolMemberDecls (
477
- Type BaseTy, ProtocolType *PT, VisibleDeclConsumer &Consumer,
478
- const DeclContext *CurrDC, LookupState LS, DeclVisibilityKind Reason,
479
- LazyResolver *TypeResolver, GenericSignatureBuilder *GSB,
480
- VisitedSet &Visited) {
476
+ // Filters out restated declarations from a protocol hierarchy
477
+ // or equivalent requirements from protocol composition types.
478
+ class RestateFilteringConsumer : public VisibleDeclConsumer {
479
+ LazyResolver *resolver;
480
+
481
+ using FoundDecl = std::pair<ValueDecl*, DeclVisibilityKind>;
482
+ using NameAndType = std::pair<DeclName, CanType>;
483
+
484
+ llvm::DenseMap<DeclName, FoundDecl> foundVars;
485
+ llvm::DenseMap<NameAndType, FoundDecl> foundFuncs;
486
+ llvm::MapVector<ValueDecl*, DeclVisibilityKind> declsToReport;
487
+
488
+ template <typename K>
489
+ void addDecl (llvm::DenseMap<K, FoundDecl> &Map, K Key, FoundDecl FD) {
490
+ // Add the declaration if we haven't found an equivalent yet, otherwise
491
+ // replace the equivalent if the found decl has a higher access level.
492
+ auto existingDecl = Map.find (Key);
493
+
494
+ if ((existingDecl == Map.end ()) ||
495
+ (Map[Key].first ->getFormalAccess () < FD.first ->getFormalAccess ())) {
496
+ if (existingDecl != Map.end ())
497
+ declsToReport.erase ({existingDecl->getSecond ().first });
498
+ Map[Key] = FD;
499
+ declsToReport.insert (FD);
500
+ }
501
+ }
502
+
503
+ CanType stripSelfRequirementsIfNeeded (ValueDecl *VD,
504
+ GenericFunctionType *GFT) const {
505
+ // Preserve the generic signature if this is a subscript, which are uncurried,
506
+ // or if we have generic params other than Self. Otherwise, use
507
+ // the resultType of the curried function type.
508
+ // When we keep the generic signature, we remove the requirements
509
+ // from Self to make sure they don't prevent us from recognizing restatements.
510
+ auto params = GFT->getGenericParams ();
511
+ if (params.size () == 1 && !isa<SubscriptDecl>(VD)) {
512
+ return GFT->getResult ()->getCanonicalType ();
513
+ }
514
+ auto Self = VD->getDeclContext ()->getSelfInterfaceType ();
515
+ SmallVector<Requirement, 4 > newReqs;
516
+ for (auto req: GFT->getRequirements ()) {
517
+ if (!Self->isEqual (req.getFirstType ()))
518
+ newReqs.push_back (req);
519
+ }
520
+ auto newSig = GenericSignature::get (params, newReqs, false );
521
+
522
+ return GenericFunctionType::get (newSig, GFT->getInput (),
523
+ GFT->getResult (), GFT->getExtInfo ())
524
+ ->getCanonicalType ();
525
+ }
526
+
527
+ public:
528
+ RestateFilteringConsumer (Type baseTy, const DeclContext *DC,
529
+ LazyResolver *resolver)
530
+ : resolver(resolver) {
531
+ assert (DC && baseTy && !baseTy->hasLValueType ());
532
+ }
533
+
534
+ void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason) override {
535
+ assert (VD);
536
+ // If this isn't a protocol context, don't look further into the decl.
537
+ if (!isa<ProtocolDecl>(VD->getDeclContext ())) {
538
+ declsToReport.insert ({VD, Reason});
539
+ return ;
540
+ }
541
+ if (resolver)
542
+ resolver->resolveDeclSignature (VD);
543
+
544
+ if (!VD->hasInterfaceType ()) {
545
+ declsToReport.insert ({VD, Reason});
546
+ return ;
547
+ }
548
+ if (auto GFT = VD->getInterfaceType ()->getAs <GenericFunctionType>()) {
549
+ auto type = stripSelfRequirementsIfNeeded (VD, GFT);
550
+ addDecl (foundFuncs, {VD->getFullName (), type}, {VD, Reason});
551
+ return ;
552
+ }
553
+ addDecl (foundVars, VD->getFullName (), {VD, Reason});
554
+ }
555
+
556
+ void feedResultsToConsumer (VisibleDeclConsumer &Consumer) const {
557
+ for (const auto entry: declsToReport)
558
+ Consumer.foundDecl (entry.first , entry.second );
559
+ }
560
+ };
561
+
562
+ static void
563
+ lookupVisibleProtocolMemberDecls (Type BaseTy, ProtocolType *PT,
564
+ VisibleDeclConsumer &Consumer,
565
+ const DeclContext *CurrDC, LookupState LS,
566
+ DeclVisibilityKind Reason,
567
+ LazyResolver *TypeResolver,
568
+ GenericSignatureBuilder *GSB,
569
+ VisitedSet &Visited) {
481
570
if (!Visited.insert (PT->getDecl ()).second )
482
571
return ;
483
572
484
573
for (auto Proto : PT->getDecl ()->getInheritedProtocols ())
485
574
lookupVisibleProtocolMemberDecls (BaseTy, Proto->getDeclaredType (), Consumer, CurrDC,
486
- LS, getReasonForSuper (Reason), TypeResolver,
487
- GSB, Visited);
488
-
575
+ LS, getReasonForSuper (Reason), TypeResolver,
576
+ GSB, Visited);
489
577
lookupTypeMembers (BaseTy, PT, Consumer, CurrDC, LS, Reason, TypeResolver);
490
578
}
491
579
@@ -834,7 +922,7 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
834
922
DeclsToReport.insert (FoundDeclTy (VD, Reason));
835
923
}
836
924
};
837
- } // unnamed namespace
925
+ } // end anonymous namespace
838
926
839
927
// / \brief Enumerate all members in \c BaseTy (including members of extensions,
840
928
// / superclasses and implemented protocols), as seen from the context \c CurrDC.
@@ -846,13 +934,15 @@ static void lookupVisibleMemberDecls(
846
934
Type BaseTy, VisibleDeclConsumer &Consumer, const DeclContext *CurrDC,
847
935
LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver,
848
936
GenericSignatureBuilder *GSB) {
849
- OverrideFilteringConsumer ConsumerWrapper (BaseTy, CurrDC, TypeResolver);
937
+ OverrideFilteringConsumer overrideConsumer (BaseTy, CurrDC, TypeResolver);
938
+ RestateFilteringConsumer restateConsumer (BaseTy, CurrDC, TypeResolver);
850
939
VisitedSet Visited;
851
- lookupVisibleMemberDeclsImpl (BaseTy, ConsumerWrapper , CurrDC, LS, Reason,
940
+ lookupVisibleMemberDeclsImpl (BaseTy, restateConsumer , CurrDC, LS, Reason,
852
941
TypeResolver, GSB, Visited);
853
942
854
943
// Report the declarations we found to the real consumer.
855
- for (const auto &DeclAndReason : ConsumerWrapper.DeclsToReport )
944
+ restateConsumer.feedResultsToConsumer (overrideConsumer);
945
+ for (const auto &DeclAndReason : overrideConsumer.DeclsToReport )
856
946
Consumer.foundDecl (DeclAndReason.D , DeclAndReason.Reason );
857
947
}
858
948
0 commit comments