@@ -78,6 +78,98 @@ bool ArgumentTypeCheckCompletionCallback::addPossibleParams(
7878 return ShowGlobalCompletions;
7979}
8080
81+ // / Information that \c getSelectedOverloadInfo gathered about a
82+ // / \c SelectedOverload.
83+ struct SelectedOverloadInfo {
84+ // / The function that is being called.
85+ ValueDecl *FuncD = nullptr ;
86+ // / The type of the called function itself (not its result type)
87+ Type FuncTy;
88+ // / The type on which the function is being called. \c null if the function is
89+ // / a free function.
90+ Type CallBaseTy;
91+ };
92+
93+ // / Extract additional information about the overload that is being called by
94+ // / \p CalleeLocator.
95+ SelectedOverloadInfo getSelectedOverloadInfo (const Solution &S,
96+ ConstraintLocator *CalleeLocator) {
97+ auto &CS = S.getConstraintSystem ();
98+
99+ SelectedOverloadInfo Result;
100+
101+ auto SelectedOverload = S.getOverloadChoiceIfAvailable (CalleeLocator);
102+ if (!SelectedOverload) {
103+ return Result;
104+ }
105+
106+ switch (SelectedOverload->choice .getKind ()) {
107+ case OverloadChoiceKind::KeyPathApplication:
108+ case OverloadChoiceKind::Decl:
109+ case OverloadChoiceKind::DeclViaDynamic:
110+ case OverloadChoiceKind::DeclViaBridge:
111+ case OverloadChoiceKind::DeclViaUnwrappedOptional: {
112+ Result.CallBaseTy = SelectedOverload->choice .getBaseType ();
113+ if (Result.CallBaseTy ) {
114+ Result.CallBaseTy = S.simplifyType (Result.CallBaseTy )->getRValueType ();
115+ }
116+
117+ Result.FuncD = SelectedOverload->choice .getDeclOrNull ();
118+ Result.FuncTy =
119+ S.simplifyTypeForCodeCompletion (SelectedOverload->openedType );
120+
121+ // For completion as the arg in a call to the implicit [keypath: _]
122+ // subscript the solver can't know what kind of keypath is expected without
123+ // an actual argument (e.g. a KeyPath vs WritableKeyPath) so it ends up as a
124+ // hole. Just assume KeyPath so we show the expected keypath's root type to
125+ // users rather than '_'.
126+ if (SelectedOverload->choice .getKind () ==
127+ OverloadChoiceKind::KeyPathApplication) {
128+ auto Params = Result.FuncTy ->getAs <AnyFunctionType>()->getParams ();
129+ if (Params.size () == 1 &&
130+ Params[0 ].getPlainType ()->is <UnresolvedType>()) {
131+ auto *KPDecl = CS.getASTContext ().getKeyPathDecl ();
132+ Type KPTy =
133+ KPDecl->mapTypeIntoContext (KPDecl->getDeclaredInterfaceType ());
134+ Type KPValueTy = KPTy->castTo <BoundGenericType>()->getGenericArgs ()[1 ];
135+ KPTy = BoundGenericType::get (KPDecl, Type (),
136+ {Result.CallBaseTy , KPValueTy});
137+ Result.FuncTy =
138+ FunctionType::get ({Params[0 ].withType (KPTy)}, KPValueTy);
139+ }
140+ }
141+ break ;
142+ }
143+ case OverloadChoiceKind::KeyPathDynamicMemberLookup: {
144+ auto *fnType = SelectedOverload->openedType ->castTo <FunctionType>();
145+ assert (fnType->getParams ().size () == 1 &&
146+ " subscript always has one argument" );
147+ // Parameter type is KeyPath<T, U> where `T` is a root type
148+ // and U is a leaf type (aka member type).
149+ auto keyPathTy =
150+ fnType->getParams ()[0 ].getPlainType ()->castTo <BoundGenericType>();
151+
152+ auto *keyPathDecl = keyPathTy->getAnyNominal ();
153+ assert (isKnownKeyPathType (keyPathTy) &&
154+ " parameter is supposed to be a keypath" );
155+
156+ auto KeyPathDynamicLocator = CS.getConstraintLocator (
157+ CalleeLocator, LocatorPathElt::KeyPathDynamicMember (keyPathDecl));
158+ Result = getSelectedOverloadInfo (S, KeyPathDynamicLocator);
159+ break ;
160+ }
161+ case OverloadChoiceKind::DynamicMemberLookup:
162+ case OverloadChoiceKind::TupleIndex:
163+ // If it's DynamicMemberLookup, we don't know which function is being
164+ // called, so we can't extract any information from it.
165+ // TupleIndex isn't a function call and is not relevant for argument
166+ // completion because it doesn't take arguments.
167+ break ;
168+ }
169+
170+ return Result;
171+ }
172+
81173void ArgumentTypeCheckCompletionCallback::sawSolutionImpl (const Solution &S) {
82174 Type ExpectedTy = getTypeForCompletion (S, CompletionExpr);
83175
@@ -104,41 +196,8 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
104196
105197 auto *CallLocator = CS.getConstraintLocator (ParentCall);
106198 auto *CalleeLocator = S.getCalleeLocator (CallLocator);
107- ValueDecl *FuncD = nullptr ;
108- Type FuncTy;
109- Type CallBaseTy;
110- // If we are calling a closure in-place there is no overload choice, but we
111- // still have all the other required information (like the argument's
112- // expected type) to provide useful code completion results.
113- if (auto SelectedOverload = S.getOverloadChoiceIfAvailable (CalleeLocator)) {
114-
115- CallBaseTy = SelectedOverload->choice .getBaseType ();
116- if (CallBaseTy) {
117- CallBaseTy = S.simplifyType (CallBaseTy)->getRValueType ();
118- }
119-
120- FuncD = SelectedOverload->choice .getDeclOrNull ();
121- FuncTy = S.simplifyTypeForCodeCompletion (SelectedOverload->openedType );
122199
123- // For completion as the arg in a call to the implicit [keypath: _]
124- // subscript the solver can't know what kind of keypath is expected without
125- // an actual argument (e.g. a KeyPath vs WritableKeyPath) so it ends up as a
126- // hole. Just assume KeyPath so we show the expected keypath's root type to
127- // users rather than '_'.
128- if (SelectedOverload->choice .getKind () ==
129- OverloadChoiceKind::KeyPathApplication) {
130- auto Params = FuncTy->getAs <AnyFunctionType>()->getParams ();
131- if (Params.size () == 1 &&
132- Params[0 ].getPlainType ()->is <UnresolvedType>()) {
133- auto *KPDecl = CS.getASTContext ().getKeyPathDecl ();
134- Type KPTy =
135- KPDecl->mapTypeIntoContext (KPDecl->getDeclaredInterfaceType ());
136- Type KPValueTy = KPTy->castTo <BoundGenericType>()->getGenericArgs ()[1 ];
137- KPTy = BoundGenericType::get (KPDecl, Type (), {CallBaseTy, KPValueTy});
138- FuncTy = FunctionType::get ({Params[0 ].withType (KPTy)}, KPValueTy);
139- }
140- }
141- }
200+ auto Info = getSelectedOverloadInfo (S, CalleeLocator);
142201
143202 // Find the parameter the completion was bound to (if any), as well as which
144203 // parameters are already bound (so we don't suggest them even when the args
@@ -174,9 +233,6 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
174233 ClaimedParams.insert (i);
175234 }
176235 }
177- } else {
178- // FIXME: We currently don't look through @dynamicMemberLookup applications
179- // for subscripts (rdar://90363138)
180236 }
181237
182238 bool HasLabel = false ;
@@ -190,8 +246,9 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
190246
191247 // If this is a duplicate of any other result, ignore this solution.
192248 if (llvm::any_of (Results, [&](const Result &R) {
193- return R.FuncD == FuncD && nullableTypesEqual (R.FuncTy , FuncTy) &&
194- nullableTypesEqual (R.BaseType , CallBaseTy) &&
249+ return R.FuncD == Info.FuncD &&
250+ nullableTypesEqual (R.FuncTy , Info.FuncTy ) &&
251+ nullableTypesEqual (R.BaseType , Info.CallBaseTy ) &&
195252 R.ParamIdx == ParamIdx &&
196253 R.IsNoninitialVariadic == IsNoninitialVariadic;
197254 })) {
@@ -201,9 +258,9 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
201258 llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes;
202259 getSolutionSpecificVarTypes (S, SolutionSpecificVarTypes);
203260
204- Results.push_back ({ExpectedTy, isa<SubscriptExpr>(ParentCall), FuncD, FuncTy ,
205- ArgIdx, ParamIdx, std::move (ClaimedParams),
206- IsNoninitialVariadic, CallBaseTy, HasLabel, IsAsync,
261+ Results.push_back ({ExpectedTy, isa<SubscriptExpr>(ParentCall), Info. FuncD ,
262+ Info. FuncTy , ArgIdx, ParamIdx, std::move (ClaimedParams),
263+ IsNoninitialVariadic, Info. CallBaseTy , HasLabel, IsAsync,
207264 SolutionSpecificVarTypes});
208265}
209266
0 commit comments