Skip to content

Commit ed51731

Browse files
authored
Merge pull request swiftlang#33577 from rintaro/5.3-ide-completion-rdar67155695
[5.3][CodeCompletion] Avoid prioritizing unavailable in LookupVisibleDecls
2 parents 4ee498b + 7a82b38 commit ed51731

File tree

2 files changed

+127
-11
lines changed

2 files changed

+127
-11
lines changed

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -941,17 +941,22 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
941941
/*wouldConflictInSwift5*/nullptr,
942942
/*skipProtocolExtensionCheck*/true)) {
943943
FoundConflicting = true;
944-
// Prefer derived requirements over their witnesses.
945-
if (Reason ==
946-
DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal ||
947-
VD->getFormalAccess() > OtherVD->getFormalAccess() ||
948-
//Prefer available one.
949-
(!AvailableAttr::isUnavailable(VD) &&
950-
AvailableAttr::isUnavailable(OtherVD))) {
951-
FilteredResults.remove(
952-
FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable, {}));
953-
FilteredResults.insert(DeclAndReason);
954-
*I = VD;
944+
945+
if (!AvailableAttr::isUnavailable(VD)) {
946+
bool preferVD = (
947+
// Prefer derived requirements over their witnesses.
948+
Reason == DeclVisibilityKind::
949+
MemberOfProtocolDerivedByCurrentNominal ||
950+
// Prefer available one.
951+
AvailableAttr::isUnavailable(OtherVD) ||
952+
// Prefer more accessible one.
953+
VD->getFormalAccess() > OtherVD->getFormalAccess());
954+
if (preferVD) {
955+
FilteredResults.remove(
956+
FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable, {}));
957+
FilteredResults.insert(DeclAndReason);
958+
*I = VD;
959+
}
955960
}
956961
}
957962
}

test/IDE/complete_rdar67155695.swift

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token=PUBLIC | %FileCheck %s --check-prefix=PUBLIC
2+
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token=INTERNAL | %FileCheck %s --check-prefix=INTERNAL
3+
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token=PRIVATE | %FileCheck %s --check-prefix=PRIVATE
4+
5+
public protocol PubP {}
6+
7+
public extension PubP {
8+
func availableP_availableC() {}
9+
10+
func availableP_unavailableC() {}
11+
12+
@available(*, unavailable)
13+
func unavailableP_availableC() {}
14+
15+
@available(*, unavailable)
16+
func unavailableP_unavailableC() {}
17+
}
18+
19+
struct TestForPubP: PubP {
20+
func availableP_availableC() {}
21+
22+
@available(*, unavailable)
23+
func availableP_unavailableC() {}
24+
25+
func unavailableP_availableC() {}
26+
27+
@available(*, unavailable)
28+
func unavailableP_unavailableC() {}
29+
}
30+
31+
func test(val: TestForPubP) {
32+
val.#^PUBLIC^#
33+
// PUBLIC: Begin completions, 4 items
34+
// PUBLIC-DAG: Keyword[self]/CurrNominal: self[#TestForPubP#];
35+
// PUBLIC-DAG: Decl[InstanceMethod]/CurrNominal: unavailableP_availableC()[#Void#];
36+
// PUBLIC-DAG: Decl[InstanceMethod]/Super: availableP_availableC()[#Void#];
37+
// PUBLIC-DAG: Decl[InstanceMethod]/Super: availableP_unavailableC()[#Void#];
38+
// PUBLIC: End completions
39+
}
40+
41+
protocol InternalP {}
42+
43+
extension InternalP {
44+
func availableP_availableC() {}
45+
46+
func availableP_unavailableC() {}
47+
48+
@available(*, unavailable)
49+
func unavailableP_availableC() {}
50+
51+
@available(*, unavailable)
52+
func unavailableP_unavailableC() {}
53+
}
54+
55+
struct TestForInternalP: InternalP {
56+
func availableP_availableC() {}
57+
58+
@available(*, unavailable)
59+
func availableP_unavailableC() {}
60+
61+
func unavailableP_availableC() {}
62+
63+
@available(*, unavailable)
64+
func unavailableP_unavailableC() {}
65+
}
66+
67+
func test(val: TestForInternalP) {
68+
val.#^INTERNAL^#
69+
// INTERNAL: Begin completions, 4 items
70+
// INTERNAL-DAG: Keyword[self]/CurrNominal: self[#TestForInternalP#];
71+
// INTERNAL-DAG: Decl[InstanceMethod]/CurrNominal: availableP_availableC()[#Void#];
72+
// INTERNAL-DAG: Decl[InstanceMethod]/CurrNominal: unavailableP_availableC()[#Void#];
73+
// INTERNAL-DAG: Decl[InstanceMethod]/Super: availableP_unavailableC()[#Void#];
74+
// INTERNAL: End completions
75+
}
76+
77+
private protocol PrivP {}
78+
79+
private extension PrivP {
80+
func availableP_availableC() {}
81+
82+
func availableP_unavailableC() {}
83+
84+
@available(*, unavailable)
85+
func unavailableP_availableC() {}
86+
87+
@available(*, unavailable)
88+
func unavailableP_unavailableC() {}
89+
}
90+
91+
struct TestForPrivP: PrivP {
92+
func availableP_availableC() {}
93+
94+
@available(*, unavailable)
95+
func availableP_unavailableC() {}
96+
97+
func unavailableP_availableC() {}
98+
99+
@available(*, unavailable)
100+
func unavailableP_unavailableC() {}
101+
}
102+
103+
func test(val: TestForPrivP) {
104+
val.#^PRIVATE^#
105+
// PRIVATE: Begin completions, 4 items
106+
// PRIVATE-DAG: Keyword[self]/CurrNominal: self[#TestForPrivP#];
107+
// PRIVATE-DAG: Decl[InstanceMethod]/CurrNominal: availableP_availableC()[#Void#];
108+
// PRIVATE-DAG: Decl[InstanceMethod]/CurrNominal: unavailableP_availableC()[#Void#];
109+
// PRIVATE-DAG: Decl[InstanceMethod]/Super: availableP_unavailableC()[#Void#];
110+
// PRIVATE-DAG: End completions
111+
}

0 commit comments

Comments
 (0)