Skip to content

Commit f6db91e

Browse files
committed
[SourceKit] Ignore references without a location
A keypath using dynamic member lookup results in various `KeyPathExpr` that have components with no location. Ignore these and any other references that have a missing location. Resolves rdar://85237365
1 parent ce77849 commit f6db91e

File tree

9 files changed

+241
-3
lines changed

9 files changed

+241
-3
lines changed

lib/IDE/IDERequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ bool CursorInfoResolver::visitDeclReference(ValueDecl *D,
226226
ReferenceMetaData Data) {
227227
if (isDone())
228228
return false;
229-
if (Data.isImplicit)
229+
if (Data.isImplicit || !Range.isValid())
230230
return true;
231231
return !tryResolve(D, CtorTyRef, ExtTyRef, Range.getStart(), /*IsRef=*/true, T);
232232
}

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
490490
bool visitDeclReference(ValueDecl *D, CharSourceRange Range,
491491
TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
492492
Type T, ReferenceMetaData Data) override {
493-
if (D == Target && !Data.isImplicit) {
493+
if (D == Target && !Data.isImplicit && Range.isValid()) {
494494
Result = Range;
495495
return false;
496496
}

test/IDE/annotation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,8 @@ func testDynamicMemberLookup(r: Lens<Rectangle>) {
366366
_ = r.bottomRight.y
367367
// CHECK: _ = <Param@[[@LINE-4]]:30>r</Param>.<Var@[[@LINE-6]]:7>bottomRight</Var>.<Var@[[@LINE-10]]:7>y</Var>
368368
}
369+
func keyPathTester<V>(keyPath: KeyPath<Lens<Rectangle>, V>) {}
370+
func testKeyPath() {
371+
keyPathTester(keyPath: \.topLeft)
372+
// CHECK: <Func@[[@LINE-3]]:6>keyPathTester</Func>(<Func@[[@LINE-3]]:6#keyPath>keyPath</Func>: \.<Var@[[@LINE-12]]:7>topLeft</Var>)
373+
}

test/SourceKit/CursorInfo/cursor_info_keypath_member_lookup.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ func test(r: Lens<Rectangle>) {
2626
_ = r.bottomRight.y
2727
}
2828

29+
func keyPathTester<V>(keyPath: KeyPath<Lens<Rectangle>, V>) {}
30+
31+
func testKeyPath() {
32+
keyPathTester(keyPath: \.topLeft)
33+
}
34+
2935
// RUN: %sourcekitd-test -req=cursor -pos=18:3 -cursor-action %s -- %s | %FileCheck -check-prefix=SUBSCRIPT %s
3036
// SUBSCRIPT: source.lang.swift.decl.function.subscript (18:3-18:12)
3137
// SUBSCRIPT: subscript(dynamicMember:)
@@ -60,3 +66,12 @@ func test(r: Lens<Rectangle>) {
6066
// YREF: ACTIONS BEGIN
6167
// YREF: source.refactoring.kind.rename.global
6268
// YREF: ACTIONS END
69+
70+
// RUN: %sourcekitd-test -req=cursor -pos=32:28 -cursor-action %s -- %s | %FileCheck -check-prefix=KEYPATH %s
71+
// KEYPATH: source.lang.swift.ref.var.instance
72+
// KEYPATH: topLeft
73+
// KEYPATH: Point
74+
// KEYPATH: ACTIONS BEGIN
75+
// KEYPATH: source.refactoring.kind.rename.global
76+
// KEYPATH: ACTIONS END
77+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
struct Point {
2+
var x: Int
3+
var y: Int
4+
}
5+
6+
struct Rectangle {
7+
var topLeft: Point
8+
var bottomRight: Point
9+
}
10+
11+
@dynamicMemberLookup
12+
struct Lens<T> {
13+
var obj: T
14+
init(_ obj: T) {
15+
self.obj = obj
16+
}
17+
18+
subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
19+
get { return Lens<U>(obj[keyPath: member]) }
20+
set { obj[keyPath: member] = newValue.obj }
21+
}
22+
}
23+
24+
func test(r: Lens<Rectangle>) {
25+
_ = r.topLeft
26+
_ = r.bottomRight.y
27+
}
28+
29+
func keyPathTester<V>(keyPath: KeyPath<Lens<Rectangle>, V>) {}
30+
31+
func testKeyPath() {
32+
keyPathTester(keyPath: \.topLeft)
33+
}
34+
35+
// RUN: %sourcekitd-test -req=sema %s -- %s > %t.response
36+
// RUN: %diff -u %s.response %t.response
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
[
2+
{
3+
key.kind: source.lang.swift.ref.struct,
4+
key.offset: 24,
5+
key.length: 3,
6+
key.is_system: 1
7+
},
8+
{
9+
key.kind: source.lang.swift.ref.struct,
10+
key.offset: 37,
11+
key.length: 3,
12+
key.is_system: 1
13+
},
14+
{
15+
key.kind: source.lang.swift.ref.struct,
16+
key.offset: 78,
17+
key.length: 5
18+
},
19+
{
20+
key.kind: source.lang.swift.ref.struct,
21+
key.offset: 103,
22+
key.length: 5
23+
},
24+
{
25+
key.kind: source.lang.swift.ref.generic_type_param,
26+
key.offset: 161,
27+
key.length: 1
28+
},
29+
{
30+
key.kind: source.lang.swift.ref.generic_type_param,
31+
key.offset: 177,
32+
key.length: 1
33+
},
34+
{
35+
key.kind: source.lang.swift.ref.var.instance,
36+
key.offset: 191,
37+
key.length: 3
38+
},
39+
{
40+
key.kind: source.lang.swift.ref.var.local,
41+
key.offset: 197,
42+
key.length: 3
43+
},
44+
{
45+
key.kind: source.lang.swift.ref.class,
46+
key.offset: 243,
47+
key.length: 15,
48+
key.is_system: 1
49+
},
50+
{
51+
key.kind: source.lang.swift.ref.generic_type_param,
52+
key.offset: 259,
53+
key.length: 1
54+
},
55+
{
56+
key.kind: source.lang.swift.ref.generic_type_param,
57+
key.offset: 262,
58+
key.length: 1
59+
},
60+
{
61+
key.kind: source.lang.swift.ref.struct,
62+
key.offset: 269,
63+
key.length: 4
64+
},
65+
{
66+
key.kind: source.lang.swift.ref.generic_type_param,
67+
key.offset: 274,
68+
key.length: 1
69+
},
70+
{
71+
key.kind: source.lang.swift.ref.struct,
72+
key.offset: 296,
73+
key.length: 4
74+
},
75+
{
76+
key.kind: source.lang.swift.ref.generic_type_param,
77+
key.offset: 301,
78+
key.length: 1
79+
},
80+
{
81+
key.kind: source.lang.swift.ref.var.instance,
82+
key.offset: 304,
83+
key.length: 3
84+
},
85+
{
86+
key.kind: source.lang.swift.ref.var.local,
87+
key.offset: 317,
88+
key.length: 6
89+
},
90+
{
91+
key.kind: source.lang.swift.ref.var.instance,
92+
key.offset: 338,
93+
key.length: 3
94+
},
95+
{
96+
key.kind: source.lang.swift.ref.var.local,
97+
key.offset: 351,
98+
key.length: 6
99+
},
100+
{
101+
key.kind: source.lang.swift.ref.var.local,
102+
key.offset: 361,
103+
key.length: 8
104+
},
105+
{
106+
key.kind: source.lang.swift.ref.var.instance,
107+
key.offset: 370,
108+
key.length: 3
109+
},
110+
{
111+
key.kind: source.lang.swift.ref.struct,
112+
key.offset: 396,
113+
key.length: 4
114+
},
115+
{
116+
key.kind: source.lang.swift.ref.struct,
117+
key.offset: 401,
118+
key.length: 9
119+
},
120+
{
121+
key.kind: source.lang.swift.ref.var.local,
122+
key.offset: 421,
123+
key.length: 1
124+
},
125+
{
126+
key.kind: source.lang.swift.ref.var.instance,
127+
key.offset: 423,
128+
key.length: 7
129+
},
130+
{
131+
key.kind: source.lang.swift.ref.var.local,
132+
key.offset: 437,
133+
key.length: 1
134+
},
135+
{
136+
key.kind: source.lang.swift.ref.var.instance,
137+
key.offset: 439,
138+
key.length: 11
139+
},
140+
{
141+
key.kind: source.lang.swift.ref.var.instance,
142+
key.offset: 451,
143+
key.length: 1
144+
},
145+
{
146+
key.kind: source.lang.swift.ref.class,
147+
key.offset: 487,
148+
key.length: 7,
149+
key.is_system: 1
150+
},
151+
{
152+
key.kind: source.lang.swift.ref.struct,
153+
key.offset: 495,
154+
key.length: 4
155+
},
156+
{
157+
key.kind: source.lang.swift.ref.struct,
158+
key.offset: 500,
159+
key.length: 9
160+
},
161+
{
162+
key.kind: source.lang.swift.ref.generic_type_param,
163+
key.offset: 512,
164+
key.length: 1
165+
},
166+
{
167+
key.kind: source.lang.swift.ref.function.free,
168+
key.offset: 543,
169+
key.length: 13
170+
},
171+
{
172+
key.kind: source.lang.swift.ref.var.instance,
173+
key.offset: 568,
174+
key.length: 7
175+
}
176+
]

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ class SourceDocASTWalker : public SourceEntityWalker {
11431143
bool visitDeclReference(ValueDecl *D, CharSourceRange Range,
11441144
TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef, Type Ty,
11451145
ReferenceMetaData Data) override {
1146-
if (Data.isImplicit)
1146+
if (Data.isImplicit || !Range.isValid())
11471147
return true;
11481148
unsigned StartOffset = getOffset(Range.getStart());
11491149
References.emplace_back(D, StartOffset, Range.getByteLength(), Ty);

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,9 @@ class SemanticAnnotator : public SourceEntityWalker {
959959
}
960960

961961
void annotate(const Decl *D, bool IsRef, CharSourceRange Range) {
962+
if (!Range.isValid())
963+
return;
964+
962965
unsigned ByteOffset = SM.getLocOffsetInBuffer(Range.getStart(), BufferID);
963966
unsigned Length = Range.getByteLength();
964967
auto Kind = CodeCompletionResult::getCodeCompletionDeclKind(D);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,6 +2230,9 @@ class AnnotationPrinter : public SourceEntityWalker {
22302230
}
22312231

22322232
void annotateSourceEntity(const SemanticSourceEntity &Entity) {
2233+
if (!Entity.Range.isValid())
2234+
return;
2235+
22332236
const char *LocPtr =
22342237
BufStart + SM.getLocOffsetInBuffer(Entity.Range.getStart(), BufferID);
22352238

0 commit comments

Comments
 (0)