@@ -5609,7 +5609,18 @@ void TypeChecker::checkClosureAttributes(ClosureExpr *closure) {
5609
5609
5610
5610
void AttributeChecker::visitCompletionHandlerAsyncAttr (
5611
5611
CompletionHandlerAsyncAttr *attr) {
5612
+ AbstractFunctionDecl *AFD = dyn_cast<AbstractFunctionDecl>(D);
5613
+ if (!AFD)
5614
+ return ;
5615
+
5616
+ evaluateOrDefault (Ctx.evaluator ,
5617
+ TypeCheckCompletionHandlerAsyncAttrRequest{AFD, attr}, {});
5618
+ }
5612
5619
5620
+ bool TypeCheckCompletionHandlerAsyncAttrRequest::evaluate (
5621
+ Evaluator &evaluator, AbstractFunctionDecl *attachedFunctionDecl,
5622
+ CompletionHandlerAsyncAttr *attr) const {
5623
+ auto &Diags = attachedFunctionDecl->getASTContext ().Diags ;
5613
5624
// Check phases:
5614
5625
// 1. Attached function shouldn't be async and should have enough args
5615
5626
// to have a completion handler
@@ -5621,30 +5632,29 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
5621
5632
// - Do some sanity checking on types
5622
5633
5623
5634
// Phase 1: Typecheck the function the attribute is attached to
5624
- auto attachedFunctionDecl = cast<AbstractFunctionDecl>(D);
5625
5635
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 ;
5631
5641
}
5632
5642
5633
5643
const ParameterList *attachedFunctionParams =
5634
5644
attachedFunctionDecl->getParameters ();
5635
5645
assert (attachedFunctionParams && " Attached function has no parameter list" );
5636
5646
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 ;
5640
5650
}
5641
5651
size_t completionHandlerIndex = attr->CompletionHandlerIndexLoc .isValid ()
5642
5652
? attr->CompletionHandlerIndex
5643
5653
: attachedFunctionParams->size () - 1 ;
5644
5654
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 ;
5648
5658
}
5649
5659
5650
5660
// Phase 2: Typecheck the completion handler
@@ -5654,14 +5664,17 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
5654
5664
AnyFunctionType *handlerType =
5655
5665
completionHandlerParamDecl->getType ()->getAs <AnyFunctionType>();
5656
5666
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 ())
5662
5675
.highlight (
5663
5676
completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
5664
- return ;
5677
+ return false ;
5665
5678
}
5666
5679
5667
5680
auto handlerTypeRepr =
@@ -5678,27 +5691,31 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
5678
5691
const bool hasError = missingVoid | hasAutoclosure | !hasEscaping;
5679
5692
5680
5693
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);
5683
5697
5684
5698
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)
5687
5702
.highlight (
5688
5703
completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
5689
5704
5690
5705
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" )
5694
5710
.highlight (
5695
5711
completionHandlerParamDecl->getTypeRepr ()->getSourceRange ());
5696
5712
5697
5713
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 ;
5702
5719
}
5703
5720
}
5704
5721
@@ -5747,21 +5764,23 @@ void AttributeChecker::visitCompletionHandlerAsyncAttr(
5747
5764
}
5748
5765
5749
5766
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 ;
5754
5771
} 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 ());
5758
5775
5759
5776
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 ());
5762
5779
}
5763
- return ;
5780
+ return false ;
5764
5781
}
5765
5782
attr->AsyncFunctionDecl = candidates.front ();
5766
5783
}
5784
+
5785
+ return true ;
5767
5786
}
0 commit comments