Skip to content

Commit 3670b16

Browse files
committed
[CodeCompletion] Migrate completion of ReturnStmtExpr to solver-based
1 parent 92de4d9 commit 3670b16

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

lib/IDE/CodeCompletion.cpp

+24-11
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,25 @@ static void addObserverKeywords(CodeCompletionResultSink &Sink) {
890890
addKeyword(Sink, "didSet", CodeCompletionKeywordKind::None);
891891
}
892892

893+
static void addKeywordsAfterReturn(CodeCompletionResultSink &Sink, DeclContext *DC) {
894+
// `return nil` is not actually represented as a `ReturnExpr` in the AST but
895+
// gets translated to a `FailStmt`. We thus can't produce the 'nil' completion
896+
// using the solver-based implementation. Add the result manually.
897+
if (auto ctor = dyn_cast_or_null<ConstructorDecl>(DC->getAsDecl())) {
898+
if (ctor->isFailable()) {
899+
CodeCompletionResultBuilder Builder(Sink, CodeCompletionResultKind::Literal,
900+
SemanticContextKind::None);
901+
Builder.setLiteralKind(CodeCompletionLiteralKind::NilLiteral);
902+
Builder.addKeyword("nil");
903+
Builder.addTypeAnnotation(ctor->getResultInterfaceType(), {});
904+
Builder.setResultTypes(ctor->getResultInterfaceType());
905+
ExpectedTypeContext TypeContext;
906+
TypeContext.setPossibleTypes({ctor->getResultInterfaceType()});
907+
Builder.setTypeContext(TypeContext, DC);
908+
}
909+
}
910+
}
911+
893912
void swift::ide::addExprKeywords(CodeCompletionResultSink &Sink,
894913
DeclContext *DC) {
895914
// Expression is invalid at top-level of non-script files.
@@ -1026,6 +1045,8 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
10261045

10271046
LLVM_FALLTHROUGH;
10281047
case CompletionKind::ReturnStmtExpr:
1048+
addKeywordsAfterReturn(Sink, CurDeclContext);
1049+
LLVM_FALLTHROUGH;
10291050
case CompletionKind::YieldStmtExpr:
10301051
case CompletionKind::ForEachSequence:
10311052
addSuperKeyword(Sink, CurDeclContext);
@@ -1533,7 +1554,8 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
15331554
case CompletionKind::CaseStmtBeginning:
15341555
case CompletionKind::ForEachSequence:
15351556
case CompletionKind::PostfixExprBeginning:
1536-
case CompletionKind::StmtOrExpr: {
1557+
case CompletionKind::StmtOrExpr:
1558+
case CompletionKind::ReturnStmtExpr: {
15371559
assert(CurDeclContext);
15381560

15391561
bool AddUnresolvedMemberCompletions =
@@ -1705,6 +1727,7 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
17051727
case CompletionKind::CaseStmtBeginning:
17061728
case CompletionKind::PostfixExprParen:
17071729
case CompletionKind::PostfixExpr:
1730+
case CompletionKind::ReturnStmtExpr:
17081731
llvm_unreachable("should be already handled");
17091732
return;
17101733

@@ -1953,16 +1976,6 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
19531976
break;
19541977
}
19551978

1956-
case CompletionKind::ReturnStmtExpr : {
1957-
SourceLoc Loc = P.Context.SourceMgr.getIDEInspectionTargetLoc();
1958-
SmallVector<Type, 2> possibleReturnTypes;
1959-
collectPossibleReturnTypesFromContext(CurDeclContext, possibleReturnTypes);
1960-
Lookup.setExpectedTypes(possibleReturnTypes,
1961-
/*isImplicitSingleExpressionReturn*/ false);
1962-
Lookup.getValueCompletionsInDeclContext(Loc);
1963-
break;
1964-
}
1965-
19661979
case CompletionKind::YieldStmtExpr: {
19671980
SourceLoc Loc = P.Context.SourceMgr.getIDEInspectionTargetLoc();
19681981
if (auto FD = dyn_cast<AccessorDecl>(CurDeclContext)) {

lib/IDE/ExprCompletion.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ void ExprTypeCheckCompletionCallback::sawSolutionImpl(
7777
const constraints::Solution &S) {
7878
auto &CS = S.getConstraintSystem();
7979

80-
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
80+
Type ExpectedTy;
81+
if (auto ContextualType = CS.getContextualType(CompletionExpr, /*forConstraint=*/false)) {
82+
ExpectedTy = ContextualType;
83+
} else {
84+
ExpectedTy = getTypeForCompletion(S, CompletionExpr);
85+
}
8186

8287
bool ImplicitReturn = isImplicitSingleExpressionReturn(CS, CompletionExpr);
8388

lib/IDE/PostfixCompletion.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,13 @@ void PostfixCompletionCallback::sawSolutionImpl(
176176
return;
177177

178178
auto *Locator = CS.getConstraintLocator(SemanticExpr);
179-
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
179+
Type ExpectedTy;
180180
Expr *ParentExpr = CS.getParentExpr(CompletionExpr);
181-
if (!ParentExpr && !ExpectedTy)
182-
ExpectedTy = CS.getContextualType(CompletionExpr, /*forConstraint=*/false);
181+
if (auto ContextualType = CS.getContextualType(CompletionExpr, /*forConstraint=*/false)) {
182+
ExpectedTy = ContextualType;
183+
} else {
184+
ExpectedTy = getTypeForCompletion(S, CompletionExpr);
185+
}
183186

184187
auto *CalleeLocator = S.getCalleeLocator(Locator);
185188
ValueDecl *ReferencedDecl = nullptr;

0 commit comments

Comments
 (0)