Skip to content

Commit 862e14e

Browse files
committed
[CursorInfo] De-duplicate reported cursor info results
The constraint system might produce multiple solutions that all reference the same declaration. We should only report the declaration once in those cases instead of multiple times. rdar://111814276
1 parent 93e209c commit 862e14e

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

lib/IDE/CursorInfo.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
277277
bool IsDynamicRef;
278278
/// The declaration that is being referenced. Will never be \c nullptr.
279279
ValueDecl *ReferencedDecl;
280+
281+
bool operator==(const CursorInfoDeclReference &Other) const {
282+
return nullableTypesEqual(BaseType, Other.BaseType) &&
283+
IsDynamicRef == Other.IsDynamicRef &&
284+
ReferencedDecl == Other.ReferencedDecl;
285+
}
280286
};
281287

282288
private:
@@ -326,8 +332,16 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
326332
[&S](Expr *E) { return S.getResolvedType(E); });
327333
}
328334

329-
Results.push_back(
330-
{OverloadInfo.BaseTy, IsDynamicRef, OverloadInfo.getValue()});
335+
CursorInfoDeclReference NewResult = {OverloadInfo.BaseTy, IsDynamicRef,
336+
OverloadInfo.getValue()};
337+
338+
if (llvm::any_of(Results, [&](const CursorInfoDeclReference &R) {
339+
return R == NewResult;
340+
})) {
341+
return;
342+
}
343+
344+
Results.push_back(NewResult);
331345
}
332346

333347
public:

test/SourceKit/CursorInfo/cursor_ambiguous.swift

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,35 @@ func testAmbiguousFunctionReference() {
22
func foo(a: Int) {}
33
func foo(a: String) {}
44

5-
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):7 %s -- %s | %FileCheck %s
5+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):7 %s -- %s | %FileCheck %s --check-prefix LOCAL_FUNC
66
_ = foo
77

8-
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):7 %s -- %s | %FileCheck %s
8+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):7 %s -- %s | %FileCheck %s --check-prefix LOCAL_FUNC
99
_ = foo(a: UInt(1))
10+
11+
// LOCAL_FUNC: source.lang.swift.ref.function.free
12+
// LOCAL_FUNC: <Declaration>func foo(a: <Type usr="s:Si">Int</Type>)</Declaration>
13+
// LOCAL_FUNC: SECONDARY SYMBOLS BEGIN
14+
// LOCAL_FUNC: source.lang.swift.ref.function.free
15+
// LOCAL_FUNC: <Declaration>func foo(a: <Type usr="s:SS">String</Type>)</Declaration>
16+
// LOCAL_FUNC: SECONDARY SYMBOLS END
1017
}
1118

12-
// CHECK: source.lang.swift.ref.function.free (2:8-2:19)
13-
// CHECK: <Declaration>func foo(a: <Type usr="s:Si">Int</Type>)</Declaration>
14-
// CHECK: SECONDARY SYMBOLS BEGIN
15-
// CHECK: source.lang.swift.ref.function.free (3:8-3:22)
16-
// CHECK: <Declaration>func foo(a: <Type usr="s:SS">String</Type>)</Declaration>
17-
// CHECK: SECONDARY SYMBOLS END
19+
20+
21+
struct TestDeduplicateResults {
22+
// The constraints system produces multiple solutions here for the argument type but
23+
// all reference the same declaration. Check that we de-duplicate them and that we
24+
// don’t report any secondary sybmols.
25+
static func staticFunc(_ duration: Int) {}
26+
27+
func test() {
28+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):10 %s -- %s | %FileCheck %s --check-prefix STATIC_FUNC
29+
Self.staticFunc(1 * 1e9)
30+
}
31+
32+
// STATIC_FUNC: source.lang.swift.ref.function.method.static
33+
// STATIC_FUNC: <Declaration>static func staticFunc(_ duration: <Type usr="s:Si">Int</Type>)</Declaration>
34+
// STATIC_FUNC: SECONDARY SYMBOLS BEGIN
35+
// STATIC_FUNC-NEXT: SECONDARY SYMBOLS END
36+
}

0 commit comments

Comments
 (0)