@@ -18,19 +18,11 @@ extension Parser {
18
18
/// Grammar
19
19
/// =======
20
20
///
21
+ /// type → simple-type
21
22
/// type → function-type
22
- /// type → array-type
23
- /// type → dictionary-type
24
- /// type → type-identifier
25
- /// type → tuple-type
26
- /// type → optional-type
27
- /// type → implicitly-unwrapped-optional-type
28
23
/// type → protocol-composition-type
24
+ /// type → constrained-sugar-type
29
25
/// type → opaque-type
30
- /// type → metatype-type
31
- /// type → any-type
32
- /// type → self-type
33
- /// type → '(' type ')'
34
26
@_spi ( RawSyntax)
35
27
public mutating func parseType( misplacedSpecifiers: [ RawTokenSyntax ] = [ ] ) -> RawTypeSyntax {
36
28
let type = self . parseTypeScalar ( misplacedSpecifiers: misplacedSpecifiers)
@@ -133,11 +125,13 @@ extension Parser {
133
125
/// Grammar
134
126
/// =======
135
127
///
136
- /// type-identifier → type-name generic-argument-clause? | type-name generic-argument-clause? '.' type-identifier
137
- /// type-name → identifier
128
+ /// protocol-composition-type → simple- type '&' protocol-composition-continuation
129
+ /// protocol-composition-continuation → simple-type | protocol-composition-type
138
130
///
139
- /// protocol-composition-type → type-identifier '&' protocol-composition-continuation
140
- /// protocol-composition-continuation → type-identifier | protocol-composition-type
131
+ /// constrained-sugar-type → constrained-sugar-type-specifier constrained-sugar-type-constraint
132
+ /// constrained-sugar-type-specifier → 'any' | 'some'
133
+ /// constrained-sugar-type-constraint → protocol-composition-type
134
+ /// constrained-sugar-type-constraint → type-simple
141
135
@_spi ( RawSyntax)
142
136
public mutating func parseSimpleOrCompositionType( ) -> RawTypeSyntax {
143
137
// 'each' is a contextual keyword for a pack reference.
@@ -219,13 +213,21 @@ extension Parser {
219
213
/// Grammar
220
214
/// =======
221
215
///
222
- /// type → type-identifier
223
- /// type → tuple-type
224
- /// type → array-type
225
- /// type → dictionary-type
226
- /// type → metatype-type
216
+ /// simple-type → type-identifier
217
+ /// simple-type → any-type
218
+ /// simple-type → paren-type
219
+ /// simple-type → tuple-type
220
+ /// simple-type → array-type
221
+ /// simple-type → dictionary-type
222
+ /// simple-type → optional-type
223
+ /// simple-type → implicitly-unwrapped-optional-type
224
+ /// simple-type → metatype-type
225
+ /// simple-type → member-type-identifier
227
226
///
228
- /// metatype-type → type '.' 'Type' | type '.' 'Protocol'
227
+ /// metatype-type → simple-type '.' 'Type' | simple-type '.' 'Protocol'
228
+ ///
229
+ /// member-type-identifier → member-type-identifier-base '.' type-identifier
230
+ /// member-type-identifier-base → simple-type | member-type-identifier
229
231
@_spi ( RawSyntax)
230
232
public mutating func parseSimpleType(
231
233
stopAtFirstPeriod: Bool = false
@@ -349,6 +351,12 @@ extension Parser {
349
351
return ( name, nil )
350
352
}
351
353
354
+ /// Parse a type identifier.
355
+ ///
356
+ /// Grammar
357
+ /// =======
358
+ ///
359
+ /// type-identifier → identifier generic-argument-clause?
352
360
mutating func parseTypeIdentifier( ) -> RawTypeSyntax {
353
361
if self . at ( . anyKeyword) {
354
362
return RawTypeSyntax ( self . parseAnyType ( ) )
@@ -369,7 +377,7 @@ extension Parser {
369
377
/// Grammar
370
378
/// =======
371
379
///
372
- /// any-type → Any
380
+ /// any-type → ' Any'
373
381
@_spi ( RawSyntax)
374
382
public mutating func parseAnyType( ) -> RawSimpleTypeIdentifierSyntax {
375
383
let ( unexpectedBeforeName, name) = self . expect ( . anyKeyword)
@@ -461,6 +469,8 @@ extension Parser {
461
469
/// Grammar
462
470
/// =======
463
471
///
472
+ /// paren-type → '(' type ')'
473
+ ///
464
474
/// tuple-type → '(' ')' | '(' tuple-type-element ',' tuple-type-element-list ')'
465
475
/// tuple-type-element-list → tuple-type-element | tuple-type-element ',' tuple-type-element-list
466
476
/// tuple-type-element → element-name type-annotation | type
@@ -639,14 +649,87 @@ extension Parser {
639
649
640
650
extension Parser . Lookahead {
641
651
mutating func canParseType( ) -> Bool {
652
+ guard self . canParseTypeScalar ( ) else {
653
+ return false
654
+ }
655
+
656
+ if self . currentToken. isEllipsis {
657
+ self . consumeAnyToken ( )
658
+ }
659
+
660
+ return true
661
+ }
662
+
663
+ mutating func skipTypeAttributeList( ) {
664
+ var specifierProgress = LoopProgressCondition ( )
665
+ // TODO: Can we model isolated/_const so that they're specified in both canParse* and parse*?
666
+ while self . at ( anyIn: TypeSpecifier . self) != nil || self . atContextualKeyword ( " isolated " ) || self . atContextualKeyword ( " _const " ) ,
667
+ specifierProgress. evaluate ( currentToken)
668
+ {
669
+ self . consumeAnyToken ( )
670
+ }
671
+
672
+ var attributeProgress = LoopProgressCondition ( )
673
+ while self . at ( . atSign) , attributeProgress. evaluate ( currentToken) {
674
+ self . consumeAnyToken ( )
675
+ self . skipTypeAttribute ( )
676
+ }
677
+ }
678
+
679
+ mutating func canParseTypeScalar( ) -> Bool {
642
680
self . skipTypeAttributeList ( )
643
681
682
+ guard self . canParseSimpleOrCompositionType ( ) else {
683
+ return false
684
+ }
685
+
686
+ if self . isAtFunctionTypeArrow ( ) {
687
+ // Handle type-function if we have an '->' with optional
688
+ // 'async' and/or 'throws'.
689
+ var loopProgress = LoopProgressCondition ( )
690
+ while let ( _, handle) = self . at ( anyIn: EffectsSpecifier . self) , loopProgress. evaluate ( currentToken) {
691
+ self . eat ( handle)
692
+ }
693
+
694
+ guard self . consume ( if: . arrow) != nil else {
695
+ return false
696
+ }
697
+
698
+ return self . canParseType ( )
699
+ }
700
+
701
+ return true
702
+ }
703
+
704
+ mutating func canParseSimpleOrCompositionType( ) -> Bool {
705
+ if self . atContextualKeyword ( " each " ) {
706
+ return self . canParseSimpleType ( ) ;
707
+ }
708
+
644
709
if self . atContextualKeyword ( " some " ) || self . atContextualKeyword ( " any " ) {
645
710
self . consumeAnyToken ( )
646
711
}
647
712
713
+ guard self . canParseSimpleType ( ) else {
714
+ return false
715
+ }
716
+
717
+ var loopCondition = LoopProgressCondition ( )
718
+ while self . atContextualPunctuator ( " & " ) && loopCondition. evaluate ( self . currentToken) {
719
+ self . consumeAnyToken ( )
720
+ guard self . canParseSimpleType ( ) else {
721
+ return false
722
+ }
723
+ }
724
+
725
+ return true
726
+ }
727
+
728
+ mutating func canParseSimpleType( ) -> Bool {
648
729
switch self . currentToken. tokenKind {
649
- case . capitalSelfKeyword, . anyKeyword, . identifier:
730
+ case . anyKeyword:
731
+ self . consumeAnyToken ( )
732
+ case . capitalSelfKeyword, . identifier:
650
733
guard self . canParseTypeIdentifier ( ) else {
651
734
return false
652
735
}
@@ -700,44 +783,9 @@ extension Parser.Lookahead {
700
783
break
701
784
}
702
785
703
- if self . isAtFunctionTypeArrow ( ) {
704
- // Handle type-function if we have an '->' with optional
705
- // 'async' and/or 'throws'.
706
- var loopProgress = LoopProgressCondition ( )
707
- while let ( _, handle) = self . at ( anyIn: EffectsSpecifier . self) , loopProgress. evaluate ( currentToken) {
708
- self . eat ( handle)
709
- }
710
-
711
- guard self . consume ( if: . arrow) != nil else {
712
- return false
713
- }
714
-
715
- return self . canParseType ( )
716
- }
717
-
718
- if self . currentToken. isEllipsis {
719
- self . consumeAnyToken ( )
720
- }
721
-
722
786
return true
723
787
}
724
788
725
- mutating func skipTypeAttributeList( ) {
726
- var specifierProgress = LoopProgressCondition ( )
727
- // TODO: Can we model isolated/_const so that they're specified in both canParse* and parse*?
728
- while self . at ( anyIn: TypeSpecifier . self) != nil || self . atContextualKeyword ( " isolated " ) || self . atContextualKeyword ( " _const " ) ,
729
- specifierProgress. evaluate ( currentToken)
730
- {
731
- self . consumeAnyToken ( )
732
- }
733
-
734
- var attributeProgress = LoopProgressCondition ( )
735
- while self . at ( . atSign) , attributeProgress. evaluate ( currentToken) {
736
- self . consumeAnyToken ( )
737
- self . skipTypeAttribute ( )
738
- }
739
- }
740
-
741
789
mutating func canParseTupleBodyType( ) -> Bool {
742
790
guard
743
791
!self . at ( any: [ . rightParen, . rightBrace] ) && !self . atContextualPunctuator ( " ... " ) && !self . atStartOfDeclaration ( )
@@ -793,30 +841,6 @@ extension Parser.Lookahead {
793
841
return self . consume ( if: . rightParen) != nil
794
842
}
795
843
796
- mutating func canParseSimpleType( ) -> Bool {
797
- var allowKeyword = false
798
- var loopCondition = LoopProgressCondition ( )
799
- while loopCondition. evaluate ( currentToken) {
800
- if !self . canParseTypeIdentifier ( ) {
801
- // Allow Foo.<keyword> but not <keyword> as the initial identifier
802
- if allowKeyword && self . currentToken. isKeyword {
803
- self . consumeAnyToken ( )
804
- } else {
805
- return false
806
- }
807
- }
808
-
809
- // Treat 'Foo.<anything>' as an attempt to write a dotted type
810
- if self . at ( . period) {
811
- self . consumeAnyToken ( )
812
- allowKeyword = true
813
- } else {
814
- return true
815
- }
816
- }
817
- preconditionFailure ( " Should return from inside the loop " )
818
- }
819
-
820
844
func isAtFunctionTypeArrow( ) -> Bool {
821
845
if self . at ( . arrow) {
822
846
return true
@@ -840,26 +864,14 @@ extension Parser.Lookahead {
840
864
return false
841
865
}
842
866
843
- mutating func canParseSimpleOrCompositionType( ) -> Bool {
844
- var loopCondition = LoopProgressCondition ( )
845
- while loopCondition. evaluate ( currentToken) {
846
- guard self . canParseSimpleType ( ) else {
847
- return false
848
- }
849
-
850
- if self . atContextualPunctuator ( " & " ) {
851
- self . consumeAnyToken ( )
852
- continue
853
- } else {
854
- return true
855
- }
867
+ mutating func canParseTypeIdentifier( allowKeyword: Bool = false ) -> Bool {
868
+ if self . at ( . anyKeyword) {
869
+ self . consumeAnyToken ( )
870
+ return true
856
871
}
857
- preconditionFailure ( " Should return from inside the loop " )
858
- }
859
872
860
- mutating func canParseTypeIdentifier( allowKeyword: Bool = false ) -> Bool {
861
873
// Parse an identifier.
862
- guard self . at ( . identifier) || self . at ( . capitalSelfKeyword) || self . at ( . anyKeyword ) || ( allowKeyword && self . currentToken. isKeyword) else {
874
+ guard self . at ( . identifier) || self . at ( . capitalSelfKeyword) || ( allowKeyword && self . currentToken. isKeyword) else {
863
875
return false
864
876
}
865
877
self . consumeAnyToken ( )
0 commit comments