@@ -128,6 +128,13 @@ public enum EffectSpecifier: TokenSpecSet {
128128 case . throwsSpecifier( let underlyingKind) : return underlyingKind. spec
129129 }
130130 }
131+
132+ var isThrowsSpecifier : Bool {
133+ switch self {
134+ case . asyncSpecifier: return false
135+ case . throwsSpecifier: return true
136+ }
137+ }
131138}
132139
133140// MARK: - EffectSpecifiersTrait
@@ -153,10 +160,12 @@ protocol RawMisplacedEffectSpecifiersTrait {
153160
154161 var asyncSpecifier : RawTokenSyntax ? { get }
155162 var throwsSpecifier : RawTokenSyntax ? { get }
163+ var thrownType : RawThrownTypeSyntax ? { get }
156164
157165 init (
158166 asyncSpecifier: RawTokenSyntax ? ,
159167 throwsSpecifier: RawTokenSyntax ? ,
168+ thrownType: RawThrownTypeSyntax ? ,
160169 arena: __shared SyntaxArena
161170 )
162171
@@ -166,14 +175,17 @@ protocol RawMisplacedEffectSpecifiersTrait {
166175protocol RawEffectSpecifiersTrait : RawMisplacedEffectSpecifiersTrait {
167176 var unexpectedBeforeAsyncSpecifier : RawUnexpectedNodesSyntax ? { get }
168177 var unexpectedBetweenAsyncSpecifierAndThrowsSpecifier : RawUnexpectedNodesSyntax ? { get }
169- var unexpectedAfterThrowsSpecifier : RawUnexpectedNodesSyntax ? { get }
170-
178+ var unexpectedBetweenThrowsSpecifierAndThrownType : RawUnexpectedNodesSyntax ? { get }
179+ var thrownType : RawThrownTypeSyntax ? { get }
180+ var unexpectedAfterThrownType : RawUnexpectedNodesSyntax ? { get }
171181 init (
172182 _ unexpectedBeforeAsyncSpecifier: RawUnexpectedNodesSyntax ? ,
173183 asyncSpecifier: RawTokenSyntax ? ,
174184 _ unexpectedBetweenAsyncSpecifierAndThrowsSpecifier: RawUnexpectedNodesSyntax ? ,
175185 throwsSpecifier: RawTokenSyntax ? ,
176- _ unexpectedAfterThrowsSpecifier: RawUnexpectedNodesSyntax ? ,
186+ _ unexpectedBetweenThrowsSpecifierAndThrownType: RawUnexpectedNodesSyntax ? ,
187+ thrownType: RawThrownTypeSyntax ? ,
188+ _ unexpectedAfterThrownType: RawUnexpectedNodesSyntax ? ,
177189 arena: __shared SyntaxArena
178190 )
179191}
@@ -182,6 +194,7 @@ extension RawEffectSpecifiersTrait {
182194 init (
183195 asyncSpecifier: RawTokenSyntax ? ,
184196 throwsSpecifier: RawTokenSyntax ? ,
197+ thrownType: RawThrownTypeSyntax ? ,
185198 arena: __shared SyntaxArena
186199 ) {
187200 self . init (
@@ -190,6 +203,8 @@ extension RawEffectSpecifiersTrait {
190203 nil ,
191204 throwsSpecifier: throwsSpecifier,
192205 nil ,
206+ thrownType: thrownType,
207+ nil ,
193208 arena: arena
194209 )
195210 }
@@ -200,7 +215,9 @@ extension RawEffectSpecifiersTrait {
200215 asyncSpecifier: self . asyncSpecifier ?? misplacedAsyncKeyword,
201216 self . unexpectedBetweenAsyncSpecifierAndThrowsSpecifier,
202217 throwsSpecifier: self . throwsSpecifier ?? misplacedThrowsKeyword,
203- self . unexpectedAfterThrowsSpecifier,
218+ self . unexpectedBetweenThrowsSpecifierAndThrownType,
219+ thrownType: thrownType,
220+ self . unexpectedAfterThrownType,
204221 arena: arena
205222 )
206223 }
@@ -521,10 +538,12 @@ extension RawDeinitializerEffectSpecifiersSyntax: RawMisplacedEffectSpecifiersTr
521538 }
522539
523540 var throwsSpecifier : RawTokenSyntax ? { nil }
541+ var thrownType : RawThrownTypeSyntax ? { nil }
524542
525543 init (
526544 asyncSpecifier: RawTokenSyntax ? ,
527545 throwsSpecifier: RawTokenSyntax ? ,
546+ thrownType: RawThrownTypeSyntax ? ,
528547 arena: __shared SwiftSyntax. SyntaxArena
529548 ) {
530549 // `throwsSpecifier` should never be present because `parseMisplacedEffectSpecifiers()` only creates missing tokens
@@ -577,12 +596,28 @@ extension TokenConsumer {
577596// MARK: - Parsing effect specifiers
578597
579598extension Parser {
599+ private mutating func parseThrownType( ) -> RawThrownTypeSyntax {
600+ let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
601+ let type = self . parseType ( )
602+ let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
603+ return RawThrownTypeSyntax (
604+ unexpectedBeforeLeftParen,
605+ leftParen: leftParen,
606+ type: type,
607+ unexpectedBeforeRightParen,
608+ rightParen: rightParen,
609+ arena: self . arena
610+ )
611+ }
612+
580613 private mutating func parseEffectSpecifiers< S: RawEffectSpecifiersTrait > ( _: S . Type ) -> S ? {
581614 var unexpectedBeforeAsync : [ RawSyntax ] = [ ]
582615 var asyncKeyword : RawTokenSyntax ? = nil
583616 var unexpectedBeforeThrows : [ RawSyntax ] = [ ]
584617 var throwsKeyword : RawTokenSyntax ?
585- var unexpectedAfterThrows : [ RawSyntax ] = [ ]
618+ var thrownType : RawThrownTypeSyntax ?
619+ var unexpectedAfterThrownType : [ RawSyntax ] = [ ]
620+
586621 while let misspelledAsync = self . consume ( ifAnyIn: S . MisspelledAsyncTokenKinds. self) {
587622 unexpectedBeforeAsync. append ( RawSyntax ( misspelledAsync) )
588623 if asyncKeyword == nil {
@@ -619,24 +654,28 @@ extension Parser {
619654 throwsKeyword = throwsKw
620655 }
621656
622- var unexpectedAfterThrowsLoopProgress = LoopProgressCondition ( )
623- while self . hasProgressed ( & unexpectedAfterThrowsLoopProgress) {
657+ if throwsKeyword != nil && self . at ( . leftParen) {
658+ thrownType = parseThrownType ( )
659+ }
660+
661+ var unexpectedAfterThrownTypeLoopProgress = LoopProgressCondition ( )
662+ while self . hasProgressed ( & unexpectedAfterThrownTypeLoopProgress) {
624663 if let ( _, handle, _) = self . at ( anyIn: S . MisspelledAsyncTokenKinds. self, or: S . CorrectAsyncTokenKinds. self) {
625664 let misspelledAsync = self . eat ( handle)
626- unexpectedAfterThrows . append ( RawSyntax ( misspelledAsync) )
665+ unexpectedAfterThrownType . append ( RawSyntax ( misspelledAsync) )
627666 if asyncKeyword == nil {
628667 // Handle `async` after `throws`
629668 asyncKeyword = missingToken ( . keyword( . async) )
630669 }
631670 } else if let ( _, handle, _) = self . at ( anyIn: S . MisspelledThrowsTokenKinds. self, or: S . CorrectThrowsTokenKinds. self) {
632671 let misspelledThrows = self . eat ( handle)
633- unexpectedAfterThrows . append ( RawSyntax ( misspelledThrows) )
672+ unexpectedAfterThrownType . append ( RawSyntax ( misspelledThrows) )
634673 } else {
635674 break
636675 }
637676 }
638677
639- if unexpectedBeforeAsync. isEmpty && asyncKeyword == nil && unexpectedBeforeThrows. isEmpty && throwsKeyword == nil && unexpectedAfterThrows . isEmpty {
678+ if unexpectedBeforeAsync. isEmpty && asyncKeyword == nil && unexpectedBeforeThrows. isEmpty && throwsKeyword == nil && thrownType == nil && unexpectedAfterThrownType . isEmpty {
640679 return nil
641680 }
642681
@@ -645,7 +684,9 @@ extension Parser {
645684 asyncSpecifier: asyncKeyword,
646685 RawUnexpectedNodesSyntax ( unexpectedBeforeThrows, arena: self . arena) ,
647686 throwsSpecifier: throwsKeyword,
648- RawUnexpectedNodesSyntax ( unexpectedAfterThrows, arena: self . arena) ,
687+ nil ,
688+ thrownType: thrownType,
689+ RawUnexpectedNodesSyntax ( unexpectedAfterThrownType, arena: self . arena) ,
649690 arena: self . arena
650691 )
651692 }
@@ -749,6 +790,7 @@ extension Parser {
749790 effectSpecifiers = S (
750791 asyncSpecifier: synthesizedAsync,
751792 throwsSpecifier: synthesizedThrows,
793+ thrownType: nil ,
752794 arena: self . arena
753795 )
754796 }
0 commit comments