Skip to content

Commit e72bc25

Browse files
committed
[CodeCompletion] Fix code suggestions for arguments in vararg followed by normal arg
For a function and call like ```swift func test(_: Foo..., yArg: Baz) {} test(.bar, #^COMPLETE^#) ``` the parser matches the code completion token to the `yArg` with a missing label, because this way all parameters are provided. However, because of this we don’t suggest any variables that could belong the the previous vararg list. To fix this, if we encounter such a situation (argument without label after vararg), manually adjust the code completion token’s position in params to belong to the vararg list. Fixes rdar://76977325 [SR-14515]
1 parent 47ca24d commit e72bc25

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,12 @@ static bool getPositionInParams(DeclContext &DC, Expr *Args, Expr *CCExpr,
795795
if (!SM.isBeforeInBuffer(tuple->getElement(PosInArgs)->getEndLoc(),
796796
CCExpr->getStartLoc())) {
797797
// The arg is after the code completion position. Stop.
798+
if (LastParamWasVariadic && tuple->getElementName(PosInArgs).empty()) {
799+
// If the last parameter was variadic and this argument stands by itself
800+
// without a label, assume that it belongs to the previous vararg
801+
// list.
802+
PosInParams--;
803+
}
798804
break;
799805
}
800806

test/IDE/complete_call_arg.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,9 @@ func testCompleteLabelAfterVararg() {
865865
enum Foo {
866866
case bar
867867
}
868+
enum Baz {
869+
case bazCase
870+
}
868871

869872
struct Rdar76355192 {
870873
func test(_: String, xArg: Foo..., yArg: Foo..., zArg: Foo...) {}
@@ -887,6 +890,37 @@ func testCompleteLabelAfterVararg() {
887890
// COMPLETE_MEMBER_IN_VARARG-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: hash({#(self): Foo#})[#(into: inout Hasher) -> Void#];
888891
// COMPLETE_MEMBER_IN_VARARG: End completions
889892
}
893+
894+
struct Sr14515 {
895+
func test(_: Foo..., yArg: Baz) {}
896+
}
897+
898+
private func testSr14515(value: Sr14515, foo: Foo, baz: Baz) {
899+
value.test(foo, #^COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG^#)
900+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG: Begin completions
901+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG-DAG: Decl[LocalVar]/Local/TypeRelation[Identical]: foo[#Foo#];
902+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG-DAG: Pattern/ExprSpecific: {#yArg: Baz#}[#Baz#];
903+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG: End completions
904+
905+
// The leading dot completion tests that have picked the right type for the argument
906+
value.test(foo, .#^COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG_DOT^#)
907+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG_DOT: Begin completions, 2 items
908+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG_DOT-DAG: Decl[EnumElement]/ExprSpecific/TypeRelation[Identical]: bar[#Foo#];
909+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG_DOT-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: hash({#(self): Foo#})[#(into: inout Hasher) -> Void#];
910+
// COMPLETE_VARARG_FOLLOWED_BY_NORMAL_ARG_DOT: End completions
911+
912+
value.test(foo, yArg: #^COMPLETE_ARG_AFTER_VARARG^#)
913+
// COMPLETE_ARG_AFTER_VARARG: Begin completions
914+
// COMPLETE_ARG_AFTER_VARARG-DAG: Decl[LocalVar]/Local/TypeRelation[Identical]: baz[#Baz#];
915+
// COMPLETE_ARG_AFTER_VARARG-NOT: Pattern/ExprSpecific: {#yArg: Baz#}[#Baz#];
916+
// COMPLETE_ARG_AFTER_VARARG: End completions
917+
918+
value.test(foo, yArg: .#^COMPLETE_ARG_AFTER_VARARG_DOT^#)
919+
// COMPLETE_ARG_AFTER_VARARG_DOT: Begin completions, 2 items
920+
// COMPLETE_ARG_AFTER_VARARG_DOT-DAG: Decl[EnumElement]/ExprSpecific/TypeRelation[Identical]: bazCase[#Baz#];
921+
// COMPLETE_ARG_AFTER_VARARG_DOT-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: hash({#(self): Baz#})[#(into: inout Hasher) -> Void#];
922+
// COMPLETE_ARG_AFTER_VARARG_DOT: End completions
923+
}
890924
}
891925

892926
func testGenericConstructor() {

0 commit comments

Comments
 (0)