@@ -51,49 +51,6 @@ namespace {
51
51
using ResultsVector = SmallVector<LookupResultEntry, 4 >;
52
52
53
53
private:
54
- // / Finds lookup results based on the types that self conforms to.
55
- // / For instance, self always conforms to a struct, enum or class.
56
- // / But in addition, self could conform to any number of protocols.
57
- // / For example, when there's a protocol extension, e.g. extension P where
58
- // / self: P2, self also conforms to P2 so P2 must be searched.
59
- class ResultFinderForTypeContext {
60
- UnqualifiedLookupFactory *const factory;
61
- // / Nontypes are formally members of the base type, i.e. the dynamic type
62
- // / of the activation record.
63
- const DeclContext *const dynamicContext;
64
- // / Types are formally members of the metatype, i.e. the static type of the
65
- // / activation record.
66
- const DeclContext *const staticContext;
67
- using SelfBounds = SmallVector<NominalTypeDecl *, 2 >;
68
- SelfBounds selfBounds;
69
-
70
- public:
71
- // / \p staticContext is also the context from which to derive the self types
72
- ResultFinderForTypeContext (UnqualifiedLookupFactory *factory,
73
- const DeclContext *dynamicContext,
74
- const DeclContext *staticContext);
75
-
76
- SWIFT_DEBUG_DUMP;
77
-
78
- private:
79
- SelfBounds findSelfBounds (const DeclContext *dc);
80
- ValueDecl *lookupBaseDecl (const DeclContext *baseDC) const ;
81
- ValueDecl *getBaseDeclForResult (const DeclContext *baseDC) const ;
82
-
83
- // Classify this declaration.
84
- // Types are formally members of the metatype.
85
- const DeclContext *
86
- whereValueIsMember (const ValueDecl *const member) const {
87
- return isa<TypeDecl>(member) ? staticContext : dynamicContext;
88
- }
89
-
90
- public:
91
- // / Do the lookups and add matches to results.
92
- void findResults (const DeclNameRef &Name, NLOptions baseNLOptions,
93
- const DeclContext *contextForLookup,
94
- SmallVectorImpl<LookupResultEntry> &results) const ;
95
- };
96
-
97
54
// Inputs
98
55
const DeclNameRef Name;
99
56
DeclContext *const DC;
@@ -152,6 +109,10 @@ namespace {
152
109
153
110
#pragma mark context-based lookup declarations
154
111
112
+ ValueDecl *lookupBaseDecl (const DeclContext *baseDC) const ;
113
+
114
+ ValueDecl *getBaseDeclForResult (const DeclContext *baseDC) const ;
115
+
155
116
// / For diagnostic purposes, move aside the unavailables, and put
156
117
// / them back as a last-ditch effort.
157
118
// / Could be cleaner someday with a richer interface to UnqualifiedLookup.
@@ -172,8 +133,9 @@ namespace {
172
133
const bool isOriginallyMacroLookup);
173
134
174
135
void findResultsAndSaveUnavailables (
175
- const DeclContext *lookupContextForThisContext,
176
- ResultFinderForTypeContext &&resultFinderForTypeContext,
136
+ const DeclContext *dynamicContext,
137
+ const DeclContext *staticContext,
138
+ SmallVector<NominalTypeDecl *, 2 > selfBounds,
177
139
NLOptions baseNLOptions);
178
140
179
141
public:
@@ -335,30 +297,8 @@ void UnqualifiedLookupFactory::lookUpTopLevelNamesInModuleScopeContext(
335
297
336
298
#pragma mark context-based lookup definitions
337
299
338
- void UnqualifiedLookupFactory::ResultFinderForTypeContext::findResults (
339
- const DeclNameRef &Name, NLOptions baseNLOptions,
340
- const DeclContext *contextForLookup,
341
- SmallVectorImpl<LookupResultEntry> &results) const {
342
- // An optimization:
343
- if (selfBounds.empty ())
344
- return ;
345
-
346
- SmallVector<ValueDecl *, 4 > Lookup;
347
- contextForLookup->lookupQualified (selfBounds, Name, factory->Loc ,
348
- baseNLOptions, Lookup);
349
- for (auto Result : Lookup) {
350
- auto baseDC = const_cast <DeclContext *>(whereValueIsMember (Result));
351
- auto baseDecl = getBaseDeclForResult (baseDC);
352
- results.emplace_back (baseDC, baseDecl, Result);
353
- #ifndef NDEBUG
354
- factory->addedResult (results.back ());
355
- #endif
356
- }
357
- }
358
-
359
300
ValueDecl *
360
- UnqualifiedLookupFactory::ResultFinderForTypeContext::getBaseDeclForResult (
361
- const DeclContext *baseDC) const {
301
+ UnqualifiedLookupFactory::getBaseDeclForResult (const DeclContext *baseDC) const {
362
302
if (baseDC == nullptr ) {
363
303
return nullptr ;
364
304
}
@@ -393,7 +333,7 @@ UnqualifiedLookupFactory::ResultFinderForTypeContext::getBaseDeclForResult(
393
333
// / unwrapping condition (e.g. `guard let self else { return }`).
394
334
// / If this is true, then we know any implicit self reference in the
395
335
// / following scope is guaranteed to be non-optional.
396
- bool implicitSelfReferenceIsUnwrapped (const ValueDecl *selfDecl) {
336
+ static bool implicitSelfReferenceIsUnwrapped (const ValueDecl *selfDecl) {
397
337
ASTContext &Ctx = selfDecl->getASTContext ();
398
338
399
339
// Check if the implicit self decl refers to a var in a conditional stmt
@@ -411,25 +351,19 @@ bool implicitSelfReferenceIsUnwrapped(const ValueDecl *selfDecl) {
411
351
return conditionalStmt->rebindsSelf (Ctx);
412
352
}
413
353
414
- ValueDecl *UnqualifiedLookupFactory::ResultFinderForTypeContext::lookupBaseDecl (
415
- const DeclContext *baseDC) const {
416
- auto dc = factory->DC ;
417
- if (!dc) {
418
- return nullptr ;
419
- }
420
-
354
+ ValueDecl *UnqualifiedLookupFactory::lookupBaseDecl (const DeclContext *baseDC) const {
421
355
// Perform an unqualified lookup for the base decl of this result. This
422
356
// handles cases where self was rebound (e.g. `guard let self = self`)
423
357
// earlier in this closure or some outer closure.
424
- auto closureExpr =
425
- dyn_cast_or_null<ClosureExpr>(dc->getInnermostClosureForSelfCapture ());
358
+ auto closureExpr =
359
+ dyn_cast_or_null<ClosureExpr>(dc->getInnermostClosureForSelfCapture ());
360
+
426
361
if (!closureExpr) {
427
362
return nullptr ;
428
363
}
429
364
430
365
auto selfDecl = ASTScope::lookupSingleLocalDecl (
431
- factory->DC ->getParentSourceFile (), DeclName (factory->Ctx .Id_self ),
432
- factory->Loc );
366
+ DC->getParentSourceFile (), DeclName (Ctx.Id_self ), Loc);
433
367
434
368
if (!selfDecl) {
435
369
return nullptr ;
@@ -466,7 +400,7 @@ ValueDecl *UnqualifiedLookupFactory::ResultFinderForTypeContext::lookupBaseDecl(
466
400
// In these cases, using the Swift 6 lookup behavior doesn't affect
467
401
// how the body is type-checked, so it can be used in Swift 5 mode
468
402
// without breaking source compatibility for non-escaping closures.
469
- if (capturesSelfWeakly && !factory-> Ctx .LangOpts .isSwiftVersionAtLeast (6 ) &&
403
+ if (capturesSelfWeakly && !Ctx.LangOpts .isSwiftVersionAtLeast (6 ) &&
470
404
!implicitSelfReferenceIsUnwrapped (selfDecl)) {
471
405
return nullptr ;
472
406
}
@@ -612,12 +546,25 @@ void UnqualifiedLookupFactory::lookForAModuleWithTheGivenName(
612
546
#pragma mark common helper definitions
613
547
614
548
void UnqualifiedLookupFactory::findResultsAndSaveUnavailables (
615
- const DeclContext *lookupContextForThisContext,
616
- ResultFinderForTypeContext &&resultFinderForTypeContext,
549
+ const DeclContext *dynamicContext,
550
+ const DeclContext *staticContext,
551
+ SmallVector<NominalTypeDecl *, 2 > selfBounds,
617
552
NLOptions baseNLOptions) {
553
+ if (selfBounds.empty ())
554
+ return ;
555
+
618
556
auto firstPossiblyUnavailableResult = Results.size ();
619
- resultFinderForTypeContext.findResults (Name, baseNLOptions,
620
- lookupContextForThisContext, Results);
557
+ SmallVector<ValueDecl *, 4 > Lookup;
558
+ staticContext->lookupQualified (selfBounds, Name, Loc, baseNLOptions, Lookup);
559
+ for (auto Result : Lookup) {
560
+ auto baseDC = isa<TypeDecl>(Result) ? staticContext : dynamicContext;
561
+ auto baseDecl = getBaseDeclForResult (baseDC);
562
+ Results.emplace_back (const_cast <DeclContext *>(baseDC), baseDecl, Result);
563
+ #ifndef NDEBUG
564
+ addedResult (Results.back ());
565
+ #endif
566
+ }
567
+
621
568
setAsideUnavailableResults (firstPossiblyUnavailableResult);
622
569
}
623
570
@@ -651,34 +598,6 @@ void UnqualifiedLookupFactory::recordCompletionOfAScope() {
651
598
IndexOfFirstOuterResult = Results.size ();
652
599
}
653
600
654
- UnqualifiedLookupFactory::ResultFinderForTypeContext::
655
- ResultFinderForTypeContext (UnqualifiedLookupFactory *factory,
656
- const DeclContext *dynamicContext,
657
- const DeclContext *staticContext)
658
- : factory(factory), dynamicContext(dynamicContext),
659
- staticContext(staticContext), selfBounds(findSelfBounds(staticContext)) {}
660
-
661
- UnqualifiedLookupFactory::ResultFinderForTypeContext::SelfBounds
662
- UnqualifiedLookupFactory::ResultFinderForTypeContext::findSelfBounds (
663
- const DeclContext *dc) {
664
- auto nominal = dc->getSelfNominalTypeDecl ();
665
- if (!nominal)
666
- return {};
667
-
668
- SelfBounds selfBounds;
669
- selfBounds.push_back (nominal);
670
-
671
- // For a protocol extension, check whether there are additional "Self"
672
- // constraints that can affect name lookup.
673
- if (dc->getExtendedProtocolDecl ()) {
674
- auto ext = cast<ExtensionDecl>(dc);
675
- auto bounds = getSelfBoundsFromWhereClause (ext);
676
- for (auto bound : bounds.decls )
677
- selfBounds.push_back (bound);
678
- }
679
- return selfBounds;
680
- }
681
-
682
601
#pragma mark ASTScopeImpl support
683
602
684
603
void UnqualifiedLookupFactory::lookInASTScopes () {
@@ -799,19 +718,39 @@ bool ASTScopeDeclGatherer::consume(ArrayRef<ValueDecl *> valuesArg,
799
718
return false ;
800
719
}
801
720
721
+ static SmallVector<NominalTypeDecl *, 2 > findSelfBounds (const DeclContext *dc) {
722
+ auto nominal = dc->getSelfNominalTypeDecl ();
723
+ if (!nominal)
724
+ return {};
725
+
726
+ SmallVector<NominalTypeDecl *, 2 > selfBounds;
727
+ selfBounds.push_back (nominal);
728
+
729
+ // For a protocol extension, check whether there are additional "Self"
730
+ // constraints that can affect name lookup.
731
+ if (dc->getExtendedProtocolDecl ()) {
732
+ auto ext = cast<ExtensionDecl>(dc);
733
+ auto bounds = getSelfBoundsFromWhereClause (ext);
734
+ for (auto bound : bounds.decls )
735
+ selfBounds.push_back (bound);
736
+ }
737
+
738
+ return selfBounds;
739
+ }
740
+
802
741
// TODO: in future, migrate this functionality into ASTScopes
803
742
bool ASTScopeDeclConsumerForUnqualifiedLookup::lookInMembers (
804
743
const DeclContext *scopeDC) const {
744
+ auto selfBounds = findSelfBounds (scopeDC);
745
+
805
746
// We're looking for members of a type.
806
747
//
807
748
// If we started the looking from inside a scope where a 'self' parameter
808
749
// is visible, instance members are returned with the 'self' parameter's
809
750
// DeclContext as the base, which is how the expression checker knows to
810
751
// convert the unqualified reference into a self member access.
811
- auto resultFinder = UnqualifiedLookupFactory::ResultFinderForTypeContext (
812
- &factory, candidateSelfDC ? candidateSelfDC : scopeDC, scopeDC);
813
- factory.findResultsAndSaveUnavailables (scopeDC, std::move (resultFinder),
814
- factory.baseNLOptions );
752
+ factory.findResultsAndSaveUnavailables (candidateSelfDC ? candidateSelfDC : scopeDC,
753
+ scopeDC, selfBounds, factory.baseNLOptions );
815
754
factory.recordCompletionOfAScope ();
816
755
817
756
// We're done looking inside a nominal type declaration. It is possible
@@ -837,18 +776,6 @@ UnqualifiedLookupRequest::evaluate(Evaluator &evaluator,
837
776
838
777
#pragma mark debugging
839
778
840
- void UnqualifiedLookupFactory::ResultFinderForTypeContext::dump () const {
841
- (void )factory;
842
- llvm::errs () << " dynamicContext: " ;
843
- dynamicContext->dumpContext ();
844
- llvm::errs () << " staticContext: " ;
845
- staticContext->dumpContext ();
846
- llvm::errs () << " selfBounds: " ;
847
- for (const auto *D : selfBounds)
848
- D->dump (llvm::errs (), 1 );
849
- llvm::errs () << " \n " ;
850
- }
851
-
852
779
void UnqualifiedLookupFactory::dump () const { print (llvm::errs ()); }
853
780
void UnqualifiedLookupFactory::dumpScopes () const { printScopes (llvm::errs ()); }
854
781
void UnqualifiedLookupFactory::dumpResults () const {
0 commit comments