@@ -1570,42 +1570,68 @@ void Parser::parseAllAvailabilityMacroArguments() {
1570
1570
AvailabilityMacrosComputed = true ;
1571
1571
}
1572
1572
1573
- static HasAsyncAlternativeAttr *parseAsyncAlternativeAttribute (
1574
- Parser &P, StringRef AttrName, SourceLoc AtLoc, DeclAttrKind DK) {
1573
+ static CompletionHandlerAsyncAttr *
1574
+ parseCompletionHandlerAsyncAttribute (Parser &P, StringRef AttrName,
1575
+ SourceLoc AtLoc, DeclAttrKind DK) {
1575
1576
SourceLoc Loc = P.PreviousLoc ;
1576
1577
1577
- // Unnamed @hasAsyncAlternative attribute
1578
- if (P.Tok . isNot (tok::l_paren))
1579
- return new (P. Context ) HasAsyncAlternativeAttr (AtLoc, Loc );
1580
-
1581
- P. consumeToken (tok::l_paren);
1578
+ if (!P. consumeIf (tok::l_paren)) {
1579
+ P. diagnose (P.getEndOfPreviousLoc (), diag::attr_expected_lparen, AttrName,
1580
+ DeclAttribute::isDeclModifier (DK) );
1581
+ return nullptr ;
1582
+ }
1582
1583
1583
1584
if (!P.Tok .is (tok::string_literal)) {
1584
1585
P.diagnose (Loc, diag::attr_expected_string_literal, AttrName);
1585
1586
return nullptr ;
1586
1587
}
1587
1588
1588
- auto Value = P.getStringLiteralIfNotInterpolated (
1589
- Loc, (" argument of '" + AttrName + " '" ).str ());
1589
+ SourceLoc nameLoc = P.Tok .getLoc ();
1590
+ Optional<StringRef> asyncFunctionName = P.getStringLiteralIfNotInterpolated (
1591
+ nameLoc, (" argument of '" + AttrName + " '" ).str ());
1590
1592
P.consumeToken (tok::string_literal);
1591
- if (!Value)
1593
+
1594
+ if (!asyncFunctionName)
1592
1595
return nullptr ;
1593
1596
1594
- ParsedDeclName parsedName = parseDeclName (Value.getValue ());
1595
- if (!parsedName || !parsedName.ContextName .empty ()) {
1596
- P.diagnose (AtLoc, diag::has_async_alternative_invalid_name, AttrName);;
1597
+ ParsedDeclName parsedAsyncName = parseDeclName (*asyncFunctionName);
1598
+ if (!parsedAsyncName || !parsedAsyncName.ContextName .empty ()) {
1599
+ P.diagnose (nameLoc, diag::attr_completion_handler_async_invalid_name,
1600
+ AttrName);
1597
1601
return nullptr ;
1598
1602
}
1599
1603
1604
+ size_t handlerIndex = 0 ;
1605
+ SourceLoc handlerIndexLoc = SourceLoc ();
1606
+ if (P.consumeIf (tok::comma)) {
1607
+ // The completion handler is explicitly specified, parse it
1608
+ if (P.parseSpecificIdentifier (" completionHandlerIndex" ,
1609
+ diag::attr_missing_label,
1610
+ " completionHandlerIndex" , AttrName) ||
1611
+ P.parseToken (tok::colon, diag::expected_colon_after_label,
1612
+ " completionHandlerIndex" )) {
1613
+ return nullptr ;
1614
+ }
1615
+
1616
+ if (P.Tok .getText ().getAsInteger (0 , handlerIndex)) {
1617
+ P.diagnose (P.Tok .getLoc (), diag::attr_expected_integer_literal, AttrName);
1618
+ return nullptr ;
1619
+ }
1620
+
1621
+ handlerIndexLoc = P.consumeToken (tok::integer_literal);
1622
+ }
1623
+
1600
1624
SourceRange AttrRange = SourceRange (Loc, P.Tok .getRange ().getStart ());
1601
1625
if (!P.consumeIf (tok::r_paren)) {
1602
- P.diagnose (Loc , diag::attr_expected_rparen, AttrName,
1626
+ P.diagnose (P. getEndOfPreviousLoc () , diag::attr_expected_rparen, AttrName,
1603
1627
DeclAttribute::isDeclModifier (DK));
1604
1628
return nullptr ;
1605
1629
}
1606
1630
1607
- return new (P.Context ) HasAsyncAlternativeAttr (
1608
- parsedName.formDeclNameRef (P.Context ), AtLoc, AttrRange);
1631
+ return new (P.Context ) CompletionHandlerAsyncAttr (
1632
+ parsedAsyncName.formDeclNameRef (P.Context ), nameLoc,
1633
+ handlerIndex, handlerIndexLoc, AtLoc,
1634
+ AttrRange);
1609
1635
}
1610
1636
1611
1637
bool Parser::parseNewDeclAttribute (DeclAttributes &Attributes, SourceLoc AtLoc,
@@ -2686,8 +2712,9 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
2686
2712
name, AtLoc, range, /* implicit*/ false ));
2687
2713
break ;
2688
2714
}
2689
- case DAK_HasAsyncAlternative: {
2690
- auto *attr = parseAsyncAlternativeAttribute (*this , AttrName, AtLoc, DK);
2715
+ case DAK_CompletionHandlerAsync: {
2716
+ auto *attr =
2717
+ parseCompletionHandlerAsyncAttribute (*this , AttrName, AtLoc, DK);
2691
2718
if (!attr) {
2692
2719
skipUntilDeclStmtRBrace (tok::r_paren);
2693
2720
consumeIf (tok::r_paren);
0 commit comments