@@ -1672,7 +1672,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
1672
1672
1673
1673
private:
1674
1674
void addKeywords (CodeCompletionResultSink &Sink, bool MaybeFuncBody);
1675
- bool trySolverCompletion ();
1675
+ bool trySolverCompletion (bool MaybeFuncBody );
1676
1676
};
1677
1677
} // end anonymous namespace
1678
1678
@@ -6054,25 +6054,7 @@ void deliverDotExprResults(
6054
6054
deliverCompletionResults (CompletionCtx, Lookup, *SF, Consumer);
6055
6055
}
6056
6056
6057
- bool CodeCompletionCallbacksImpl::trySolverCompletion () {
6058
- CompletionContext.CodeCompletionKind = Kind;
6059
-
6060
- if (Kind == CompletionKind::None)
6061
- return true ;
6062
-
6063
- bool MaybeFuncBody = true ;
6064
- if (CurDeclContext) {
6065
- auto *CD = CurDeclContext->getLocalContext ();
6066
- if (!CD || CD->getContextKind () == DeclContextKind::Initializer ||
6067
- CD->getContextKind () == DeclContextKind::TopLevelCodeDecl)
6068
- MaybeFuncBody = false ;
6069
- }
6070
-
6071
- if (auto *DC = dyn_cast_or_null<DeclContext>(ParsedDecl)) {
6072
- if (DC->isChildContextOf (CurDeclContext))
6073
- CurDeclContext = DC;
6074
- }
6075
-
6057
+ bool CodeCompletionCallbacksImpl::trySolverCompletion (bool MaybeFuncBody) {
6076
6058
assert (ParsedExpr || CurDeclContext);
6077
6059
6078
6060
SourceLoc CompletionLoc = ParsedExpr
@@ -6111,12 +6093,42 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion() {
6111
6093
}
6112
6094
}
6113
6095
6096
+ // Undoes the single-expression closure/function body transformation on the
6097
+ // given DeclContext and its parent contexts if they have a single expression
6098
+ // body that contains the code completion location.
6099
+ //
6100
+ // FIXME: Remove this once all expression position completions are migrated
6101
+ // to work via TypeCheckCompletionCallback.
6102
+ static void undoSingleExpressionReturn (DeclContext *DC) {
6103
+ auto updateBody = [](BraceStmt *BS, ASTContext &Ctx) -> bool {
6104
+ ASTNode FirstElem = BS->getFirstElement ();
6105
+ auto *RS = dyn_cast_or_null<ReturnStmt>(FirstElem.dyn_cast <Stmt*>());
6106
+
6107
+ if (!RS || !RS->isImplicit ())
6108
+ return false ;
6109
+
6110
+ BS->setFirstElement (RS->getResult ());
6111
+ return true ;
6112
+ };
6113
+
6114
+ while (ClosureExpr *CE = dyn_cast_or_null<ClosureExpr>(DC)) {
6115
+ if (CE->hasSingleExpressionBody ()) {
6116
+ if (updateBody (CE->getBody (), CE->getASTContext ()))
6117
+ CE->setBody (CE->getBody (), false );
6118
+ }
6119
+ DC = DC->getParent ();
6120
+ }
6121
+ if (FuncDecl *FD = dyn_cast_or_null<FuncDecl>(DC)) {
6122
+ if (FD->hasSingleExpressionBody ()) {
6123
+ if (updateBody (FD->getBody (), FD->getASTContext ()))
6124
+ FD->setHasSingleExpressionBody (false );
6125
+ }
6126
+ }
6127
+ }
6128
+
6114
6129
void CodeCompletionCallbacksImpl::doneParsing () {
6115
6130
CompletionContext.CodeCompletionKind = Kind;
6116
6131
6117
- if (trySolverCompletion ())
6118
- return ;
6119
-
6120
6132
if (Kind == CompletionKind::None) {
6121
6133
return ;
6122
6134
}
@@ -6134,6 +6146,10 @@ void CodeCompletionCallbacksImpl::doneParsing() {
6134
6146
CurDeclContext = DC;
6135
6147
}
6136
6148
6149
+ if (trySolverCompletion (MaybeFuncBody))
6150
+ return ;
6151
+
6152
+ undoSingleExpressionReturn (CurDeclContext);
6137
6153
typeCheckContextAt (
6138
6154
CurDeclContext,
6139
6155
ParsedExpr
0 commit comments