|
19 | 19 | #include "swift/AST/ASTVisitor.h"
|
20 | 20 | #include "swift/AST/DebuggerClient.h"
|
21 | 21 | #include "swift/AST/ImportCache.h"
|
| 22 | +#include "swift/AST/Initializer.h" |
22 | 23 | #include "swift/AST/ModuleNameLookup.h"
|
23 | 24 | #include "swift/AST/NameLookup.h"
|
24 | 25 | #include "swift/AST/NameLookupRequests.h"
|
25 | 26 | #include "swift/AST/PropertyWrappers.h"
|
26 | 27 | #include "swift/AST/SourceFile.h"
|
27 |
| -#include "swift/AST/Initializer.h" |
28 | 28 | #include "swift/Basic/Debug.h"
|
29 | 29 | #include "swift/Basic/STLExtras.h"
|
30 | 30 | #include "swift/Basic/SourceManager.h"
|
@@ -77,6 +77,8 @@ namespace {
|
77 | 77 |
|
78 | 78 | private:
|
79 | 79 | SelfBounds findSelfBounds(const DeclContext *dc);
|
| 80 | + ValueDecl *lookupBaseDecl(const DeclContext *baseDC) const; |
| 81 | + ValueDecl *getBaseDeclForResult(const DeclContext *baseDC) const; |
80 | 82 |
|
81 | 83 | // Classify this declaration.
|
82 | 84 | // Types are formally members of the metatype.
|
@@ -345,64 +347,74 @@ void UnqualifiedLookupFactory::ResultFinderForTypeContext::findResults(
|
345 | 347 | contextForLookup->lookupQualified(selfBounds, Name, baseNLOptions, Lookup);
|
346 | 348 | for (auto Result : Lookup) {
|
347 | 349 | auto baseDC = const_cast<DeclContext *>(whereValueIsMember(Result));
|
348 |
| - |
349 |
| - // Retrieve the base decl for this lookup |
350 |
| - ValueDecl* baseDecl; |
351 |
| - |
352 |
| - // Perform an unqualified lookup for the base decl of this result. This handles cases |
353 |
| - // where self was rebound (e.g. `guard let self = self`) earlier in the scope. |
354 |
| - // - Only do this in closures that capture self weakly, since implicit self isn't |
355 |
| - // allowed to be rebound in other contexts. In other contexts, implicit self |
356 |
| - // _always_ refers to the context's self `ParamDecl`, even if there is another |
357 |
| - // local decl with the name `self` that would be found by `lookupSingleLocalDecl`. |
358 |
| - ValueDecl* localBaseDecl = nullptr; |
359 |
| - bool isInWeakSelfClosure = false; |
360 |
| - if (auto closureExpr = dyn_cast<ClosureExpr>(factory->DC)) { |
361 |
| - if (auto selfDecl = closureExpr->getCapturedSelfDecl()) { |
362 |
| - auto *attr = selfDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>(); |
363 |
| - isInWeakSelfClosure = attr->get() == ReferenceOwnership::Weak; |
364 |
| - } |
365 |
| - } |
366 |
| - |
367 |
| - if (isInWeakSelfClosure) { |
368 |
| - localBaseDecl = ASTScope::lookupSingleLocalDecl(factory->DC->getParentSourceFile(), |
369 |
| - DeclName(factory->Ctx.Id_self), |
370 |
| - factory->Loc); |
371 |
| - } |
372 |
| - |
373 |
| - if (baseDC == nullptr) |
374 |
| - baseDecl = nullptr; |
375 |
| - |
376 |
| - else if (localBaseDecl) |
377 |
| - baseDecl = localBaseDecl; |
| 350 | + auto baseDecl = getBaseDeclForResult(baseDC); |
| 351 | + results.emplace_back(baseDC, baseDecl, Result); |
| 352 | +#ifndef NDEBUG |
| 353 | + factory->addedResult(results.back()); |
| 354 | +#endif |
| 355 | + } |
| 356 | +} |
378 | 357 |
|
379 |
| - else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(baseDC)) |
380 |
| - baseDecl = AFD->getImplicitSelfDecl(); |
| 358 | +ValueDecl * |
| 359 | +UnqualifiedLookupFactory::ResultFinderForTypeContext::getBaseDeclForResult( |
| 360 | + const DeclContext *baseDC) const { |
| 361 | + if (baseDC == nullptr) { |
| 362 | + return nullptr; |
| 363 | + } |
381 | 364 |
|
382 |
| - else if (auto *PBI = dyn_cast<PatternBindingInitializer>(baseDC)) { |
383 |
| - auto *selfDecl = PBI->getImplicitSelfDecl(); |
384 |
| - assert(selfDecl); |
385 |
| - baseDecl = selfDecl; |
386 |
| - } |
| 365 | + if (auto localBaseDecl = lookupBaseDecl(baseDC)) { |
| 366 | + return localBaseDecl; |
| 367 | + } |
387 | 368 |
|
388 |
| - else if (auto *CE = dyn_cast<ClosureExpr>(baseDC)) { |
389 |
| - auto *selfDecl = CE->getCapturedSelfDecl(); |
390 |
| - assert(selfDecl); |
391 |
| - assert(selfDecl->isSelfParamCapture()); |
392 |
| - baseDecl = selfDecl; |
393 |
| - } |
| 369 | + if (auto *AFD = dyn_cast<AbstractFunctionDecl>(baseDC)) { |
| 370 | + return const_cast<ParamDecl *>(AFD->getImplicitSelfDecl()); |
| 371 | + } |
394 | 372 |
|
395 |
| - else { |
396 |
| - auto *nominalDecl = baseDC->getSelfNominalTypeDecl(); |
397 |
| - assert(nominalDecl); |
398 |
| - baseDecl = nominalDecl; |
| 373 | + if (auto *PBI = dyn_cast<PatternBindingInitializer>(baseDC)) { |
| 374 | + auto *selfDecl = PBI->getImplicitSelfDecl(); |
| 375 | + assert(selfDecl); |
| 376 | + return selfDecl; |
| 377 | + } |
| 378 | + |
| 379 | + else if (auto *CE = dyn_cast<ClosureExpr>(baseDC)) { |
| 380 | + auto *selfDecl = CE->getCapturedSelfDecl(); |
| 381 | + assert(selfDecl); |
| 382 | + assert(selfDecl->isSelfParamCapture()); |
| 383 | + return selfDecl; |
| 384 | + } |
| 385 | + |
| 386 | + auto *nominalDecl = baseDC->getSelfNominalTypeDecl(); |
| 387 | + assert(nominalDecl); |
| 388 | + return nominalDecl; |
| 389 | +} |
| 390 | + |
| 391 | +ValueDecl *UnqualifiedLookupFactory::ResultFinderForTypeContext::lookupBaseDecl( |
| 392 | + const DeclContext *baseDC) const { |
| 393 | + // Perform an unqualified lookup for the base decl of this result. This |
| 394 | + // handles cases where self was rebound (e.g. `guard let self = self`) |
| 395 | + // earlier in the scope. |
| 396 | + // |
| 397 | + // Only do this in closures that capture self weakly, since implicit self |
| 398 | + // isn't allowed to be rebound in other contexts. In other contexts, implicit |
| 399 | + // self _always_ refers to the context's self `ParamDecl`, even if there |
| 400 | + // is another local decl with the name `self` that would be found by |
| 401 | + // `lookupSingleLocalDecl`. |
| 402 | + bool isInWeakSelfClosure = false; |
| 403 | + if (auto closureExpr = dyn_cast<ClosureExpr>(factory->DC)) { |
| 404 | + if (auto decl = closureExpr->getCapturedSelfDecl()) { |
| 405 | + if (auto a = decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) { |
| 406 | + isInWeakSelfClosure = a->get() == ReferenceOwnership::Weak; |
| 407 | + } |
399 | 408 | }
|
400 |
| - |
401 |
| - results.emplace_back(baseDC, baseDecl, Result); |
402 |
| -#ifndef NDEBUG |
403 |
| - factory->addedResult(results.back()); |
404 |
| -#endif |
405 | 409 | }
|
| 410 | + |
| 411 | + if (isInWeakSelfClosure) { |
| 412 | + return ASTScope::lookupSingleLocalDecl(factory->DC->getParentSourceFile(), |
| 413 | + DeclName(factory->Ctx.Id_self), |
| 414 | + factory->Loc); |
| 415 | + } |
| 416 | + |
| 417 | + return nullptr; |
406 | 418 | }
|
407 | 419 |
|
408 | 420 | // TODO (someday): Instead of adding unavailable entries to Results,
|
|
0 commit comments