Parses a list of elements where each element is parsed using the given `parse_element` function.
(
&mut self,
recovery_context_kind: RecoveryContextKind,
mut parse_element: impl FnMut(&mut Parser<'src>),
)
| 724 | /// Parses a list of elements where each element is parsed using the given |
| 725 | /// `parse_element` function. |
| 726 | fn parse_list( |
| 727 | &mut self, |
| 728 | recovery_context_kind: RecoveryContextKind, |
| 729 | mut parse_element: impl FnMut(&mut Parser<'src>), |
| 730 | ) { |
| 731 | let mut progress = ParserProgress::default(); |
| 732 | let mut unexpected_indents = 0; |
| 733 | |
| 734 | let saved_context = self.recovery_context; |
| 735 | self.recovery_context = self |
| 736 | .recovery_context |
| 737 | .union(RecoveryContext::from_kind(recovery_context_kind)); |
| 738 | |
| 739 | loop { |
| 740 | progress.assert_progressing(self); |
| 741 | |
| 742 | if 0 < unexpected_indents && self.at(TokenKind::Dedent) { |
| 743 | // Ignore this `Dedent` like we ignored the `Indent`, avoiding extra errors from |
| 744 | // being imbalanced |
| 745 | unexpected_indents -= 1; |
| 746 | self.bump(TokenKind::Dedent); |
| 747 | } else if recovery_context_kind.is_list_element(self) { |
| 748 | parse_element(self); |
| 749 | } else if recovery_context_kind.is_regular_list_terminator(self) { |
| 750 | break; |
| 751 | } else { |
| 752 | // Run the error recovery: If the token is recognised as an element or terminator |
| 753 | // of an enclosing list, then we try to re-lex in the context of a logical line and |
| 754 | // break out of list parsing. |
| 755 | if self.is_enclosing_list_element_or_terminator() { |
| 756 | self.tokens.re_lex_logical_token(); |
| 757 | break; |
| 758 | } |
| 759 | |
| 760 | self.add_error( |
| 761 | recovery_context_kind.create_error(self), |
| 762 | self.current_token_range(), |
| 763 | ); |
| 764 | |
| 765 | if matches!( |
| 766 | recovery_context_kind, |
| 767 | RecoveryContextKind::ModuleStatements | RecoveryContextKind::BlockStatements |
| 768 | ) && self.at(TokenKind::Indent) |
| 769 | { |
| 770 | // For this invalid `Indent`, ensure the matching `Dedent` gets consumed as well |
| 771 | unexpected_indents += 1; |
| 772 | } |
| 773 | self.bump_any(); |
| 774 | } |
| 775 | } |
| 776 | |
| 777 | self.recovery_context = saved_context; |
| 778 | } |
| 779 | |
| 780 | /// Parses a comma separated list of elements into a vector where each element |
| 781 | /// is parsed using the given `parse_element` function. |
no test coverage detected