@@ -1171,14 +1171,14 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
1171
1171
//
1172
1172
// { ... -> Int in x } // x must be Int
1173
1173
// { ... -> () in return x } // x must be Void
1174
- if (typeContext.isSingleExpressionBody && expectedTy->isVoid ())
1174
+ if (typeContext.isImplicitSingleExpressionReturn && expectedTy->isVoid ())
1175
1175
continue ;
1176
1176
1177
1177
Result = std::max (Result, calculateTypeRelation (Ty, expectedTy, DC));
1178
1178
1179
1179
// Map invalid -> unrelated when in a single-expression body, since the
1180
1180
// input may be incomplete.
1181
- if (typeContext.isSingleExpressionBody &&
1181
+ if (typeContext.isImplicitSingleExpressionReturn &&
1182
1182
Result == CodeCompletionResult::ExpectedTypeRelation::Invalid)
1183
1183
Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
1184
1184
}
@@ -1958,9 +1958,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1958
1958
IsStaticMetatype = value;
1959
1959
}
1960
1960
1961
- void setExpectedTypes (ArrayRef<Type> Types, bool isSingleExpressionBody,
1961
+ void setExpectedTypes (ArrayRef<Type> Types,
1962
+ bool isImplicitSingleExpressionReturn,
1962
1963
bool preferNonVoid = false ) {
1963
- expectedTypeContext.isSingleExpressionBody = isSingleExpressionBody;
1964
+ expectedTypeContext.isImplicitSingleExpressionReturn =
1965
+ isImplicitSingleExpressionReturn;
1964
1966
expectedTypeContext.preferNonVoid = preferNonVoid;
1965
1967
expectedTypeContext.possibleTypes .clear ();
1966
1968
expectedTypeContext.possibleTypes .reserve (Types.size ());
@@ -1976,7 +1978,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1976
1978
CodeCompletionContext::TypeContextKind typeContextKind () const {
1977
1979
if (expectedTypeContext.empty () && !expectedTypeContext.preferNonVoid ) {
1978
1980
return CodeCompletionContext::TypeContextKind::None;
1979
- } else if (expectedTypeContext.isSingleExpressionBody ) {
1981
+ } else if (expectedTypeContext.isImplicitSingleExpressionReturn ) {
1980
1982
return CodeCompletionContext::TypeContextKind::SingleExpressionBody;
1981
1983
} else {
1982
1984
return CodeCompletionContext::TypeContextKind::Required;
@@ -4340,6 +4342,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
4340
4342
if (!T->mayHaveMembers ())
4341
4343
return ;
4342
4344
4345
+ if (auto objT = T->getOptionalObjectType ()) {
4346
+ // Add 'nil' keyword with erasing '.' instruction.
4347
+ unsigned bytesToErase = 0 ;
4348
+ auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4349
+ if (DotLoc.isValid ())
4350
+ bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4351
+ addKeyword (" nil" , T, SemanticContextKind::None,
4352
+ CodeCompletionKeywordKind::kw_nil, bytesToErase);
4353
+ }
4354
+
4343
4355
// We can only say .foo where foo is a static member of the contextual
4344
4356
// type and has the same type (or if the member is a function, then the
4345
4357
// same result type) as the contextual type.
@@ -4378,14 +4390,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
4378
4390
objT = objT->lookThroughAllOptionalTypes ();
4379
4391
if (seenTypes.insert (objT->getCanonicalType ()).second )
4380
4392
getUnresolvedMemberCompletions (objT);
4381
-
4382
- // Add 'nil' keyword with erasing '.' instruction.
4383
- unsigned bytesToErase = 0 ;
4384
- auto &SM = CurrDeclContext->getASTContext ().SourceMgr ;
4385
- if (DotLoc.isValid ())
4386
- bytesToErase = SM.getByteDistance (DotLoc, SM.getCodeCompletionLoc ());
4387
- addKeyword (" nil" , T, SemanticContextKind::None,
4388
- CodeCompletionKeywordKind::kw_nil, bytesToErase);
4389
4393
}
4390
4394
getUnresolvedMemberCompletions (T);
4391
4395
}
@@ -6083,6 +6087,45 @@ static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
6083
6087
DCForModules);
6084
6088
}
6085
6089
6090
+ void deliverUnresolvedMemberResults (
6091
+ ArrayRef<UnresolvedMemberTypeCheckCompletionCallback::Result> Results,
6092
+ DeclContext *DC, SourceLoc DotLoc,
6093
+ ide::CodeCompletionContext &CompletionCtx,
6094
+ CodeCompletionConsumer &Consumer) {
6095
+ ASTContext &Ctx = DC->getASTContext ();
6096
+ CompletionLookup Lookup (CompletionCtx.getResultSink (), Ctx, DC,
6097
+ &CompletionCtx);
6098
+
6099
+ assert (DotLoc.isValid ());
6100
+ Lookup.setHaveDot (DotLoc);
6101
+ Lookup.shouldCheckForDuplicates (Results.size () > 1 );
6102
+
6103
+ // Get the canonical versions of the top-level types
6104
+ SmallPtrSet<CanType, 4 > originalTypes;
6105
+ for (auto &Result: Results)
6106
+ originalTypes.insert (Result.ExpectedTy ->getCanonicalType ());
6107
+
6108
+ for (auto &Result: Results) {
6109
+ Lookup.setExpectedTypes ({Result.ExpectedTy },
6110
+ Result.IsImplicitSingleExpressionReturn ,
6111
+ /* expectsNonVoid*/ true );
6112
+ Lookup.setIdealExpectedType (Result.ExpectedTy );
6113
+
6114
+ // For optional types, also get members of the unwrapped type if it's not
6115
+ // already equivalent to one of the top-level types. Handling it via the top
6116
+ // level type and not here ensures we give the correct type relation
6117
+ // (identical, rather than convertible).
6118
+ if (Result.ExpectedTy ->getOptionalObjectType ()) {
6119
+ Type Unwrapped = Result.ExpectedTy ->lookThroughAllOptionalTypes ();
6120
+ if (originalTypes.insert (Unwrapped->getCanonicalType ()).second )
6121
+ Lookup.getUnresolvedMemberCompletions (Unwrapped);
6122
+ }
6123
+ Lookup.getUnresolvedMemberCompletions (Result.ExpectedTy );
6124
+ }
6125
+ SourceFile *SF = DC->getParentSourceFile ();
6126
+ deliverCompletionResults (CompletionCtx, Lookup, *SF, Consumer);
6127
+ }
6128
+
6086
6129
void deliverDotExprResults (
6087
6130
ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
6088
6131
Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
@@ -6113,7 +6156,7 @@ void deliverDotExprResults(
6113
6156
Lookup.setIsStaticMetatype (Result.BaseIsStaticMetaType );
6114
6157
Lookup.getPostfixKeywordCompletions (Result.BaseTy , BaseExpr);
6115
6158
Lookup.setExpectedTypes (Result.ExpectedTypes ,
6116
- Result.IsSingleExpressionBody ,
6159
+ Result.IsImplicitSingleExpressionReturn ,
6117
6160
Result.ExpectsNonVoid );
6118
6161
if (isDynamicLookup (Result.BaseTy ))
6119
6162
Lookup.setIsDynamicLookup ();
@@ -6158,6 +6201,23 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
6158
6201
Consumer);
6159
6202
return true ;
6160
6203
}
6204
+ case CompletionKind::UnresolvedMember: {
6205
+ assert (CodeCompleteTokenExpr);
6206
+ assert (CurDeclContext);
6207
+
6208
+ UnresolvedMemberTypeCheckCompletionCallback Lookup (CodeCompleteTokenExpr);
6209
+ llvm::SaveAndRestore<TypeCheckCompletionCallback*>
6210
+ CompletionCollector (Context.CompletionCallback , &Lookup);
6211
+ typeCheckContextAt (CurDeclContext, CompletionLoc);
6212
+
6213
+ if (!Lookup.gotCallback ())
6214
+ Lookup.fallbackTypeCheck (CurDeclContext);
6215
+
6216
+ addKeywords (CompletionContext.getResultSink (), MaybeFuncBody);
6217
+ deliverUnresolvedMemberResults (Lookup.getResults (), CurDeclContext, DotLoc,
6218
+ CompletionContext, Consumer);
6219
+ return true ;
6220
+ }
6161
6221
default :
6162
6222
return false ;
6163
6223
}
@@ -6277,6 +6337,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6277
6337
switch (Kind) {
6278
6338
case CompletionKind::None:
6279
6339
case CompletionKind::DotExpr:
6340
+ case CompletionKind::UnresolvedMember:
6280
6341
llvm_unreachable (" should be already handled" );
6281
6342
return ;
6282
6343
@@ -6336,7 +6397,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6336
6397
case CompletionKind::PostfixExprBeginning: {
6337
6398
ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6338
6399
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6339
- ContextInfo.isSingleExpressionBody ());
6400
+ ContextInfo.isImplicitSingleExpressionReturn ());
6340
6401
DoPostfixExprBeginning ();
6341
6402
break ;
6342
6403
}
@@ -6358,8 +6419,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6358
6419
6359
6420
if (ShouldCompleteCallPatternAfterParen) {
6360
6421
ExprContextInfo ParentContextInfo (CurDeclContext, ParsedExpr);
6361
- Lookup.setExpectedTypes (ParentContextInfo.getPossibleTypes (),
6362
- ParentContextInfo.isSingleExpressionBody ());
6422
+ Lookup.setExpectedTypes (
6423
+ ParentContextInfo.getPossibleTypes (),
6424
+ ParentContextInfo.isImplicitSingleExpressionReturn ());
6363
6425
if (!ContextInfo.getPossibleCallees ().empty ()) {
6364
6426
for (auto &typeAndDecl : ContextInfo.getPossibleCallees ())
6365
6427
Lookup.tryFunctionCallCompletions (typeAndDecl.Type , typeAndDecl.Decl ,
@@ -6377,7 +6439,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6377
6439
(Lookup.FoundFunctionCalls &&
6378
6440
Lookup.FoundFunctionsWithoutFirstKeyword )) {
6379
6441
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6380
- ContextInfo.isSingleExpressionBody ());
6442
+ ContextInfo.isImplicitSingleExpressionReturn ());
6381
6443
Lookup.setHaveLParen (false );
6382
6444
DoPostfixExprBeginning ();
6383
6445
}
@@ -6426,7 +6488,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6426
6488
case CompletionKind::CaseStmtBeginning: {
6427
6489
ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6428
6490
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6429
- ContextInfo.isSingleExpressionBody ());
6491
+ ContextInfo.isImplicitSingleExpressionReturn ());
6430
6492
Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
6431
6493
Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
6432
6494
DoPostfixExprBeginning ();
@@ -6445,7 +6507,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6445
6507
if (isa<AccessorDecl>(ParsedDecl)) {
6446
6508
ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6447
6509
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6448
- ContextInfo.isSingleExpressionBody ());
6510
+ ContextInfo.isImplicitSingleExpressionReturn ());
6449
6511
DoPostfixExprBeginning ();
6450
6512
}
6451
6513
break ;
@@ -6478,15 +6540,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6478
6540
Lookup.addImportModuleNames ();
6479
6541
break ;
6480
6542
}
6481
- case CompletionKind::UnresolvedMember: {
6482
- Lookup.setHaveDot (DotLoc);
6483
- ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6484
- Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6485
- ContextInfo.isSingleExpressionBody ());
6486
- Lookup.setIdealExpectedType (CodeCompleteTokenExpr->getType ());
6487
- Lookup.getUnresolvedMemberCompletions (ContextInfo.getPossibleTypes ());
6488
- break ;
6489
- }
6490
6543
case CompletionKind::CallArg: {
6491
6544
ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6492
6545
@@ -6528,7 +6581,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6528
6581
6529
6582
if (shouldPerformGlobalCompletion) {
6530
6583
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6531
- ContextInfo.isSingleExpressionBody ());
6584
+ ContextInfo.isImplicitSingleExpressionReturn ());
6532
6585
DoPostfixExprBeginning ();
6533
6586
}
6534
6587
break ;
@@ -6647,7 +6700,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6647
6700
SmallVector<Type, 2 > possibleReturnTypes;
6648
6701
collectPossibleReturnTypesFromContext (CurDeclContext, possibleReturnTypes);
6649
6702
Lookup.setExpectedTypes (possibleReturnTypes,
6650
- /* isSingleExpressionBody */ false );
6703
+ /* isImplicitSingleExpressionReturn */ false );
6651
6704
Lookup.getValueCompletionsInDeclContext (Loc);
6652
6705
break ;
6653
6706
}
@@ -6658,7 +6711,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6658
6711
if (FD->isCoroutine ()) {
6659
6712
// TODO: handle multi-value yields.
6660
6713
Lookup.setExpectedTypes (FD->getStorage ()->getValueInterfaceType (),
6661
- /* isSingleExpressionBody */ false );
6714
+ /* isImplicitSingleExpressionReturn */ false );
6662
6715
}
6663
6716
}
6664
6717
Lookup.getValueCompletionsInDeclContext (Loc);
@@ -6668,7 +6721,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6668
6721
case CompletionKind::AfterPoundExpr: {
6669
6722
ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
6670
6723
Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
6671
- ContextInfo.isSingleExpressionBody ());
6724
+ ContextInfo.isImplicitSingleExpressionReturn ());
6672
6725
6673
6726
Lookup.addPoundAvailable (ParentStmtKind);
6674
6727
Lookup.addPoundLiteralCompletions (/* needPound=*/ false );
0 commit comments