@@ -1543,12 +1543,14 @@ extension Parser {
1543
1543
var token : RawTokenSyntax
1544
1544
}
1545
1545
1546
- mutating func parseAccessorIntroducer( ) -> AccessorIntroducer ? {
1546
+ mutating func parseAccessorIntroducer(
1547
+ forcedKind: ( AccessorKind , TokenConsumptionHandle ) ? = nil
1548
+ ) -> AccessorIntroducer ? {
1547
1549
// Check there is an identifier before consuming
1548
1550
var look = self . lookahead ( )
1549
1551
let _ = look. consumeAttributeList ( )
1550
1552
let hasModifier = look. consume ( ifAny: [ . contextualKeyword( . mutating) , . contextualKeyword( . nonmutating) , . contextualKeyword( . __consuming) ] ) != nil
1551
- guard let ( kind, handle) = look. at ( anyIn: AccessorKind . self) else {
1553
+ guard let ( kind, handle) = look. at ( anyIn: AccessorKind . self) ?? forcedKind else {
1552
1554
return nil
1553
1555
}
1554
1556
@@ -1611,15 +1613,18 @@ extension Parser {
1611
1613
return specifiers
1612
1614
}
1613
1615
1614
- /// Parse the body of a variable declaration. This can include explicit
1615
- /// getters, setters, and observers, or the body of a computed property.
1616
+ /// Parse an accessor.
1617
+ mutating func parseAccessorDecl( ) -> RawAccessorDeclSyntax {
1618
+ let forcedHandle = TokenConsumptionHandle ( tokenKind: . contextualKeyword( . get) , missing: true )
1619
+ let introducer = parseAccessorIntroducer ( forcedKind: ( . get, forcedHandle) ) !
1620
+ return parseAccessorDecl ( introducer: introducer)
1621
+ }
1622
+
1623
+ /// Parse an accessor once we know we have an introducer
1616
1624
///
1617
1625
/// Grammar
1618
1626
/// =======
1619
1627
///
1620
- /// getter-setter-block → code-block
1621
- /// getter-setter-block → { getter-clause setter-clause opt }
1622
- /// getter-setter-block → { setter-clause getter-clause }
1623
1628
/// getter-clause → attributes opt mutation-modifier opt get code-block
1624
1629
/// setter-clause → attributes opt mutation-modifier opt set setter-name opt code-block
1625
1630
/// setter-name → ( identifier )
@@ -1631,6 +1636,63 @@ extension Parser {
1631
1636
/// willSet-didSet-block → { didSet-clause willSet-clause opt }
1632
1637
/// willSet-clause → attributes opt willSet setter-name opt code-block
1633
1638
/// didSet-clause → attributes opt didSet setter-name opt code-block
1639
+ private mutating func parseAccessorDecl(
1640
+ introducer: AccessorIntroducer
1641
+ ) -> RawAccessorDeclSyntax {
1642
+ // 'set' and 'willSet' can have an optional name. This isn't valid in a
1643
+ // protocol, but we parse and then reject it for better QoI.
1644
+ //
1645
+ // set-name ::= '(' identifier ')'
1646
+ let parameter : RawAccessorParameterSyntax ?
1647
+ if [ AccessorKind . set, . willSet, . didSet] . contains ( introducer. kind) , let lparen = self . consume ( if: . leftParen) {
1648
+ let ( unexpectedBeforeName, name) = self . expectIdentifier ( )
1649
+ let ( unexpectedBeforeRParen, rparen) = self . expect ( . rightParen)
1650
+ parameter = RawAccessorParameterSyntax (
1651
+ leftParen: lparen,
1652
+ unexpectedBeforeName,
1653
+ name: name,
1654
+ unexpectedBeforeRParen,
1655
+ rightParen: rparen,
1656
+ arena: self . arena
1657
+ )
1658
+ } else {
1659
+ parameter = nil
1660
+ }
1661
+
1662
+ // Next, parse effects specifiers. While it's only valid to have them
1663
+ // on 'get' accessors, we also emit diagnostics if they show up on others.
1664
+ let asyncKeyword : RawTokenSyntax ?
1665
+ let throwsKeyword : RawTokenSyntax ?
1666
+ if self . at ( anyIn: EffectsSpecifier . self) != nil {
1667
+ asyncKeyword = self . parseEffectsSpecifier ( )
1668
+ throwsKeyword = self . parseEffectsSpecifier ( )
1669
+ } else {
1670
+ asyncKeyword = nil
1671
+ throwsKeyword = nil
1672
+ }
1673
+
1674
+ let body = self . parseOptionalCodeBlock ( )
1675
+ return RawAccessorDeclSyntax (
1676
+ attributes: introducer. attributes,
1677
+ modifier: introducer. modifier,
1678
+ accessorKind: introducer. token,
1679
+ parameter: parameter,
1680
+ asyncKeyword: asyncKeyword,
1681
+ throwsKeyword: throwsKeyword,
1682
+ body: body,
1683
+ arena: self . arena
1684
+ )
1685
+ }
1686
+
1687
+ /// Parse the body of a variable declaration. This can include explicit
1688
+ /// getters, setters, and observers, or the body of a computed property.
1689
+ ///
1690
+ /// Grammar
1691
+ /// =======
1692
+ ///
1693
+ /// getter-setter-block → code-block
1694
+ /// getter-setter-block → { getter-clause setter-clause opt }
1695
+ /// getter-setter-block → { setter-clause getter-clause }
1634
1696
@_spi ( RawSyntax)
1635
1697
public mutating func parseGetSet( ) -> RawSubscriptDeclSyntax . Accessor {
1636
1698
// Parse getter and setter.
@@ -1685,52 +1747,7 @@ extension Parser {
1685
1747
)
1686
1748
}
1687
1749
1688
- // 'set' and 'willSet' can have an optional name. This isn't valid in a
1689
- // protocol, but we parse and then reject it for better QoI.
1690
- //
1691
- // set-name ::= '(' identifier ')'
1692
- let parameter : RawAccessorParameterSyntax ?
1693
- if [ AccessorKind . set, . willSet, . didSet] . contains ( introducer. kind) , let lparen = self . consume ( if: . leftParen) {
1694
- let ( unexpectedBeforeName, name) = self . expectIdentifier ( )
1695
- let ( unexpectedBeforeRParen, rparen) = self . expect ( . rightParen)
1696
- parameter = RawAccessorParameterSyntax (
1697
- leftParen: lparen,
1698
- unexpectedBeforeName,
1699
- name: name,
1700
- unexpectedBeforeRParen,
1701
- rightParen: rparen,
1702
- arena: self . arena
1703
- )
1704
- } else {
1705
- parameter = nil
1706
- }
1707
-
1708
- // Next, parse effects specifiers. While it's only valid to have them
1709
- // on 'get' accessors, we also emit diagnostics if they show up on others.
1710
- let asyncKeyword : RawTokenSyntax ?
1711
- let throwsKeyword : RawTokenSyntax ?
1712
- if self . at ( anyIn: EffectsSpecifier . self) != nil {
1713
- asyncKeyword = self . parseEffectsSpecifier ( )
1714
- throwsKeyword = self . parseEffectsSpecifier ( )
1715
- } else {
1716
- asyncKeyword = nil
1717
- throwsKeyword = nil
1718
- }
1719
-
1720
- let body = self . parseOptionalCodeBlock ( )
1721
-
1722
- elements. append (
1723
- RawAccessorDeclSyntax (
1724
- attributes: introducer. attributes,
1725
- modifier: introducer. modifier,
1726
- accessorKind: introducer. token,
1727
- parameter: parameter,
1728
- asyncKeyword: asyncKeyword,
1729
- throwsKeyword: throwsKeyword,
1730
- body: body,
1731
- arena: self . arena
1732
- )
1733
- )
1750
+ elements. append ( parseAccessorDecl ( introducer: introducer) )
1734
1751
}
1735
1752
}
1736
1753
0 commit comments