22
22
#include " swift/AST/Pattern.h"
23
23
#include " swift/AST/ProtocolConformance.h"
24
24
#include " swift/AST/SourceFile.h"
25
+ #include " swift/AST/Stmt.h"
25
26
#include " swift/AST/TypeRepr.h"
26
27
#include " swift/AST/Types.h"
27
28
#include " swift/AST/USRGeneration.h"
@@ -449,8 +450,9 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
449
450
ContainerTracker Containers;
450
451
451
452
// Contains a mapping for captures of the form [x], from the declared "x"
452
- // to the captured "x" in the enclosing scope.
453
- llvm::DenseMap<VarDecl *, VarDecl *> sameNamedCaptures;
453
+ // to the captured "x" in the enclosing scope. Also includes shorthand if
454
+ // let bindings.
455
+ llvm::DenseMap<ValueDecl *, ValueDecl *> sameNamedCaptures;
454
456
455
457
bool getNameAndUSR (ValueDecl *D, ExtensionDecl *ExtD,
456
458
StringRef &name, StringRef &USR) {
@@ -559,6 +561,16 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
559
561
return false ;
560
562
}
561
563
564
+ ValueDecl *firstDecl (ValueDecl *D) {
565
+ while (true ) {
566
+ auto captured = sameNamedCaptures.find (D);
567
+ if (captured == sameNamedCaptures.end ())
568
+ break ;
569
+ D = captured->second ;
570
+ }
571
+ return D;
572
+ }
573
+
562
574
public:
563
575
IndexSwiftASTWalker (IndexDataConsumer &IdxConsumer, ASTContext &Ctx,
564
576
SourceFile *SF = nullptr )
@@ -706,22 +718,11 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
706
718
if (Cancelled)
707
719
return false ;
708
720
709
- // Record any captures of the form [x], herso we can treat
710
- if (auto captureList = dyn_cast<CaptureListExpr>(E)) {
711
- for (const auto &capture : captureList->getCaptureList ()) {
712
- auto declaredVar = capture.getVar ();
713
- if (capture.PBD ->getEqualLoc (0 ).isValid ())
714
- continue ;
715
-
716
- VarDecl *capturedVar = nullptr ;
717
- if (auto init = capture.PBD ->getInit (0 )) {
718
- if (auto declRef = dyn_cast<DeclRefExpr>(init))
719
- capturedVar = dyn_cast_or_null<VarDecl>(declRef->getDecl ());
720
- }
721
-
722
- if (capturedVar) {
723
- sameNamedCaptures[declaredVar] = capturedVar;
724
- }
721
+ // Record any same named captures/shorthand if let bindings so we can
722
+ // treat their references as references to the original decl.
723
+ if (auto *captureList = dyn_cast<CaptureListExpr>(E)) {
724
+ for (auto shadows : getShorthandShadows (captureList)) {
725
+ sameNamedCaptures[shadows.first ] = shadows.second ;
725
726
}
726
727
}
727
728
@@ -739,6 +740,20 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
739
740
return true ;
740
741
}
741
742
743
+ bool walkToStmtPre (Stmt *stmt) override {
744
+ if (Cancelled)
745
+ return false ;
746
+
747
+ // Record any same named captures/shorthand if let bindings so we can
748
+ // treat their references as references to the original decl.
749
+ if (auto *condition = dyn_cast<LabeledConditionalStmt>(stmt)) {
750
+ for (auto shadows : getShorthandShadows (condition)) {
751
+ sameNamedCaptures[shadows.first ] = shadows.second ;
752
+ }
753
+ }
754
+ return true ;
755
+ }
756
+
742
757
bool walkToTypeReprPre (TypeRepr *T) override {
743
758
if (Cancelled)
744
759
return false ;
@@ -820,6 +835,11 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
820
835
if (isRepressed (Loc) || Loc.isInvalid ())
821
836
return true ;
822
837
838
+ // Dig back to the original captured variable
839
+ if (auto *VD = dyn_cast<VarDecl>(D)) {
840
+ D = firstDecl (D);
841
+ }
842
+
823
843
IndexSymbol Info;
824
844
825
845
if (Data.isImplicit )
@@ -1459,6 +1479,24 @@ bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
1459
1479
}
1460
1480
1461
1481
bool IndexSwiftASTWalker::report (ValueDecl *D) {
1482
+ auto *shadowedDecl = firstDecl (D);
1483
+ if (D != shadowedDecl) {
1484
+ // Report a reference to the shadowed decl
1485
+ SourceLoc loc = D->getNameLoc ();
1486
+
1487
+ IndexSymbol info;
1488
+ if (!reportRef (shadowedDecl, loc, info, AccessKind::Read))
1489
+ return false ;
1490
+
1491
+ // Suppress the reference if there is any (it is implicit and hence
1492
+ // already skipped in the shorthand if let case, but explicit in the
1493
+ // captured case).
1494
+ repressRefAtLoc (loc);
1495
+
1496
+ // Skip the definition of a shadowed decl
1497
+ return true ;
1498
+ }
1499
+
1462
1500
if (startEntityDecl (D)) {
1463
1501
// Pass accessors.
1464
1502
if (auto StoreD = dyn_cast<AbstractStorageDecl>(D)) {
@@ -1632,15 +1670,6 @@ bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
1632
1670
if (auto *VD = dyn_cast<VarDecl>(D)) {
1633
1671
// Always base the symbol information on the canonical VarDecl
1634
1672
D = VD->getCanonicalVarDecl ();
1635
-
1636
- // Dig back to the original captured variable.
1637
- while (true ) {
1638
- auto captured = sameNamedCaptures.find (cast<VarDecl>(D));
1639
- if (captured == sameNamedCaptures.end ())
1640
- break ;
1641
-
1642
- D = captured->second ;
1643
- }
1644
1673
}
1645
1674
1646
1675
Info.decl = D;
0 commit comments