Skip to content

Commit 6af24d0

Browse files
committed
[index] Fix dynamicMemberLookup subscript reference implicit role
When building the implicit subscript expression, set the "implicit" bit correctly and pass it through in the indexer so that we get implicit refernces to the subscript. This would be useful for e.g. searching for all uses of the dynamic subscript.
1 parent 0224d40 commit 6af24d0

File tree

10 files changed

+56
-35
lines changed

10 files changed

+56
-35
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ enum class SemaReferenceKind : uint8_t {
4141
struct ReferenceMetaData {
4242
SemaReferenceKind Kind;
4343
llvm::Optional<AccessKind> AccKind;
44-
ReferenceMetaData(SemaReferenceKind Kind, llvm::Optional<AccessKind> AccKind) :
45-
Kind(Kind), AccKind(AccKind) {}
44+
bool isImplicit = false;
45+
ReferenceMetaData(SemaReferenceKind Kind, llvm::Optional<AccessKind> AccKind,
46+
bool isImplicit = false)
47+
: Kind(Kind), AccKind(AccKind), isImplicit(isImplicit) {}
4648
};
4749

4850
/// An abstract class used to traverse an AST.

include/swift/IDE/SourceEntityWalker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ class SourceEntityWalker {
113113
///
114114
/// \param D the referenced decl.
115115
/// \param Range the source range of the source reference.
116-
/// \param AccKind whether this is a read, write or read/write access.
116+
/// \param Data whether this is a read, write or read/write access, etc.
117117
/// \param IsOpenBracket this is \c true when the method is called on an
118118
/// open bracket.
119119
virtual bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
120-
Optional<AccessKind> AccKind,
120+
ReferenceMetaData Data,
121121
bool IsOpenBracket);
122122

123123
/// This method is called for each keyword argument in a call expression.

include/swift/IDE/Utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class CursorInfoResolver : public SourceEntityWalker {
231231
bool tryResolve(ModuleEntity Mod, SourceLoc Loc);
232232
bool tryResolve(Stmt *St);
233233
bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
234-
Optional<AccessKind> AccKind,
234+
ReferenceMetaData Data,
235235
bool IsOpenBracket) override;
236236
};
237237

lib/IDE/SourceEntityWalker.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ class SemaAnnotator : public ASTWalker {
7070
bool passReference(ModuleEntity Mod, std::pair<Identifier, SourceLoc> IdLoc);
7171

7272
bool passSubscriptReference(ValueDecl *D, SourceLoc Loc,
73-
Optional<AccessKind> AccKind,
74-
bool IsOpenBracket);
73+
ReferenceMetaData Data, bool IsOpenBracket);
7574

7675
bool passCallArgNames(Expr *Fn, TupleExpr *TupleE);
7776

@@ -265,6 +264,7 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
265264
!isa<MakeTemporarilyEscapableExpr>(E) &&
266265
!isa<CollectionUpcastConversionExpr>(E) &&
267266
!isa<OpaqueValueExpr>(E) &&
267+
!isa<SubscriptExpr>(E) &&
268268
!isa<KeyPathExpr>(E) &&
269269
E->isImplicit())
270270
return { true, E };
@@ -327,16 +327,19 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
327327
if (SE->hasDecl())
328328
SubscrD = SE->getDecl().getDecl();
329329

330+
ReferenceMetaData data(SemaReferenceKind::SubscriptRef, OpAccess,
331+
SE->isImplicit());
332+
330333
if (SubscrD) {
331-
if (!passSubscriptReference(SubscrD, E->getLoc(), OpAccess, true))
334+
if (!passSubscriptReference(SubscrD, E->getLoc(), data, true))
332335
return { false, nullptr };
333336
}
334337

335338
if (!SE->getIndex()->walk(*this))
336339
return { false, nullptr };
337340

338341
if (SubscrD) {
339-
if (!passSubscriptReference(SubscrD, E->getEndLoc(), OpAccess, false))
342+
if (!passSubscriptReference(SubscrD, E->getEndLoc(), data, false))
340343
return { false, nullptr };
341344
}
342345

@@ -578,14 +581,14 @@ bool SemaAnnotator::passModulePathElements(
578581
}
579582

580583
bool SemaAnnotator::passSubscriptReference(ValueDecl *D, SourceLoc Loc,
581-
Optional<AccessKind> AccKind,
584+
ReferenceMetaData Data,
582585
bool IsOpenBracket) {
583586
CharSourceRange Range = Loc.isValid()
584587
? CharSourceRange(Loc, 1)
585588
: CharSourceRange();
586589

587-
bool Continue = SEWalker.visitSubscriptReference(D, Range, AccKind,
588-
IsOpenBracket);
590+
bool Continue =
591+
SEWalker.visitSubscriptReference(D, Range, Data, IsOpenBracket);
589592
if (!Continue)
590593
Cancelled = true;
591594
return Continue;
@@ -728,13 +731,14 @@ bool SourceEntityWalker::visitDeclReference(ValueDecl *D, CharSourceRange Range,
728731

729732
bool SourceEntityWalker::visitSubscriptReference(ValueDecl *D,
730733
CharSourceRange Range,
731-
Optional<AccessKind> AccKind,
734+
ReferenceMetaData Data,
732735
bool IsOpenBracket) {
733736
// Most of the clients treat subscript reference the same way as a
734737
// regular reference when called on the open bracket and
735738
// ignore the closing one.
736-
return IsOpenBracket ? visitDeclReference(D, Range, nullptr, nullptr, Type(),
737-
ReferenceMetaData(SemaReferenceKind::SubscriptRef, AccKind)) : true;
739+
return IsOpenBracket
740+
? visitDeclReference(D, Range, nullptr, nullptr, Type(), Data)
741+
: true;
738742
}
739743

740744
bool SourceEntityWalker::visitCallArgName(Identifier Name,

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ bool CursorInfoResolver::tryResolve(Stmt *St) {
118118
return false;
119119
}
120120

121-
bool CursorInfoResolver::visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
122-
Optional<AccessKind> AccKind,
121+
bool CursorInfoResolver::visitSubscriptReference(ValueDecl *D,
122+
CharSourceRange Range,
123+
ReferenceMetaData Data,
123124
bool IsOpenBracket) {
124125
// We should treat both open and close brackets equally
125-
return visitDeclReference(D, Range, nullptr, nullptr, Type(),
126-
ReferenceMetaData(SemaReferenceKind::SubscriptRef, AccKind));
126+
return visitDeclReference(D, Range, nullptr, nullptr, Type(), Data);
127127
}
128128

129129
ResolvedCursorInfo CursorInfoResolver::resolve(SourceLoc Loc) {

lib/Index/Index.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
394394
return true;
395395

396396
IndexSymbol Info;
397+
398+
if (Data.isImplicit)
399+
Info.roles |= (unsigned)SymbolRole::Implicit;
400+
397401
if (CtorTyRef)
398402
if (!reportRef(CtorTyRef, Loc, Info, Data.AccKind))
399403
return false;

test/Index/index_keypath_member_lookup.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func testRead1(r: Lens<Rectangle>, a: Lens<[Int]>) {
4848
// CHECK: [[TL_LINE:[0-9]+]]:7 | param/Swift | r
4949

5050
// => implicit dynamicMember subscript (topLeft)
51-
// CHECK: [[TL_LINE]]:9 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
51+
// CHECK: [[TL_LINE]]:9 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Impl,RelCont | rel: 1
5252
// CHECK: [[TL_LINE]]:9 | instance-method/acc-get/Swift | getter:subscript(dynamicMember:) | [[SUB_GET_USR]] | Ref,Call,Impl,RelRec,RelCall,RelCont | rel: 2
5353

5454
// => property topLeft
@@ -59,15 +59,15 @@ func testRead1(r: Lens<Rectangle>, a: Lens<[Int]>) {
5959
// CHECK: [[BR_LINE:[0-9]+]]:7 | param/Swift | r
6060

6161
// => implicit dynamicMember subscript (bottomRight)
62-
// CHECK: [[BR_LINE]]:9 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
62+
// CHECK: [[BR_LINE]]:9 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Impl,RelCont | rel: 1
6363
// CHECK: [[BR_LINE]]:9 | instance-method/acc-get/Swift | getter:subscript(dynamicMember:) | [[SUB_GET_USR]] | Ref,Call,Impl,RelRec,RelCall,RelCont | rel: 2
6464

6565
// => property bottomRight
6666
// CHECK: [[BR_LINE]]:9 | instance-property/Swift | bottomRight | [[BR_USR]] | Ref,Read,RelCont | rel: 1
6767
// CHECK: [[BR_LINE]]:9 | instance-method/acc-get/Swift | getter:bottomRight | [[BR_GET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
6868

6969
// => implicit dynamicMember subscript (y)
70-
// CHECK: [[BR_LINE]]:21 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
70+
// CHECK: [[BR_LINE]]:21 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Impl,RelCont | rel: 1
7171
// CHECK: [[BR_LINE]]:21 | instance-method/acc-get/Swift | getter:subscript(dynamicMember:) | [[SUB_GET_USR]] | Ref,Call,Impl,RelRec,RelCall,RelCont | rel: 2
7272

7373
// => property y
@@ -78,7 +78,7 @@ func testRead1(r: Lens<Rectangle>, a: Lens<[Int]>) {
7878
// CHECK: [[A_LINE:[0-9]+]]:7 | param/Swift | a
7979

8080
// => implicit dynamicMember subscript
81-
// CHECK: [[A_LINE]]:8 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
81+
// CHECK: [[A_LINE]]:8 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Impl,RelCont | rel: 1
8282
// CHECK: [[A_LINE]]:8 | instance-method/acc-get/Swift | getter:subscript(dynamicMember:) | [[SUB_GET_USR]] | Ref,Call,Impl,RelRec,RelCall,RelCont | rel: 2
8383

8484
// => subscript [Int]
@@ -92,7 +92,7 @@ func testWrite1(r: inout Lens<Rectangle>, p: Lens<Point>, a: inout Lens<[Int]>)
9292
// CHECK: [[WTL_LINE:[0-9]+]]:3 | param/Swift | r
9393

9494
// => implicit dynamicMember subscript (topLeft)
95-
// CHECK: [[WTL_LINE]]:5 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Writ,RelCont | rel: 1
95+
// CHECK: [[WTL_LINE]]:5 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Writ,Impl,RelCont | rel: 1
9696
// CHECK: [[WTL_LINE]]:5 | instance-method/acc-set/Swift | setter:subscript(dynamicMember:) | [[SUB_SET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
9797

9898
// => property topLeft
@@ -103,7 +103,7 @@ func testWrite1(r: inout Lens<Rectangle>, p: Lens<Point>, a: inout Lens<[Int]>)
103103
// CHECK: [[WBR_LINE:[0-9]+]]:3 | param/Swift | r
104104

105105
// => implicit dynamicMember subscript (bottomRight)
106-
// CHECK: [[WBR_LINE:[0-9]+]]:5 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Writ,RelCont | rel: 1
106+
// CHECK: [[WBR_LINE:[0-9]+]]:5 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,Writ,Impl,RelCont | rel: 1
107107
// CHECK: [[WBR_LINE:[0-9]+]]:5 | instance-method/acc-get/Swift | getter:subscript(dynamicMember:) | [[SUB_GET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
108108
// CHECK: [[WBR_LINE:[0-9]+]]:5 | instance-method/acc-set/Swift | setter:subscript(dynamicMember:) | [[SUB_SET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
109109

@@ -113,7 +113,7 @@ func testWrite1(r: inout Lens<Rectangle>, p: Lens<Point>, a: inout Lens<[Int]>)
113113
// CHECK: [[WBR_LINE:[0-9]+]]:5 | instance-method/acc-set/Swift | setter:bottomRight | [[BR_SET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
114114

115115
// => implicit dynamicMember subscript (y)
116-
// CHECK: [[WBR_LINE:[0-9]+]]:17 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Writ,RelCont | rel: 1
116+
// CHECK: [[WBR_LINE:[0-9]+]]:17 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Writ,Impl,RelCont | rel: 1
117117
// CHECK: [[WBR_LINE:[0-9]+]]:17 | instance-method/acc-set/Swift | setter:subscript(dynamicMember:) | [[SUB_SET_USR]] | Ref,Call,Impl,RelCall,RelCont | rel: 1
118118

119119
// => property y
@@ -123,3 +123,17 @@ func testWrite1(r: inout Lens<Rectangle>, p: Lens<Point>, a: inout Lens<[Int]>)
123123
// FIXME: crashes typechecker rdar://problem/49533404
124124
// a[0] = Lens(1)
125125
}
126+
127+
func testExplicit(r: Lens<Rectangle>, a: Lens<[Int]>) {
128+
_ = r[dynamicMember: \.topLeft]
129+
// CHECK: [[ETL_LINE:[0-9]+]]:7 | param/Swift | r
130+
// Not implicit.
131+
// CHECK: [[ETL_LINE]]:8 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
132+
// CHECK: [[ETL_LINE]]:26 | instance-property/Swift | topLeft | [[TL_USR]] | Ref,Read,RelCont | rel: 1
133+
134+
_ = a[dynamicMember: \.[0]]
135+
// CHECK: [[EA_LINE:[0-9]+]]:7 | param/Swift | a
136+
// Not implicit.
137+
// CHECK: [[EA_LINE]]:8 | instance-property/subscript/Swift | subscript(dynamicMember:) | [[SUB_USR]] | Ref,Read,RelCont | rel: 1
138+
// CHECK: [[EA_LINE]]:26 | instance-property/subscript/Swift | subscript(_:) | s:SayxSicip | Ref,Read,RelCont | rel: 1
139+
}

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,11 +1038,10 @@ class SourceDocASTWalker : public SourceEntityWalker {
10381038
}
10391039

10401040
bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
1041-
Optional<AccessKind> AccKind,
1041+
ReferenceMetaData Data,
10421042
bool IsOpenBracket) override {
10431043
// Treat both open and close brackets equally
1044-
return visitDeclReference(D, Range, nullptr, nullptr, Type(),
1045-
ReferenceMetaData(SemaReferenceKind::SubscriptRef, AccKind));
1044+
return visitDeclReference(D, Range, nullptr, nullptr, Type(), Data);
10461045
}
10471046

10481047
bool isLocal(Decl *D) const {

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -920,11 +920,10 @@ class SemanticAnnotator : public SourceEntityWalker {
920920
}
921921

922922
bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
923-
Optional<AccessKind> AccKind,
923+
ReferenceMetaData Data,
924924
bool IsOpenBracket) override {
925925
// We should treat both open and close brackets equally
926-
return visitDeclReference(D, Range, nullptr, nullptr, Type(),
927-
ReferenceMetaData(SemaReferenceKind::SubscriptRef, AccKind));
926+
return visitDeclReference(D, Range, nullptr, nullptr, Type(), Data);
928927
}
929928

930929
void annotate(const Decl *D, bool IsRef, CharSourceRange Range) {

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,10 +1439,9 @@ class AnnotationPrinter : public SourceEntityWalker {
14391439
}
14401440

14411441
bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
1442-
Optional<AccessKind> AccKind,
1442+
ReferenceMetaData Data,
14431443
bool IsOpenBracket) override {
1444-
return visitDeclReference(D, Range, nullptr, nullptr, Type(),
1445-
ReferenceMetaData(SemaReferenceKind::SubscriptRef, AccKind));
1444+
return visitDeclReference(D, Range, nullptr, nullptr, Type(), Data);
14461445
}
14471446

14481447
bool visitCallArgName(Identifier Name, CharSourceRange Range,

0 commit comments

Comments
 (0)