1818#include " TypeChecker.h"
1919#include " MiscDiagnostics.h"
2020#include " swift/AST/ASTWalker.h"
21+ #include " swift/AST/Initializer.h"
2122#include " swift/AST/NameLookup.h"
2223#include " swift/AST/Pattern.h"
2324#include " swift/AST/TypeRefinementContext.h"
@@ -856,27 +857,41 @@ static Optional<ASTNode> findInnermostAncestor(
856857static const Decl *findContainingDeclaration (SourceRange ReferenceRange,
857858 const DeclContext *ReferenceDC,
858859 const SourceManager &SM) {
859- if (const Decl *D = ReferenceDC->getInnermostDeclarationDeclContext ())
860+ auto ContainsReferenceRange = [&](const Decl *D) -> bool {
861+ if (ReferenceRange.isInvalid ())
862+ return false ;
863+ return SM.rangeContains (D->getSourceRange (), ReferenceRange);
864+ };
865+
866+ if (const Decl *D = ReferenceDC->getInnermostDeclarationDeclContext ()) {
867+ // If we have an inner declaration context, see if we can narrow the search
868+ // down to one of its members. This is important for properties, which don't
869+ // count as DeclContexts of their own but which can still introduce
870+ // availability.
871+ if (auto *IDC = dyn_cast<IterableDeclContext>(D)) {
872+ auto BestMember = llvm::find_if (IDC->getMembers (),
873+ ContainsReferenceRange);
874+ if (BestMember != IDC->getMembers ().end ())
875+ return *BestMember;
876+ }
860877 return D;
878+ }
861879
862- // We couldn't find a suitable node by climbing the DeclContext
863- // hierarchy, so fall back to looking for a top-level declaration
864- // that contains the reference range. We will hit this case for
865- // top-level elements that do not themselves introduce DeclContexts,
866- // such as extensions and global variables. If we don't have a reference
867- // range, there is nothing we can do, so return null.
880+ // We couldn't find a suitable node by climbing the DeclContext hierarchy, so
881+ // fall back to looking for a top-level declaration that contains the
882+ // reference range. We will hit this case for top-level elements that do not
883+ // themselves introduce DeclContexts, such as global variables. If we don't
884+ // have a reference range, there is nothing we can do, so return null.
868885 if (ReferenceRange.isInvalid ())
869886 return nullptr ;
870887
871888 SourceFile *SF = ReferenceDC->getParentSourceFile ();
872889 if (!SF)
873890 return nullptr ;
874891
875- for (Decl *D : SF->Decls ) {
876- if (SM.rangeContains (D->getSourceRange (), ReferenceRange)) {
877- return D;
878- }
879- }
892+ auto BestTopLevelDecl = llvm::find_if (SF->Decls , ContainsReferenceRange);
893+ if (BestTopLevelDecl != SF->Decls .end ())
894+ return *BestTopLevelDecl;
880895
881896 return nullptr ;
882897}
@@ -929,9 +944,13 @@ abstractSyntaxDeclForAvailableAttribute(const Decl *ConcreteSyntaxDecl) {
929944 // binding.
930945 ArrayRef<PatternBindingEntry> Entries = PBD->getPatternList ();
931946 if (!Entries.empty ()) {
932- VarDecl *VD = Entries.front ().getPattern ()->getSingleVar ();
933- if (VD)
934- return VD;
947+ const VarDecl *AnyVD = nullptr ;
948+ // FIXME: This is wasteful; we only need the first variable.
949+ Entries.front ().getPattern ()->forEachVariable ([&](const VarDecl *VD) {
950+ AnyVD = VD;
951+ });
952+ if (AnyVD)
953+ return AnyVD;
935954 }
936955 } else if (auto *ECD = dyn_cast<EnumCaseDecl>(ConcreteSyntaxDecl)) {
937956 // Similar to the PatternBindingDecl case above, we return the
@@ -1408,7 +1427,7 @@ someEnclosingDeclMatches(SourceRange ReferenceRange,
14081427 // Climb the DeclContext hierarchy to see if any of the containing
14091428 // declarations matches the predicate.
14101429 const DeclContext *DC = ReferenceDC;
1411- do {
1430+ while ( true ) {
14121431 auto *D = DC->getInnermostDeclarationDeclContext ();
14131432 if (!D)
14141433 break ;
@@ -1424,20 +1443,15 @@ someEnclosingDeclMatches(SourceRange ReferenceRange,
14241443 return true ;
14251444 }
14261445
1427- DC = DC-> getParent ();
1428- } while (DC);
1446+ DC = D-> getDeclContext ();
1447+ }
14291448
14301449 // Search the AST starting from our innermost declaration context to see if
14311450 // if the reference is inside a property declaration but not inside an
14321451 // accessor (this can happen for the TypeRepr for the declared type of a
14331452 // property, for example).
14341453 // We can't rely on the DeclContext hierarchy climb above because properties
1435- // do not introduce a new DeclContext. This search is potentially slow, so we
1436- // do it last and only if the reference declaration context is a
1437- // type or global context.
1438-
1439- if (!ReferenceDC->isTypeContext () && !ReferenceDC->isModuleScopeContext ())
1440- return false ;
1454+ // do not introduce a new DeclContext.
14411455
14421456 // Don't search for a containing declaration if we don't have a source range.
14431457 if (ReferenceRange.isInvalid ())
@@ -1448,28 +1462,11 @@ someEnclosingDeclMatches(SourceRange ReferenceRange,
14481462 findContainingDeclaration (ReferenceRange, ReferenceDC, Ctx.SourceMgr );
14491463
14501464 // We may not be able to find a declaration to search if the ReferenceRange
1451- // is invalid (i.e., we are in synthesized code).
1465+ // isn't useful (i.e., we are in synthesized code).
14521466 if (!DeclToSearch)
14531467 return false ;
14541468
1455- InnermostAncestorFinder::MatchPredicate IsDeclaration =
1456- [](ASTNode Node, ASTWalker::ParentTy Parent) {
1457- return Node.is <Decl *>();
1458- };
1459-
1460- Optional<ASTNode> FoundDeclarationNode =
1461- findInnermostAncestor (ReferenceRange, Ctx.SourceMgr ,
1462- const_cast <Decl *>(DeclToSearch), IsDeclaration);
1463-
1464- if (FoundDeclarationNode.hasValue ()) {
1465- const Decl *D = FoundDeclarationNode.getValue ().get <Decl *>();
1466- D = abstractSyntaxDeclForAvailableAttribute (D);
1467- if (Pred (D)) {
1468- return true ;
1469- }
1470- }
1471-
1472- return false ;
1469+ return Pred (abstractSyntaxDeclForAvailableAttribute (DeclToSearch));
14731470}
14741471
14751472// / Returns true if the reference or any of its parents is an
0 commit comments