Parses a sequence of clauses. The parser only continues for as long as it sees the token indicating the start of the specific clause. Unlike [`Parser::parse_list`], this method does not perform error recovery when the next token is not a list terminator or the start of a list element. The special method is necessary because Python uses indentation over explicit delimiters to indicate the end of
(
&mut self,
clause: Clause,
mut parse_clause: impl FnMut(&mut Parser<'src>) -> T,
)
| 4001 | /// `Else`) to the recovery context so that expression recovery stops when it encounters an |
| 4002 | /// `else` token. |
| 4003 | fn parse_clauses<T>( |
| 4004 | &mut self, |
| 4005 | clause: Clause, |
| 4006 | mut parse_clause: impl FnMut(&mut Parser<'src>) -> T, |
| 4007 | ) -> Vec<T> { |
| 4008 | let mut clauses = Vec::new(); |
| 4009 | let mut progress = ParserProgress::default(); |
| 4010 | |
| 4011 | let recovery_kind = match clause { |
| 4012 | Clause::ElIf => RecoveryContextKind::Elif, |
| 4013 | Clause::Except => RecoveryContextKind::Except, |
| 4014 | _ => unreachable!("Clause is not supported"), |
| 4015 | }; |
| 4016 | |
| 4017 | let saved_context = self.recovery_context; |
| 4018 | self.recovery_context = self |
| 4019 | .recovery_context |
| 4020 | .union(RecoveryContext::from_kind(recovery_kind)); |
| 4021 | |
| 4022 | while recovery_kind.is_list_element(self) { |
| 4023 | progress.assert_progressing(self); |
| 4024 | |
| 4025 | if clauses.is_empty() { |
| 4026 | clauses.reserve_exact(1); |
| 4027 | } |
| 4028 | clauses.push(parse_clause(self)); |
| 4029 | } |
| 4030 | |
| 4031 | self.recovery_context = saved_context; |
| 4032 | |
| 4033 | clauses |
| 4034 | } |
| 4035 | } |
| 4036 | |
| 4037 | #[derive(Copy, Clone)] |
no test coverage detected