@@ -227,12 +227,12 @@ class UnqualifiedLookupFactory {
227
227
private:
228
228
bool useASTScopesForExperimentalLookup () const ;
229
229
230
- void lookInModuleScope (DCAndResolvedIsCascadingUse dcAndIsCascadingUse);
230
+ void lookInModuleScopeContext (DCAndResolvedIsCascadingUse dcAndIsCascadingUse);
231
231
232
232
#pragma mark ASTScope-based-lookup declarations
233
233
234
234
235
- Optional<DCAndResolvedIsCascadingUse>
235
+ void
236
236
experimentallyLookInASTScopes (DeclContext *dc, Optional<bool > isCascadingUse);
237
237
238
238
std::pair<const ASTScope *, bool >
@@ -243,25 +243,36 @@ class UnqualifiedLookupFactory {
243
243
nonoperatorScopeForASTScopeLookup (DeclContext *dc,
244
244
Optional<bool > isCascadingUse) const ;
245
245
246
- struct LookInScopeForASTScopeLookupResult {
247
- bool isDone; // Searching outers
246
+ struct ASTScopeLookupState {
247
+ const ASTScope *scope;
248
248
DeclContext *selfDC;
249
249
DeclContext *dc;
250
250
Optional<bool > isCascadingUse;
251
+
252
+ ASTScopeLookupState withParentScope () const {
253
+ return ASTScopeLookupState{scope->getParent (), selfDC, dc, isCascadingUse};
254
+ }
255
+ ASTScopeLookupState withNoScope () const {
256
+ return ASTScopeLookupState{nullptr , selfDC, dc, isCascadingUse};
257
+ }
258
+ ASTScopeLookupState withSelfDC (DeclContext *selfDC) const {
259
+ return ASTScopeLookupState{scope, selfDC, dc, isCascadingUse};
260
+ }
261
+ ASTScopeLookupState withDC (DeclContext *dc) const {
262
+ return ASTScopeLookupState{scope, selfDC, dc, isCascadingUse};
263
+ }
264
+ ASTScopeLookupState withResolvedIsCascadingUse (bool isCascadingUse) const {
265
+ return ASTScopeLookupState{scope, selfDC, dc, isCascadingUse};
266
+ }
251
267
};
252
268
253
269
// / Return status and new selfDC and new DC
254
- Optional<LookInScopeForASTScopeLookupResult>
255
- lookInScopeForASTScopeLookup (const ASTScope *const currentScope,
256
- DeclContext *selfDC, DeclContext *dc,
257
- const Optional<bool > isCascadingUse);
270
+ ASTScopeLookupState
271
+ lookInScopeForASTScopeLookup (const ASTScopeLookupState);
258
272
259
273
// / Returns status and selfDC and DC
260
- Optional<LookInScopeForASTScopeLookupResult>
261
- lookIntoDeclarationContextForASTScopeLookup (DeclContext *dc,
262
- DeclContext *selfDC,
263
- DeclContext *wasDC,
264
- Optional<bool > isCascadingUse);
274
+ ASTScopeLookupState
275
+ lookIntoDeclarationContextForASTScopeLookup (ASTScopeLookupState);
265
276
// / Can lookup stop searching for results, assuming hasn't looked for outer
266
277
// / results yet?
267
278
bool isFirstResultEnough () const ;
@@ -273,9 +284,7 @@ class UnqualifiedLookupFactory {
273
284
274
285
#pragma mark normal (non-ASTScope-based) lookup declarations
275
286
276
- // / Return None if lookup done.
277
- Optional<DCAndResolvedIsCascadingUse>
278
- lookInDeclContexts (DeclContext *dc, const Optional <bool > isCascadingUseArg);
287
+ void lookInDeclContexts (DeclContext *dc, const Optional <bool > isCascadingUseArg);
279
288
280
289
// / Return None if lookup done.
281
290
Optional<DCAndResolvedIsCascadingUse>
@@ -403,16 +412,16 @@ IndexOfFirstOuterResult(lookupToBeCreated.IndexOfFirstOuterResult)
403
412
404
413
void UnqualifiedLookupFactory::performUnqualifiedLookup () {
405
414
const Optional<bool > isCascadingUseInitial =
406
- options.contains (Flags::KnownPrivate) ? Optional<bool >(false ) : None;
407
- // Never perform local lookup for operators.
408
- Optional<DCAndResolvedIsCascadingUse> dcAndIsCascadingUse = useASTScopesForExperimentalLookup ()
409
- ? experimentallyLookInASTScopes (DC, isCascadingUseInitial)
410
- : lookInDeclContexts (DC, isCascadingUseInitial) ;
411
- if (dcAndIsCascadingUse. hasValue ())
412
- lookInModuleScope (dcAndIsCascadingUse. getValue () );
415
+ options.contains (Flags::KnownPrivate) ? Optional<bool >(false ) : None;
416
+
417
+ if ( useASTScopesForExperimentalLookup ()) {
418
+ experimentallyLookInASTScopes (DC, isCascadingUseInitial);
419
+ return ;
420
+ }
421
+ lookInDeclContexts (DC, isCascadingUseInitial );
413
422
}
414
423
415
- void UnqualifiedLookupFactory::lookInModuleScope (
424
+ void UnqualifiedLookupFactory::lookInModuleScopeContext (
416
425
DCAndResolvedIsCascadingUse dcAndIsCascadingUse) {
417
426
DeclContext *const DC = dcAndIsCascadingUse.DC ;
418
427
const bool isCascadingUse = dcAndIsCascadingUse.isCascadingUse ;
@@ -447,8 +456,7 @@ bool UnqualifiedLookupFactory::useASTScopesForExperimentalLookup() const {
447
456
448
457
#pragma mark ASTScope-based-lookup definitions
449
458
450
- // / Return None if lookup done
451
- Optional<UnqualifiedLookupFactory::DCAndResolvedIsCascadingUse>
459
+ void
452
460
UnqualifiedLookupFactory::experimentallyLookInASTScopes (DeclContext *const startDC,
453
461
Optional<bool > isCascadingUse) {
454
462
const std::pair<const ASTScope *, Optional<bool >>
@@ -457,23 +465,17 @@ UnqualifiedLookupFactory::experimentallyLookInASTScopes(DeclContext *const start
457
465
? operatorScopeForASTScopeLookup (startDC, isCascadingUse)
458
466
: nonoperatorScopeForASTScopeLookup (startDC, isCascadingUse);
459
467
// Walk scopes outward from the innermost scope until we find something.
460
- DeclContext *dc = startDC;
461
- DeclContext *selfDC = nullptr ;
462
- Optional<bool > currentIsCascadingUse = lookupScopeAndIsCascadingUse.second ;
463
- for (auto currentScope = lookupScopeAndIsCascadingUse.first ; currentScope;
464
- currentScope = currentScope->getParent ()) {
465
- auto r = lookInScopeForASTScopeLookup (currentScope, selfDC, dc,
466
- currentIsCascadingUse);
467
- if (!r.hasValue ())
468
- return None;
469
- selfDC = r.getValue ().selfDC ;
470
- dc = r.getValue ().dc ;
471
- currentIsCascadingUse = r.getValue ().isCascadingUse ;
472
- const bool isDone = r.getValue ().isDone ;
473
- if (isDone)
474
- return DCAndResolvedIsCascadingUse{dc, currentIsCascadingUse.getValue ()};
468
+
469
+ ASTScopeLookupState state{lookupScopeAndIsCascadingUse.first , nullptr , startDC, lookupScopeAndIsCascadingUse.second };
470
+ while ( state.scope ) {
471
+ state = lookInScopeForASTScopeLookup (state);
472
+ if (!state.scope )
473
+ break ;
474
+ state = state.withParentScope ();
475
475
}
476
- llvm_unreachable (" impossible" );
476
+ if (isFirstResultEnough ())
477
+ return ;
478
+ lookInModuleScopeContext (DCAndResolvedIsCascadingUse{state.dc , state.isCascadingUse .getValue ()});
477
479
}
478
480
479
481
std::pair<const ASTScope *, bool >
@@ -507,127 +509,115 @@ UnqualifiedLookupFactory::nonoperatorScopeForASTScopeLookup(
507
509
return std::make_pair (lookupScope, isCascadingUse);
508
510
}
509
511
510
- Optional< UnqualifiedLookupFactory::LookInScopeForASTScopeLookupResult>
512
+ UnqualifiedLookupFactory::ASTScopeLookupState
511
513
UnqualifiedLookupFactory::lookInScopeForASTScopeLookup (
512
- const ASTScope *const currentScope, DeclContext *selfDC, DeclContext *dc,
513
- const Optional<bool > isCascadingUse) {
514
+ const ASTScopeLookupState state) {
514
515
515
516
// Perform local lookup within this scope.
516
- auto localBindings = currentScope ->getLocalBindings ();
517
+ auto localBindings = state. scope ->getLocalBindings ();
517
518
for (auto local : localBindings) {
518
- Consumer.foundDecl (local, getLocalDeclVisibilityKind (currentScope ));
519
+ Consumer.foundDecl (local, getLocalDeclVisibilityKind (state. scope ));
519
520
}
520
521
521
522
recordCompletionOfAScope ();
522
523
// If we found anything, we're done.
523
524
if (isFirstResultEnough ())
524
- return None ;
525
+ return state. withNoScope () ;
525
526
526
527
// When we are in the body of a method, get the 'self' declaration.
527
- if (currentScope ->getKind () == ASTScopeKind::AbstractFunctionBody &&
528
- currentScope ->getAbstractFunctionDecl ()
528
+ if (state. scope ->getKind () == ASTScopeKind::AbstractFunctionBody &&
529
+ state. scope ->getAbstractFunctionDecl ()
529
530
->getDeclContext ()
530
531
->isTypeContext ()) {
531
- selfDC = currentScope->getAbstractFunctionDecl ();
532
- return LookInScopeForASTScopeLookupResult{false , selfDC, dc,
533
- isCascadingUse};
532
+ return state.withSelfDC (state.scope ->getAbstractFunctionDecl ());
534
533
}
535
534
536
535
// If there is a declaration context associated with this scope, we might
537
536
// want to look in it.
538
- if (auto scopeDC = currentScope->getDeclContext ())
539
- return lookIntoDeclarationContextForASTScopeLookup (scopeDC, selfDC, dc,
540
- isCascadingUse);
541
- return LookInScopeForASTScopeLookupResult{false , selfDC, dc, isCascadingUse};
537
+ return lookIntoDeclarationContextForASTScopeLookup (state);
542
538
}
543
539
544
- Optional< UnqualifiedLookupFactory::LookInScopeForASTScopeLookupResult>
540
+ UnqualifiedLookupFactory::ASTScopeLookupState
545
541
UnqualifiedLookupFactory::lookIntoDeclarationContextForASTScopeLookup (
546
- DeclContext *dc, DeclContext *selfDC, DeclContext *wasDC,
547
- Optional<bool > isCascadingUse) {
542
+ ASTScopeLookupState stateArg) {
543
+
544
+ DeclContext *scopeDC = stateArg.scope ->getDeclContext ();
545
+ if (!scopeDC)
546
+ return stateArg;
548
547
549
548
// If we haven't determined whether we have a cascading use, do so now.
550
549
const bool isCascadingUseResult = resolveIsCascadingUse (
551
- dc, isCascadingUse, /* onlyCareAboutFunctionBody=*/ false );
550
+ scopeDC, stateArg.isCascadingUse , /* onlyCareAboutFunctionBody=*/ false );
551
+
552
+ const ASTScopeLookupState defaultReturnState = stateArg.withResolvedIsCascadingUse (isCascadingUseResult);
552
553
553
554
// Pattern binding initializers are only interesting insofar as they
554
555
// affect lookup in an enclosing nominal type or extension thereof.
555
- if (auto *bindingInit = dyn_cast<PatternBindingInitializer>(dc )) {
556
+ if (auto *bindingInit = dyn_cast<PatternBindingInitializer>(scopeDC )) {
556
557
// Lazy variable initializer contexts have a 'self' parameter for
557
558
// instance member lookup.
558
559
if (bindingInit->getImplicitSelfDecl ())
559
- selfDC = bindingInit;
560
+ return defaultReturnState. withSelfDC ( bindingInit) ;
560
561
561
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
562
- isCascadingUseResult};
562
+ return defaultReturnState;
563
563
}
564
564
565
565
// Default arguments only have 'static' access to the members of the
566
566
// enclosing type, if there is one.
567
- if (isa<DefaultArgumentInitializer>(dc))
568
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
569
- isCascadingUseResult};
567
+ if (isa<DefaultArgumentInitializer>(scopeDC))
568
+ return defaultReturnState;
570
569
571
570
// Functions/initializers/deinitializers are only interesting insofar as
572
571
// they affect lookup in an enclosing nominal type or extension thereof.
573
- if (isa<AbstractFunctionDecl>(dc))
574
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
575
- isCascadingUseResult};
572
+ if (isa<AbstractFunctionDecl>(scopeDC))
573
+ return defaultReturnState;
576
574
577
575
// Subscripts have no lookup of their own.
578
- if (isa<SubscriptDecl>(dc))
579
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
580
- isCascadingUseResult};
576
+ if (isa<SubscriptDecl>(scopeDC))
577
+ return defaultReturnState;
581
578
582
579
// Closures have no lookup of their own.
583
- if (isa<AbstractClosureExpr>(dc))
584
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
585
- isCascadingUseResult};
580
+ if (isa<AbstractClosureExpr>(scopeDC))
581
+ return defaultReturnState;
586
582
587
583
// Top-level declarations have no lookup of their own.
588
- if (isa<TopLevelCodeDecl>(dc))
589
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
590
- isCascadingUseResult};
584
+ if (isa<TopLevelCodeDecl>(scopeDC))
585
+ return defaultReturnState;
591
586
592
587
// Typealiases have no lookup of their own.
593
- if (isa<TypeAliasDecl>(dc))
594
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
595
- isCascadingUseResult};
588
+ if (isa<TypeAliasDecl>(scopeDC))
589
+ return defaultReturnState;
596
590
597
591
// Lookup in the source file's scope marks the end.
598
- if (isa<SourceFile>(dc )) {
592
+ if (isa<SourceFile>(scopeDC )) {
599
593
// FIXME: A bit of a hack.
600
- return LookInScopeForASTScopeLookupResult{true , selfDC, dc,
601
- isCascadingUseResult};
594
+ return defaultReturnState.withDC (scopeDC).withNoScope ();
602
595
}
603
596
604
597
// We have a nominal type or an extension thereof. Perform lookup into
605
598
// the nominal type.
606
- auto nominal = dc ->getSelfNominalTypeDecl ();
599
+ auto nominal = scopeDC ->getSelfNominalTypeDecl ();
607
600
if (!nominal)
608
- return LookInScopeForASTScopeLookupResult{false , selfDC, wasDC,
609
- isCascadingUseResult};
601
+ return defaultReturnState;
610
602
611
603
// Dig out the type we're looking into.
612
604
using LookupDecls = SmallVector<NominalTypeDecl *, 2 >;
613
605
LookupDecls lookupDecls;
614
- populateLookupDeclsFromContext (dc , lookupDecls);
606
+ populateLookupDeclsFromContext (scopeDC , lookupDecls);
615
607
616
- NLOptions options = baseNLOptions;
608
+
617
609
// Perform lookup into the type.
618
- if (isCascadingUseResult)
619
- options |= NL_KnownCascadingDependency;
620
- else
621
- options |= NL_KnownNonCascadingDependency;
610
+ NLOptions options = baseNLOptions | (
611
+ isCascadingUseResult ? NL_KnownCascadingDependency : NL_KnownNonCascadingDependency);
622
612
623
613
SmallVector<ValueDecl *, 4 > lookup;
624
- dc ->lookupQualified (lookupDecls, Name, options, lookup);
614
+ scopeDC ->lookupQualified (lookupDecls, Name, options, lookup);
625
615
626
616
auto startIndex = Results.size ();
627
617
for (auto result : lookup) {
628
- auto *baseDC = dc ;
629
- if (!isa<TypeDecl>(result) && selfDC)
630
- baseDC = selfDC;
618
+ auto *baseDC = scopeDC ;
619
+ if (!isa<TypeDecl>(result) && defaultReturnState. selfDC )
620
+ baseDC = defaultReturnState. selfDC ;
631
621
Results.push_back (LookupResultEntry (baseDC, result));
632
622
}
633
623
@@ -650,29 +640,27 @@ UnqualifiedLookupFactory::lookIntoDeclarationContextForASTScopeLookup(
650
640
651
641
recordCompletionOfAScope ();
652
642
if (isFirstResultEnough ())
653
- return None ;
643
+ return defaultReturnState. withNoScope () ;
654
644
}
655
645
}
656
646
657
647
// Forget the 'self' declaration.
658
- selfDC = nullptr ;
659
-
660
- return LookInScopeForASTScopeLookupResult{false , selfDC, dc,
661
- isCascadingUseResult};
648
+ return defaultReturnState.withSelfDC (nullptr );
662
649
}
663
650
664
651
#pragma mark context-based lookup declarations
665
652
666
- Optional<UnqualifiedLookupFactory::DCAndResolvedIsCascadingUse>
653
+ void
667
654
UnqualifiedLookupFactory::lookInDeclContexts (DeclContext *dc, const Optional <bool > isCascadingUseArg) {
655
+ // #error move final rnt to tails of next two
668
656
auto dcAndIsCascadingUse =
669
657
Name.isOperator () ? lookupOperatorInDeclContexts (DC, isCascadingUseArg)
670
658
: lookupNameInDeclContexts (DC, isCascadingUseArg);
671
659
if (!dcAndIsCascadingUse.hasValue ())
672
- return None ;
660
+ return ;
673
661
if (addLocalVariableResults (dcAndIsCascadingUse.getValue ().DC ))
674
- return None ;
675
- return dcAndIsCascadingUse;
662
+ return ;
663
+ lookInModuleScopeContext ( dcAndIsCascadingUse. getValue ()) ;
676
664
}
677
665
678
666
Optional<UnqualifiedLookupFactory::DCAndResolvedIsCascadingUse>
0 commit comments