@@ -6747,6 +6747,28 @@ void deliverUnresolvedMemberResults(
67476747 deliverCompletionResults (CompletionCtx, Lookup, DC, Consumer);
67486748}
67496749
6750+ void deliverKeyPathResults (
6751+ ArrayRef<KeyPathTypeCheckCompletionCallback::Result> Results,
6752+ DeclContext *DC, SourceLoc DotLoc,
6753+ ide::CodeCompletionContext &CompletionCtx,
6754+ CodeCompletionConsumer &Consumer) {
6755+ ASTContext &Ctx = DC->getASTContext ();
6756+ CompletionLookup Lookup (CompletionCtx.getResultSink (), Ctx, DC,
6757+ &CompletionCtx);
6758+
6759+ if (DotLoc.isValid ()) {
6760+ Lookup.setHaveDot (DotLoc);
6761+ }
6762+ Lookup.shouldCheckForDuplicates (Results.size () > 1 );
6763+
6764+ for (auto &Result : Results) {
6765+ Lookup.setIsSwiftKeyPathExpr (Result.OnRoot );
6766+ Lookup.getValueExprCompletions (Result.BaseType );
6767+ }
6768+
6769+ deliverCompletionResults (CompletionCtx, Lookup, DC, Consumer);
6770+ }
6771+
67506772void deliverDotExprResults (
67516773 ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
67526774 Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
@@ -6838,6 +6860,21 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
68386860 CompletionContext, Consumer);
68396861 return true ;
68406862 }
6863+ case CompletionKind::KeyPathExprSwift: {
6864+ assert (CurDeclContext);
6865+
6866+ // CodeCompletionCallbacks::completeExprKeyPath takes a \c KeyPathExpr,
6867+ // so we can safely cast the \c ParsedExpr back to a \c KeyPathExpr.
6868+ auto KeyPath = cast<KeyPathExpr>(ParsedExpr);
6869+ KeyPathTypeCheckCompletionCallback Lookup (KeyPath);
6870+ llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector (
6871+ Context.CompletionCallback , &Lookup);
6872+ typeCheckContextAt (CurDeclContext, CompletionLoc);
6873+
6874+ deliverKeyPathResults (Lookup.getResults (), CurDeclContext, DotLoc,
6875+ CompletionContext, Consumer);
6876+ return true ;
6877+ }
68416878 default :
68426879 return false ;
68436880 }
@@ -6958,60 +6995,10 @@ void CodeCompletionCallbacksImpl::doneParsing() {
69586995 case CompletionKind::None:
69596996 case CompletionKind::DotExpr:
69606997 case CompletionKind::UnresolvedMember:
6998+ case CompletionKind::KeyPathExprSwift:
69616999 llvm_unreachable (" should be already handled" );
69627000 return ;
69637001
6964- case CompletionKind::KeyPathExprSwift: {
6965- auto KPE = dyn_cast<KeyPathExpr>(ParsedExpr);
6966- auto BGT = (*ExprType)->getAs <BoundGenericType>();
6967- if (!KPE || !BGT || BGT->getGenericArgs ().size () != 2 )
6968- break ;
6969- assert (!KPE->isObjC ());
6970-
6971- if (DotLoc.isValid ())
6972- Lookup.setHaveDot (DotLoc);
6973-
6974- bool OnRoot = !KPE->getComponents ().front ().isValid ();
6975- Lookup.setIsSwiftKeyPathExpr (OnRoot);
6976-
6977- Type baseType = BGT->getGenericArgs ()[OnRoot ? 0 : 1 ];
6978- if (OnRoot && baseType->is <UnresolvedType>()) {
6979- // Infer the root type of the keypath from the context type.
6980- ExprContextInfo ContextInfo (CurDeclContext, ParsedExpr);
6981- for (auto T : ContextInfo.getPossibleTypes ()) {
6982- if (auto unwrapped = T->getOptionalObjectType ())
6983- T = unwrapped;
6984-
6985- // If the context type is any of the KeyPath types, use it.
6986- if (T->getAnyNominal () && T->getAnyNominal ()->getKeyPathTypeKind () &&
6987- !T->hasUnresolvedType () && T->is <BoundGenericType>()) {
6988- baseType = T->castTo <BoundGenericType>()->getGenericArgs ()[0 ];
6989- break ;
6990- }
6991-
6992- // KeyPath can be used as a function that receives its root type.
6993- if (T->is <AnyFunctionType>()) {
6994- auto *fnType = T->castTo <AnyFunctionType>();
6995- if (fnType->getNumParams () == 1 ) {
6996- const AnyFunctionType::Param ¶m = fnType->getParams ()[0 ];
6997- baseType = param.getParameterType ();
6998- break ;
6999- }
7000- }
7001- }
7002- }
7003- if (!OnRoot && KPE->getComponents ().back ().getKind () ==
7004- KeyPathExpr::Component::Kind::OptionalWrap) {
7005- // KeyPath expr with '?' (e.g. '\Ty.[0].prop?.another').
7006- // Although expected type is optional, we should unwrap it because it's
7007- // unwrapped.
7008- baseType = baseType->getOptionalObjectType ();
7009- }
7010-
7011- Lookup.getValueExprCompletions (baseType);
7012- break ;
7013- }
7014-
70157002 case CompletionKind::StmtOrExpr:
70167003 case CompletionKind::ForEachSequence:
70177004 case CompletionKind::PostfixExprBeginning: {
0 commit comments