Parse the end of a character class set and pop the character class parser stack. The union given corresponds to the last union built before seeing the closing `]`. The union returned corresponds to the parent character class set with the nested class added to it. This assumes that the parser is positioned at a `]` and will advance the parser to the byte immediately following the `]`. If the stac
(
&self,
nested_union: ast::ClassSetUnion,
)
| 860 | /// If there is no corresponding opening bracket on the parser's stack, |
| 861 | /// then an error is returned. |
| 862 | fn pop_class( |
| 863 | &self, |
| 864 | nested_union: ast::ClassSetUnion, |
| 865 | ) -> Result<Either<ast::ClassSetUnion, ast::Class>> { |
| 866 | assert_eq!(self.char(), ']'); |
| 867 | |
| 868 | let item = ast::ClassSet::Item(nested_union.into_item()); |
| 869 | let prevset = self.pop_class_op(item); |
| 870 | let mut stack = self.parser().stack_class.borrow_mut(); |
| 871 | match stack.pop() { |
| 872 | None => { |
| 873 | // We can never observe an empty stack: |
| 874 | // |
| 875 | // 1) We are guaranteed to start with a non-empty stack since |
| 876 | // the character class parser is only initiated when it sees |
| 877 | // a `[`. |
| 878 | // 2) If we ever observe an empty stack while popping after |
| 879 | // seeing a `]`, then we signal the character class parser |
| 880 | // to terminate. |
| 881 | panic!("unexpected empty character class stack") |
| 882 | }, |
| 883 | Some(ClassState::Op { .. }) => { |
| 884 | // This panic is unfortunate, but this case is impossible |
| 885 | // since we already popped the Op state if one exists above. |
| 886 | // Namely, every push to the class parser stack is guarded by |
| 887 | // whether an existing Op is already on the top of the stack. |
| 888 | // If it is, the existing Op is modified. That is, the stack |
| 889 | // can never have consecutive Op states. |
| 890 | panic!("unexpected ClassState::Op") |
| 891 | } |
| 892 | Some(ClassState::Open { mut union, mut set }) => { |
| 893 | self.bump(); |
| 894 | set.span.end = self.pos(); |
| 895 | set.kind = prevset; |
| 896 | if stack.is_empty() { |
| 897 | Ok(Either::Right(ast::Class::Bracketed(set))) |
| 898 | } else { |
| 899 | union.push(ast::ClassSetItem::Bracketed(Box::new(set))); |
| 900 | Ok(Either::Left(union)) |
| 901 | } |
| 902 | } |
| 903 | } |
| 904 | } |
| 905 | |
| 906 | /// Return an "unclosed class" error whose span points to the most |
| 907 | /// recently opened class. |
no test coverage detected