Skip to content

Commit 26123f0

Browse files
committed
[CodeCompletion] Don't show protocol extension only members in override
Protocol extension only members are not customization point. Code completion should not suggest them in override/conformance completion. rdar://problem/53591636 (cherry picked from commit ab7ba4c)
1 parent a0a432e commit 26123f0

File tree

8 files changed

+96
-26
lines changed

8 files changed

+96
-26
lines changed

include/swift/AST/NameLookup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ void lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer,
473473
const DeclContext *CurrDC,
474474
bool includeInstanceMembers,
475475
bool includeDerivedRequirements,
476+
bool includeProtocolExtensionMembers,
476477
GenericSignatureBuilder *GSB = nullptr);
477478

478479
namespace namelookup {

lib/IDE/CodeCompletion.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,7 +3555,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35553555
if (Type Unwrapped = ExprType->getOptionalObjectType()) {
35563556
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
35573557
IncludeInstanceMembers,
3558-
/*includeDerivedRequirements*/false);
3558+
/*includeDerivedRequirements*/false,
3559+
/*includeProtocolExtensionMembers*/true);
35593560
return true;
35603561
}
35613562
assert(IsUnwrappedOptional && "IUOs should be optional if not bound/forced");
@@ -3576,7 +3577,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35763577
if (!tryTupleExprCompletions(Unwrapped)) {
35773578
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
35783579
IncludeInstanceMembers,
3579-
/*includeDerivedRequirements*/false);
3580+
/*includeDerivedRequirements*/false,
3581+
/*includeProtocolExtensionMembers*/true);
35803582
}
35813583
}
35823584
return true;
@@ -3647,7 +3649,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
36473649

36483650
lookupVisibleMemberDecls(*this, ExprType, CurrDeclContext,
36493651
IncludeInstanceMembers,
3650-
/*includeDerivedRequirements*/false);
3652+
/*includeDerivedRequirements*/false,
3653+
/*includeProtocolExtensionMembers*/true);
36513654
}
36523655

36533656
void collectOperators(SmallVectorImpl<OperatorDecl *> &results) {
@@ -4123,7 +4126,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
41234126
llvm::SaveAndRestore<bool> SaveUnresolved(IsUnresolvedMember, true);
41244127
lookupVisibleMemberDecls(consumer, baseType, CurrDeclContext,
41254128
/*includeInstanceMembers=*/false,
4126-
/*includeDerivedRequirements*/false);
4129+
/*includeDerivedRequirements*/false,
4130+
/*includeProtocolExtensionMembers*/true);
41274131
}
41284132

41294133
void getUnresolvedMemberCompletions(ArrayRef<Type> Types) {
@@ -4185,7 +4189,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
41854189
lookupVisibleMemberDecls(*this, MetatypeType::get(BaseType),
41864190
CurrDeclContext,
41874191
IncludeInstanceMembers,
4188-
/*includeDerivedRequirements*/false);
4192+
/*includeDerivedRequirements*/false,
4193+
/*includeProtocolExtensionMembers*/false);
41894194
if (BaseType->isAnyExistentialType()) {
41904195
addKeyword("Protocol", MetatypeType::get(BaseType));
41914196
addKeyword("Type", ExistentialMetatypeType::get(BaseType));
@@ -4219,7 +4224,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
42194224
NeedLeadingDot = false;
42204225
lookupVisibleMemberDecls(*this, MetatypeType::get(selfTy),
42214226
CurrDeclContext, IncludeInstanceMembers,
4222-
/*includeDerivedRequirements*/false);
4227+
/*includeDerivedRequirements*/false,
4228+
/*includeProtocolExtensionMembers*/true);
42234229
}
42244230

42254231
static bool canUseAttributeOnDecl(DeclAttrKind DAK, bool IsInSil,
@@ -4888,7 +4894,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
48884894
Type Meta = MetatypeType::get(CurrTy);
48894895
lookupVisibleMemberDecls(*this, Meta, CurrDeclContext,
48904896
/*includeInstanceMembers=*/true,
4891-
/*includeDerivedRequirements*/true);
4897+
/*includeDerivedRequirements*/true,
4898+
/*includeProtocolExtensionMembers*/false);
48924899
addDesignatedInitializers(NTD);
48934900
addAssociatedTypes(NTD);
48944901
}

lib/IDE/ConformingMethodList.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ void ConformingMethodListCallbacks::getMatchingMethods(
165165

166166
lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), CurDeclContext,
167167
/*includeInstanceMembers=*/false,
168-
/*includeDerivedRequirements*/false);
168+
/*includeDerivedRequirements*/false,
169+
/*includeProtocolExtensionMembers*/true);
169170
}
170171

171172
} // anonymous namespace.

lib/IDE/TypeContextInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ void ContextInfoCallbacks::getImplicitMembers(
168168

169169
lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), CurDeclContext,
170170
/*includeInstanceMembers=*/false,
171-
/*includeDerivedRequirements*/false);
171+
/*includeDerivedRequirements*/false,
172+
/*includeProtocolExtensionMembers*/true);
172173
}
173174

174175
void PrintingTypeContextInfoConsumer::handleResults(

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ struct LookupState {
6161
/// This option is only for override completion lookup.
6262
unsigned IncludeDerivedRequirements : 1;
6363

64+
/// Should protocol extension members be included?
65+
unsigned IncludeProtocolExtensionMembers : 1;
66+
6467
LookupState()
6568
: IsQualified(0), IsOnMetatype(0), IsOnSuperclass(0),
6669
InheritsSuperclassInitializers(0), IncludeInstanceMembers(0),
67-
IncludeDerivedRequirements(0) {}
70+
IncludeDerivedRequirements(0), IncludeProtocolExtensionMembers(0) {}
6871

6972
public:
7073
LookupState(const LookupState &) = default;
@@ -91,6 +94,9 @@ struct LookupState {
9194
bool isIncludingDerivedRequirements() const {
9295
return IncludeDerivedRequirements;
9396
}
97+
bool isIncludingProtocolExtensionMembers() const {
98+
return IncludeProtocolExtensionMembers;
99+
}
94100

95101
LookupState withOnMetatype() const {
96102
auto Result = *this;
@@ -127,6 +133,12 @@ struct LookupState {
127133
Result.IncludeDerivedRequirements = 1;
128134
return Result;
129135
}
136+
137+
LookupState withIncludeProtocolExtensionMembers() const {
138+
auto Result = *this;
139+
Result.IncludeProtocolExtensionMembers = 1;
140+
return Result;
141+
}
130142
};
131143
} // end anonymous namespace
132144

@@ -463,13 +475,20 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
463475
};
464476
DeclVisibilityKind ReasonForThisDecl = ReasonForThisProtocol;
465477
if (const auto Witness = NormalConformance->getWitness(VD)) {
466-
if (Witness.getDecl()->getFullName() == VD->getFullName()) {
478+
auto *WD = Witness.getDecl();
479+
if (WD->getFullName() == VD->getFullName()) {
467480
if (LS.isIncludingDerivedRequirements() &&
468481
Reason == DeclVisibilityKind::MemberOfCurrentNominal &&
469-
isDerivedRequirement(Witness.getDecl())) {
482+
isDerivedRequirement(WD)) {
470483
ReasonForThisDecl =
471484
DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal;
485+
} else if (!LS.isIncludingProtocolExtensionMembers() &&
486+
WD->getDeclContext()->getExtendedProtocolDecl()) {
487+
// Don't skip this requiement.
488+
// Witnesses in protocol extensions aren't reported.
472489
} else {
490+
// lookupVisibleMemberDecls() generally prefers witness members
491+
// over requirements.
473492
continue;
474493
}
475494
}
@@ -481,11 +500,13 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
481500
}
482501

483502
// Add members from any extensions.
484-
SmallVector<ValueDecl *, 2> FoundDecls;
485-
doGlobalExtensionLookup(BaseTy, Proto->getDeclaredType(), FoundDecls,
486-
FromContext, LS, ReasonForThisProtocol);
487-
for (auto *VD : FoundDecls)
488-
Consumer.foundDecl(VD, ReasonForThisProtocol);
503+
if (LS.isIncludingProtocolExtensionMembers()) {
504+
SmallVector<ValueDecl *, 2> FoundDecls;
505+
doGlobalExtensionLookup(BaseTy, Proto->getDeclaredType(), FoundDecls,
506+
FromContext, LS, ReasonForThisProtocol);
507+
for (auto *VD : FoundDecls)
508+
Consumer.foundDecl(VD, ReasonForThisProtocol);
509+
}
489510
}
490511
}
491512

@@ -582,6 +603,9 @@ static void lookupVisibleMemberDeclsImpl(
582603
if (LS.isIncludingDerivedRequirements()) {
583604
subLS = subLS.withIncludedDerivedRequirements();
584605
}
606+
if (LS.isIncludingProtocolExtensionMembers()) {
607+
subLS = subLS.withIncludeProtocolExtensionMembers();
608+
}
585609

586610
// Just perform normal dot lookup on the type see if we find extensions or
587611
// anything else. For example, type SomeTy.SomeMember can look up static
@@ -1111,6 +1135,7 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
11111135
GenericParamList *GenericParams = nullptr;
11121136
Type ExtendedType;
11131137
auto LS = LookupState::makeUnqualified();
1138+
LS = LS.withIncludeProtocolExtensionMembers();
11141139

11151140
// Skip initializer contexts, we will not find any declarations there.
11161141
if (isa<Initializer>(DC)) {
@@ -1308,6 +1333,7 @@ void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy,
13081333
const DeclContext *CurrDC,
13091334
bool includeInstanceMembers,
13101335
bool includeDerivedRequirements,
1336+
bool includeProtocolExtensionMembers,
13111337
GenericSignatureBuilder *GSB) {
13121338
assert(CurrDC);
13131339
LookupState ls = LookupState::makeQualified();
@@ -1317,6 +1343,9 @@ void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy,
13171343
if (includeDerivedRequirements) {
13181344
ls = ls.withIncludedDerivedRequirements();
13191345
}
1346+
if (includeProtocolExtensionMembers) {
1347+
ls = ls.withIncludeProtocolExtensionMembers();
1348+
}
13201349

13211350
::lookupVisibleMemberDecls(BaseTy, Consumer, CurrDC, ls,
13221351
DeclVisibilityKind::MemberOfCurrentNominal,

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ void TypeChecker::performTypoCorrection(DeclContext *DC, DeclRefKind refKind,
627627
if (baseTypeOrNull) {
628628
lookupVisibleMemberDecls(consumer, baseTypeOrNull, DC,
629629
/*includeInstanceMembers*/true,
630-
/*includeDerivedRequirements*/false, gsb);
630+
/*includeDerivedRequirements*/false,
631+
/*includeProtocolExtensionMembers*/true, gsb);
631632
} else {
632633
lookupVisibleDecls(consumer, DC, /*top level*/ true,
633634
corrections.Loc.getBaseNameLoc());

test/IDE/complete_from_stdlib.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@
5252
// RUN: %FileCheck %s -check-prefix=PRIVATE_NOMINAL_MEMBERS_10 < %t.members10.txt
5353
// RUN: %FileCheck %s -check-prefix=NO_STDLIB_PRIVATE < %t.members10.txt
5454

55-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURNS_DROPFIRST_SEQUENCE | %FileCheck %s -check-prefix=RETURNS_DROPFIRST_SEQUENCE
56-
5755
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_INT_1 | %FileCheck %s -check-prefix=POSTFIX_RVALUE_INT
5856
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_INT_2 | %FileCheck %s -check-prefix=POSTFIX_LVALUE_INT
5957
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_OPTIONAL_1 | %FileCheck %s -check-prefix=POSTFIX_OPTIONAL
@@ -218,12 +216,6 @@ func testArchetypeReplacement6() {
218216
// PRIVATE_NOMINAL_MEMBERS_10: Begin completions
219217
// PRIVATE_NOMINAL_MEMBERS_10-DAG: Decl[InstanceMethod]/CurrNominal: foo({#(t): P1 & P2#})[#Void#]{{; name=.+}}
220218

221-
// rdar://problem/22334700
222-
struct Test1000 : Sequence {
223-
func #^RETURNS_DROPFIRST_SEQUENCE^#
224-
}
225-
// RETURNS_DROPFIRST_SEQUENCE: Decl[InstanceMethod]/Super: dropFirst(_ k: Int = 1) -> DropFirstSequence<Test1000>
226-
227219
func testPostfixOperator1(_ x: Int) {
228220
x#^POSTFIX_INT_1^#
229221
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token CONFORMANCE_EXT | %FileCheck %s --check-prefix=CONFORMANCE_EXT
2+
3+
protocol P {
4+
init(requirement: Int)
5+
init(customizable: Int)
6+
7+
var requirementVar: Int { get }
8+
var customizableVar: Int { get }
9+
10+
func requirementMethod()
11+
func customizableMethod()
12+
}
13+
14+
extension P {
15+
init(customizable v: Int) { self.init(requirement: v) }
16+
init(nonRequirement v: Int) { self.init(requirement: v) }
17+
18+
var customizableVar: Int { 1 }
19+
var nonRequirementVar: Int { 1 }
20+
21+
func customizableMethod() {}
22+
func nonRequirement() {}
23+
}
24+
25+
struct S: P {
26+
#^CONFORMANCE_EXT^#
27+
28+
// CONFORMANCE_EXT: Begin completions
29+
// CONFORMANCE_EXT-NOT: nonRequirement
30+
// CONFORMANCE_EXT-DAG: Decl[Constructor]/Super: init(requirement: Int) {|};
31+
// CONFORMANCE_EXT-DAG: Decl[Constructor]/Super: init(customizable: Int) {|};
32+
// CONFORMANCE_EXT-DAG: Decl[InstanceVar]/Super: var requirementVar: Int;
33+
// CONFORMANCE_EXT-DAG: Decl[InstanceVar]/Super: var customizableVar: Int;
34+
// CONFORMANCE_EXT-DAG: Decl[InstanceMethod]/Super: func requirementMethod() {|};
35+
// CONFORMANCE_EXT-DAG: Decl[InstanceMethod]/Super: func customizableMethod() {|};
36+
// CONFORMANCE_EXT-NOT: nonRequirement
37+
// CONFORMANCE_EXT: End completions
38+
}

0 commit comments

Comments
 (0)