@@ -5609,7 +5609,18 @@ void TypeChecker::checkClosureAttributes(ClosureExpr *closure) {
56095609
56105610void AttributeChecker::visitCompletionHandlerAsyncAttr (
56115611 CompletionHandlerAsyncAttr *attr) {
5612+ AbstractFunctionDecl *AFD = dyn_cast<AbstractFunctionDecl>(D);
5613+ if (!AFD)
5614+ return ;
5615+
5616+ evaluateOrDefault (Ctx.evaluator ,
5617+ TypeCheckCompletionHandlerAsyncAttrRequest{AFD, attr}, {});
5618+ }
56125619
5620+ bool TypeCheckCompletionHandlerAsyncAttrRequest::evaluate (
5621+ Evaluator &evaluator, AbstractFunctionDecl *attachedFunctionDecl,
5622+ CompletionHandlerAsyncAttr *attr) const {
5623+ auto &Diags = attachedFunctionDecl->getASTContext ().Diags ;
56135624 // Check phases:
56145625 // 1. Attached function shouldn't be async and should have enough args
56155626 // to have a completion handler
@@ -5621,30 +5632,29 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
56215632 // - Do some sanity checking on types
56225633
56235634 // Phase 1: Typecheck the function the attribute is attached to
5624- auto attachedFunctionDecl = cast<AbstractFunctionDecl>(D);
56255635 if (attachedFunctionDecl->hasAsync ()) {
5626- diagnose (attr->getLocation (),
5627- diag::attr_completion_handler_async_handler_not_func, attr);
5628- diagnose (attachedFunctionDecl->getAsyncLoc (),
5629- diag::note_attr_function_declared_async);
5630- return ;
5636+ Diags. diagnose (attr->getLocation (),
5637+ diag::attr_completion_handler_async_handler_not_func, attr);
5638+ Diags. diagnose (attachedFunctionDecl->getAsyncLoc (),
5639+ diag::note_attr_function_declared_async);
5640+ return false ;
56315641 }
56325642
56335643 const ParameterList *attachedFunctionParams =
56345644 attachedFunctionDecl->getParameters ();
56355645 assert (attachedFunctionParams && " Attached function has no parameter list" );
56365646 if (attachedFunctionParams->size () == 0 ) {
5637- diagnose (attr->getLocation (),
5638- diag::attr_completion_handler_async_handler_not_func, attr);
5639- return ;
5647+ Diags. diagnose (attr->getLocation (),
5648+ diag::attr_completion_handler_async_handler_not_func, attr);
5649+ return false ;
56405650 }
56415651 size_t completionHandlerIndex = attr->CompletionHandlerIndexLoc .isValid ()
56425652 ? attr->CompletionHandlerIndex
56435653 : attachedFunctionParams->size () - 1 ;
56445654 if (attachedFunctionParams->size () < completionHandlerIndex) {
5645- diagnose (attr->CompletionHandlerIndexLoc ,
5646- diag::attr_completion_handler_async_handler_out_of_range);
5647- return ;
5655+ Diags. diagnose (attr->CompletionHandlerIndexLoc ,
5656+ diag::attr_completion_handler_async_handler_out_of_range);
5657+ return false ;
56485658 }
56495659
56505660 // Phase 2: Typecheck the completion handler
@@ -5654,14 +5664,17 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
56545664 AnyFunctionType *handlerType =
56555665 completionHandlerParamDecl->getType ()->getAs <AnyFunctionType>();
56565666 if (!handlerType) {
5657- diagnose (attr->getLocation (),
5658- diag::attr_completion_handler_async_handler_not_func, attr);
5659- diagnose (completionHandlerParamDecl->getTypeRepr ()->getLoc (),
5660- diag::note_attr_completion_handler_async_type_is_not_function,
5661- completionHandlerParamDecl->getType ())
5667+ Diags.diagnose (attr->getLocation (),
5668+ diag::attr_completion_handler_async_handler_not_func,
5669+ attr);
5670+ Diags
5671+ .diagnose (
5672+ completionHandlerParamDecl->getTypeRepr ()->getLoc (),
5673+ diag::note_attr_completion_handler_async_type_is_not_function,
5674+ completionHandlerParamDecl->getType ())
56625675 .highlight (
56635676 completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
5664- return ;
5677+ return false ;
56655678 }
56665679
56675680 auto handlerTypeRepr =
@@ -5678,27 +5691,31 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
56785691 const bool hasError = missingVoid | hasAutoclosure | !hasEscaping;
56795692
56805693 if (hasError) {
5681- diagnose (attr->getLocation (),
5682- diag::attr_completion_handler_async_handler_not_func, attr);
5694+ Diags.diagnose (attr->getLocation (),
5695+ diag::attr_completion_handler_async_handler_not_func,
5696+ attr);
56835697
56845698 if (missingVoid)
5685- diagnose (completionHandlerParamDecl->getLoc (),
5686- diag::note_attr_completion_function_must_return_void)
5699+ Diags
5700+ .diagnose (completionHandlerParamDecl->getLoc (),
5701+ diag::note_attr_completion_function_must_return_void)
56875702 .highlight (
56885703 completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
56895704
56905705 if (!hasEscaping)
5691- diagnose (completionHandlerParamDecl->getLoc (),
5692- diag::note_attr_completion_handler_async_handler_attr_req,
5693- true , " escaping" )
5706+ Diags
5707+ .diagnose (completionHandlerParamDecl->getLoc (),
5708+ diag::note_attr_completion_handler_async_handler_attr_req,
5709+ true , " escaping" )
56945710 .highlight (
56955711 completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
56965712
56975713 if (hasAutoclosure)
5698- diagnose (handlerTypeAttrs->getLoc (TAK_autoclosure),
5699- diag::note_attr_completion_handler_async_handler_attr_req,
5700- false , " autoclosure" );
5701- return ;
5714+ Diags.diagnose (
5715+ handlerTypeAttrs->getLoc (TAK_autoclosure),
5716+ diag::note_attr_completion_handler_async_handler_attr_req, false ,
5717+ " autoclosure" );
5718+ return false ;
57025719 }
57035720 }
57045721
@@ -5747,21 +5764,23 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
57475764 }
57485765
57495766 if (candidates.empty ()) {
5750- diagnose (attr->AsyncFunctionNameLoc ,
5751- diag::attr_completion_handler_async_no_suitable_function,
5752- attr->getAsyncFunctionName ());
5753- return ;
5767+ Diags. diagnose (attr->AsyncFunctionNameLoc ,
5768+ diag::attr_completion_handler_async_no_suitable_function,
5769+ attr->getAsyncFunctionName ());
5770+ return false ;
57545771 } else if (candidates.size () > 1 ) {
5755- diagnose (attr->AsyncFunctionNameLoc ,
5756- diag::attr_completion_handler_async_ambiguous_function, attr ,
5757- attr->getAsyncFunctionName ());
5772+ Diags. diagnose (attr->AsyncFunctionNameLoc ,
5773+ diag::attr_completion_handler_async_ambiguous_function,
5774+ attr, attr->getAsyncFunctionName ());
57585775
57595776 for (AbstractFunctionDecl *candidate : candidates) {
5760- diagnose (candidate->getLoc (), diag::decl_declared_here,
5761- candidate->getName ());
5777+ Diags. diagnose (candidate->getLoc (), diag::decl_declared_here,
5778+ candidate->getName ());
57625779 }
5763- return ;
5780+ return false ;
57645781 }
57655782 attr->AsyncFunctionDecl = candidates.front ();
57665783 }
5784+
5785+ return true ;
57675786}
0 commit comments