@@ -34,52 +34,6 @@ static bool SwiftKeyPathFilter(ValueDecl *decl, DeclVisibilityKind) {
3434 }
3535}
3636
37- // / Returns \c true if \p DC can handles async call.
38- static bool canDeclContextHandleAsync (const DeclContext *DC) {
39- if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
40- return func->isAsyncContext ();
41-
42- if (auto *closure = dyn_cast<ClosureExpr>(DC)) {
43- // See if the closure has 'async' function type.
44- if (auto closureType = closure->getType ())
45- if (auto fnType = closureType->getAs <AnyFunctionType>())
46- if (fnType->isAsync ())
47- return true ;
48-
49- // If the closure doesn't contain any async call in the body, closure itself
50- // doesn't have 'async' type even if 'async' closure is expected.
51- // func foo(fn: () async -> Void)
52- // foo { <HERE> }
53- // In this case, the closure is wrapped with a 'FunctionConversionExpr'
54- // which has 'async' function type.
55- struct AsyncClosureChecker : public ASTWalker {
56- const ClosureExpr *Target;
57- bool Result = false ;
58-
59- AsyncClosureChecker (const ClosureExpr *Target) : Target(Target) {}
60-
61- std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
62- if (E == Target)
63- return {false , E};
64-
65- if (auto conversionExpr = dyn_cast<FunctionConversionExpr>(E)) {
66- if (conversionExpr->getSubExpr () == Target) {
67- if (conversionExpr->getType ()->is <AnyFunctionType>() &&
68- conversionExpr->getType ()->castTo <AnyFunctionType>()->isAsync ())
69- Result = true ;
70- return {false , E};
71- }
72- }
73- return {true , E};
74- }
75- } checker (closure);
76- closure->getParent ()->walkContext (checker);
77- return checker.Result ;
78- }
79-
80- return false ;
81- }
82-
8337static bool isTopLevelSubcontext (const DeclContext *DC) {
8438 for (; DC && DC->isLocalContext (); DC = DC->getParent ()) {
8539 switch (DC->getContextKind ()) {
@@ -207,6 +161,52 @@ bool swift::ide::isCompletionDeclContextLocalContext(DeclContext *DC) {
207161 return true ;
208162}
209163
164+ // / Returns \c true if \p DC can handles async call.
165+ bool swift::ide::canDeclContextHandleAsync (const DeclContext *DC) {
166+ if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
167+ return func->isAsyncContext ();
168+
169+ if (auto *closure = dyn_cast<ClosureExpr>(DC)) {
170+ // See if the closure has 'async' function type.
171+ if (auto closureType = closure->getType ())
172+ if (auto fnType = closureType->getAs <AnyFunctionType>())
173+ if (fnType->isAsync ())
174+ return true ;
175+
176+ // If the closure doesn't contain any async call in the body, closure itself
177+ // doesn't have 'async' type even if 'async' closure is expected.
178+ // func foo(fn: () async -> Void)
179+ // foo { <HERE> }
180+ // In this case, the closure is wrapped with a 'FunctionConversionExpr'
181+ // which has 'async' function type.
182+ struct AsyncClosureChecker : public ASTWalker {
183+ const ClosureExpr *Target;
184+ bool Result = false ;
185+
186+ AsyncClosureChecker (const ClosureExpr *Target) : Target(Target) {}
187+
188+ std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
189+ if (E == Target)
190+ return {false , E};
191+
192+ if (auto conversionExpr = dyn_cast<FunctionConversionExpr>(E)) {
193+ if (conversionExpr->getSubExpr () == Target) {
194+ if (conversionExpr->getType ()->is <AnyFunctionType>() &&
195+ conversionExpr->getType ()->castTo <AnyFunctionType>()->isAsync ())
196+ Result = true ;
197+ return {false , E};
198+ }
199+ }
200+ return {true , E};
201+ }
202+ } checker (closure);
203+ closure->getParent ()->walkContext (checker);
204+ return checker.Result ;
205+ }
206+
207+ return false ;
208+ }
209+
210210// / Return \c true if the completion happens at top-level of a library file.
211211bool swift::ide::isCodeCompletionAtTopLevelOfLibraryFile (
212212 const DeclContext *DC) {
0 commit comments