@@ -94,6 +94,19 @@ fn and_chain(
9494 . expect ( "control-flow statement must have at least one condition" )
9595}
9696
97+ /// Return the only pattern unchanged when there is exactly one, otherwise
98+ /// wrap the list in an `or_pattern`.
99+ fn make_or_pattern (
100+ ctx : & mut yeast:: build:: BuildCtx < ' _ , SwiftContext > ,
101+ items : Vec < yeast:: Id > ,
102+ ) -> yeast:: Id {
103+ if items. len ( ) == 1 {
104+ items[ 0 ]
105+ } else {
106+ tree ! ( ( or_pattern pattern: { items} ) )
107+ }
108+ }
109+
97110/// Translate a multi-part identifier (for example `Foo.Bar.Baz`) into a
98111/// `member_access_expr` chain rooted at a `name_expr` over the first
99112/// part. Panics on an empty input because the grammar's `_+` quantifier
@@ -746,22 +759,17 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
746759 rule!(
747760 ( switchCase label: ( switchCaseLabel caseItems: _* @items) statements: _* @body)
748761 =>
749- switch_case {
750- let pattern = if items. len( ) == 1 {
751- items[ 0 ]
752- } else {
753- tree!( ( or_pattern pattern: { items} ) )
754- } ;
755- tree!( ( switch_case pattern: { pattern} body: ( block stmt: { body} ) ) )
756- }
762+ ( switch_case
763+ pattern: { make_or_pattern( & mut ctx, items) }
764+ body: ( block stmt: { body} ) )
757765 ) ,
758766 rule!(
759767 ( switchCase label: ( switchDefaultLabel) statements: _* @body)
760768 =>
761769 ( switch_case body: ( block stmt: { body} ) )
762770 ) ,
763- // A single case item unwraps to its pattern (used as an `or_pattern`
764- // element).
771+ // A single case item unwraps to its pattern, possibly boxed in conditional_pattern
772+ rule! ( ( switchCaseItem pattern : @p whereClause : ( whereClause condition : @cond ) ) => ( conditional_pattern pattern : { p } condition : { cond } ) ) ,
765773 rule!( ( switchCaseItem pattern: @p) => pattern { p } ) ,
766774 // A pattern-matching condition (`if case let x = e`, `if case .foo(let x)
767775 // = e`) becomes a `pattern_guard_expr`: the matched pattern and the
@@ -877,17 +885,24 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
877885 body: { body}
878886 catch_clause: { catches} )
879887 ) ,
880- // Catch block with bound identifier; optional where-clause guard.
888+ rule!(
889+ ( catchItem pattern: @pattern whereClause: ( whereClause condition: @guard) )
890+ =>
891+ ( conditional_pattern pattern: { pattern} condition: { guard} )
892+ ) ,
893+ rule!(
894+ ( catchItem pattern: @pattern)
895+ =>
896+ pattern { pattern}
897+ ) ,
898+ // Catch block with one or more patterns (which have been translated by the catchItem rules)
881899 rule!(
882900 ( catchClause
883- catchItems: ( catchItem
884- pattern: @pattern
885- whereClause: ( whereClause condition: @guard) ?)
901+ catchItems: _+ @patterns
886902 body: @body)
887903 =>
888904 ( catch_clause
889- pattern: { pattern}
890- guard: { guard}
905+ pattern: { make_or_pattern( & mut ctx, patterns) }
891906 body: { body} )
892907 ) ,
893908 // Catch block without error binding
0 commit comments