Skip to content

Commit c55d6ce

Browse files
committed
[CodeCompletion] Fix call arguments completion in overloaded case
In `<expr> '(' <code-completion-token>` case, we usually complete call arguments. If '<expr>' isn't typechecked, for example, because of overloading, we used to give up arguments completions. Now, use possible callee informations from the context type analyzer. This increases the chance to provide accurate completions. rdar://problem/43703157
1 parent 8a6c540 commit c55d6ce

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5153,6 +5153,7 @@ class CodeCompletionTypeContextAnalyzer {
51535153
// Results populated by Analyze()
51545154
SmallVector<Type, 2> PossibleTypes;
51555155
SmallVector<StringRef, 2> PossibleNames;
5156+
SmallVector<FunctionTypeAndDecl, 2> PossibleCallees;
51565157

51575158
void recordPossibleType(Type ty) {
51585159
if (!ty || ty->is<ErrorType>())
@@ -5166,7 +5167,7 @@ class CodeCompletionTypeContextAnalyzer {
51665167

51675168
bool collectArgumentExpectation(DeclContext &DC, Expr *E, Expr *CCExpr) {
51685169
// Collect parameter lists for possible func decls.
5169-
SmallVector<FunctionTypeAndDecl, 4> Candidates;
5170+
SmallVector<FunctionTypeAndDecl, 2> Candidates;
51705171
Expr *Arg = nullptr;
51715172
if (auto *applyExpr = dyn_cast<ApplyExpr>(E)) {
51725173
if (!collectPossibleCalleesForApply(DC, applyExpr, Candidates))
@@ -5177,6 +5178,7 @@ class CodeCompletionTypeContextAnalyzer {
51775178
return false;
51785179
Arg = subscriptExpr->getIndex();
51795180
}
5181+
PossibleCallees.append(Candidates.begin(), Candidates.end());
51805182

51815183
// Determine the position of code completion token in call argument.
51825184
unsigned Position;
@@ -5413,6 +5415,9 @@ class CodeCompletionTypeContextAnalyzer {
54135415

54145416
ArrayRef<Type> getPossibleTypes() const { return PossibleTypes; }
54155417
ArrayRef<StringRef> getPossibleNames() const { return PossibleNames; }
5418+
ArrayRef<FunctionTypeAndDecl> getPossibleCallees() const {
5419+
return PossibleCallees;
5420+
}
54165421
};
54175422

54185423
} // end anonymous namespace
@@ -5584,13 +5589,16 @@ void CodeCompletionCallbacksImpl::doneParsing() {
55845589
Lookup.setExpectedTypes(TypeAnalyzer.getPossibleTypes());
55855590
}
55865591

5587-
if (ExprType) {
5588-
if (ShouldCompleteCallPatternAfterParen) {
5592+
if (ShouldCompleteCallPatternAfterParen) {
5593+
if (ExprType) {
55895594
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
55905595
} else {
5591-
// Add argument labels, then fallthrough to get values.
5592-
Lookup.addArgNameCompletionResults(TypeAnalyzer.getPossibleNames());
5596+
for (auto &typeAndDecl : TypeAnalyzer.getPossibleCallees())
5597+
Lookup.getValueExprCompletions(typeAndDecl.first, typeAndDecl.second);
55935598
}
5599+
} else {
5600+
// Add argument labels, then fallthrough to get values.
5601+
Lookup.addArgNameCompletionResults(TypeAnalyzer.getPossibleNames());
55945602
}
55955603

55965604
if (!Lookup.FoundFunctionCalls ||

test/IDE/complete_call_arg.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
// RUN-FIXME: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD2 | %FileCheck %s -check-prefix=OVERLOAD2
1212
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD3 | %FileCheck %s -check-prefix=OVERLOAD3
1313
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD4 | %FileCheck %s -check-prefix=OVERLOAD4
14+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD5 | %FileCheck %s -check-prefix=OVERLOAD5
15+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD6 | %FileCheck %s -check-prefix=OVERLOAD6
16+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERLOAD7 | %FileCheck %s -check-prefix=OVERLOAD6
1417

1518
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER1 | %FileCheck %s -check-prefix=MEMBER1
1619
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER2 | %FileCheck %s -check-prefix=MEMBER2
@@ -215,12 +218,24 @@ class C3 {
215218
func f2() {
216219
foo2(C2I, #^OVERLOAD2^#)
217220
}
218-
func f2() {
221+
func f3() {
219222
foo2(C1I, b1: #^OVERLOAD3^#)
220223
}
221-
func f2() {
224+
func f4() {
222225
foo2(C2I, b2: #^OVERLOAD4^#)
223226
}
227+
228+
func f5() {
229+
foo2(#^OVERLOAD5^#
230+
}
231+
232+
func overloaded(_ a1: C1, b1: C2) {}
233+
func overloaded(a2: C2, b2: C1) {}
234+
235+
func f6(obj: C3) {
236+
overloaded(#^OVERLOAD6^#
237+
obj.overloaded(#^OVERLOAD7^#
238+
}
224239
}
225240

226241
// OVERLOAD1: Begin completions, 1 items
@@ -251,6 +266,20 @@ class C3 {
251266
// FIXME: This should be a negative test case
252267
// NEGATIVE_OVERLOAD4-NOT: Decl[Class]{{.*}} C2
253268

269+
// OVERLOAD5: Begin completions
270+
// OVERLOAD5-DAG: Pattern/CurrModule: ['(']{#(a): C1#}, {#b1: C2#}[')'][#Void#]; name=a: C1, b1: C2
271+
// OVERLOAD5-DAG: Pattern/CurrModule: ['(']{#(a): C2#}, {#b2: C1#}[')'][#Void#]; name=a: C2, b2: C1
272+
// OVERLOAD5-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: C1I[#C1#]; name=C1I
273+
// OVERLOAD5-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: C2I[#C2#]; name=C2I
274+
// OVERLOAD5: End completions
275+
276+
// OVERLOAD6: Begin completions
277+
// OVERLOAD6-DAG: Pattern/CurrModule: ['(']{#(a1): C1#}, {#b1: C2#}[')'][#Void#]; name=a1: C1, b1: C2
278+
// OVERLOAD6-DAG: Pattern/CurrModule: ['(']{#a2: C2#}, {#b2: C1#}[')'][#Void#]; name=a2: C2, b2: C1
279+
// OVERLOAD6-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: C1I[#C1#]; name=C1I
280+
// OVERLOAD6-DAG: Decl[InstanceVar]/CurrNominal: C2I[#C2#]; name=C2I
281+
// OVERLOAD6: End completions
282+
254283
class C4 {
255284
func f1(_ G : Gen) {
256285
foo(1, b1: G.#^MEMBER1^#

0 commit comments

Comments
 (0)