@@ -745,6 +745,22 @@ static bool getPositionInArgs(DeclContext &DC, Expr *Args, Expr *CCExpr,
745
745
return false ;
746
746
}
747
747
748
+ // / For function call arguments \p Args, return the argument at \p Position
749
+ // / computed by \c getPositionInArgs
750
+ static Expr *getArgAtPosition (Expr *Args, unsigned Position) {
751
+ if (isa<ParenExpr>(Args)) {
752
+ assert (Position == 0 );
753
+ return Args;
754
+ }
755
+
756
+ if (auto *tuple = dyn_cast<TupleExpr>(Args)) {
757
+ return tuple->getElement (Position);
758
+ } else {
759
+ llvm_unreachable (" Unable to retrieve arg at position returned by "
760
+ " getPositionInArgs?" );
761
+ }
762
+ }
763
+
748
764
// / Get index of \p CCExpr in \p Params. Note that the position in \p Params may
749
765
// / be different than the position in \p Args if there are defaulted arguments
750
766
// / in \p Params which don't occur in \p Args.
@@ -848,15 +864,15 @@ class ExprContextAnalyzer {
848
864
bool analyzeApplyExpr (Expr *E) {
849
865
// Collect parameter lists for possible func decls.
850
866
SmallVector<FunctionTypeAndDecl, 2 > Candidates;
851
- Expr *Arg = nullptr ;
867
+ Expr *Args = nullptr ;
852
868
if (auto *applyExpr = dyn_cast<ApplyExpr>(E)) {
853
869
if (!collectPossibleCalleesForApply (*DC, applyExpr, Candidates))
854
870
return false ;
855
- Arg = applyExpr->getArg ();
871
+ Args = applyExpr->getArg ();
856
872
} else if (auto *subscriptExpr = dyn_cast<SubscriptExpr>(E)) {
857
873
if (!collectPossibleCalleesForSubscript (*DC, subscriptExpr, Candidates))
858
874
return false ;
859
- Arg = subscriptExpr->getIndex ();
875
+ Args = subscriptExpr->getIndex ();
860
876
} else {
861
877
llvm_unreachable (" unexpected expression kind" );
862
878
}
@@ -866,14 +882,43 @@ class ExprContextAnalyzer {
866
882
// Determine the position of code completion token in call argument.
867
883
unsigned PositionInArgs;
868
884
bool HasName;
869
- if (!getPositionInArgs (*DC, Arg , ParsedExpr, PositionInArgs, HasName))
885
+ if (!getPositionInArgs (*DC, Args , ParsedExpr, PositionInArgs, HasName))
870
886
return false ;
871
887
872
888
// Collect possible types (or labels) at the position.
873
889
{
874
- bool MayNeedName = !HasName && !E->isImplicit () &&
875
- (isa<CallExpr>(E) | isa<SubscriptExpr>(E) ||
876
- isa<UnresolvedMemberExpr>(E));
890
+ bool MayBeArgForLabeledParam =
891
+ HasName || E->isImplicit () ||
892
+ (!isa<CallExpr>(E) && !isa<SubscriptExpr>(E) &&
893
+ !isa<UnresolvedMemberExpr>(E));
894
+
895
+ // If the completion position cannot be the actual argument, it must be
896
+ // able to be an argument label.
897
+ bool MayBeLabel = !MayBeArgForLabeledParam;
898
+
899
+ // Alternatively, the code completion position may complete to an argument
900
+ // label if we are currently completing variadic args.
901
+ // E.g.
902
+ // func foo(x: Int..., y: Int...) {}
903
+ // foo(x: 1, #^COMPLETE^#)
904
+ // #^COMPLETE^# may complete to either an additional variadic arg or to
905
+ // the argument label `y`.
906
+ //
907
+ // Varargs are represented by a VarargExpansionExpr that contains an
908
+ // ArrayExpr on the call side.
909
+ if (auto Vararg = dyn_cast<VarargExpansionExpr>(
910
+ getArgAtPosition (Args, PositionInArgs))) {
911
+ if (auto Array = dyn_cast_or_null<ArrayExpr>(Vararg->getSubExpr ())) {
912
+ if (Array->getNumElements () > 0 &&
913
+ !isa<CodeCompletionExpr>(Array->getElement (0 ))) {
914
+ // We can only complete as argument label if we have at least one
915
+ // proper vararg before the code completion token. We shouldn't be
916
+ // suggesting labels for:
917
+ // foo(x: #^COMPLETE^#)
918
+ MayBeLabel = true ;
919
+ }
920
+ }
921
+ }
877
922
SmallPtrSet<CanType, 4 > seenTypes;
878
923
llvm::SmallSet<std::pair<Identifier, CanType>, 4 > seenArgs;
879
924
for (auto &typeAndDecl : Candidates) {
@@ -883,7 +928,7 @@ class ExprContextAnalyzer {
883
928
884
929
auto Params = typeAndDecl.Type ->getParams ();
885
930
unsigned PositionInParams;
886
- if (!getPositionInParams (*DC, Arg , ParsedExpr, Params,
931
+ if (!getPositionInParams (*DC, Args , ParsedExpr, Params,
887
932
PositionInParams)) {
888
933
// If the argument doesn't have a matching position in the parameters,
889
934
// indicate that with optional nullptr param.
@@ -907,11 +952,13 @@ class ExprContextAnalyzer {
907
952
paramList && (paramList->get (Pos)->isDefaultArgument () ||
908
953
paramList->get (Pos)->isVariadic ());
909
954
910
- if (paramType.hasLabel () && MayNeedName ) {
955
+ if (MayBeLabel && paramType.hasLabel ()) {
911
956
if (seenArgs.insert ({paramType.getLabel (), ty->getCanonicalType ()})
912
957
.second )
913
958
recordPossibleParam (¶mType, !canSkip);
914
- } else {
959
+ }
960
+
961
+ if (MayBeArgForLabeledParam || !paramType.hasLabel ()) {
915
962
auto argTy = ty;
916
963
if (paramType.isInOut ())
917
964
argTy = InOutType::get (argTy);
0 commit comments