diff options
Diffstat (limited to 'crates/ra_mbe/src/tt_cursor.rs')
-rw-r--r-- | crates/ra_mbe/src/tt_cursor.rs | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs index eef642a9c..53bc305be 100644 --- a/crates/ra_mbe/src/tt_cursor.rs +++ b/crates/ra_mbe/src/tt_cursor.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use crate::ParseError; | 1 | use crate::ParseError; |
2 | use crate::subtree_parser::Parser; | 2 | use crate::subtree_parser::Parser; |
3 | use crate::subtree_source::TokenPeek; | ||
4 | use smallvec::{SmallVec, smallvec}; | 3 | use smallvec::{SmallVec, smallvec}; |
5 | 4 | ||
6 | #[derive(Debug, Clone)] | 5 | #[derive(Debug, Clone)] |
@@ -153,7 +152,7 @@ impl<'a> TtCursor<'a> { | |||
153 | pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { | 152 | pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { |
154 | let parser = Parser::new(&mut self.pos, self.subtree); | 153 | let parser = Parser::new(&mut self.pos, self.subtree); |
155 | parser.parse_vis() | 154 | parser.parse_vis() |
156 | } | 155 | } |
157 | 156 | ||
158 | pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { | 157 | pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { |
159 | if self.at_char(char) { | 158 | if self.at_char(char) { |
@@ -262,3 +261,48 @@ impl<'a> TtCursor<'a> { | |||
262 | self.pos = memento.pos; | 261 | self.pos = memento.pos; |
263 | } | 262 | } |
264 | } | 263 | } |
264 | |||
265 | pub(crate) struct TokenPeek<'a, I> | ||
266 | where | ||
267 | I: Iterator<Item = &'a tt::TokenTree>, | ||
268 | { | ||
269 | iter: itertools::MultiPeek<I>, | ||
270 | } | ||
271 | |||
272 | // helper function | ||
273 | fn to_punct(tt: &tt::TokenTree) -> Option<&tt::Punct> { | ||
274 | if let tt::TokenTree::Leaf(tt::Leaf::Punct(pp)) = tt { | ||
275 | return Some(pp); | ||
276 | } | ||
277 | None | ||
278 | } | ||
279 | |||
280 | impl<'a, I> TokenPeek<'a, I> | ||
281 | where | ||
282 | I: Iterator<Item = &'a tt::TokenTree>, | ||
283 | { | ||
284 | pub fn new(iter: I) -> Self { | ||
285 | TokenPeek { iter: itertools::multipeek(iter) } | ||
286 | } | ||
287 | |||
288 | pub fn current_punct2(&mut self, p: &tt::Punct) -> Option<((char, char), bool)> { | ||
289 | if p.spacing != tt::Spacing::Joint { | ||
290 | return None; | ||
291 | } | ||
292 | |||
293 | self.iter.reset_peek(); | ||
294 | let p1 = to_punct(self.iter.peek()?)?; | ||
295 | Some(((p.char, p1.char), p1.spacing == tt::Spacing::Joint)) | ||
296 | } | ||
297 | |||
298 | pub fn current_punct3(&mut self, p: &tt::Punct) -> Option<((char, char, char), bool)> { | ||
299 | self.current_punct2(p).and_then(|((p0, p1), last_joint)| { | ||
300 | if !last_joint { | ||
301 | None | ||
302 | } else { | ||
303 | let p2 = to_punct(*self.iter.peek()?)?; | ||
304 | Some(((p0, p1, p2.char), p2.spacing == tt::Spacing::Joint)) | ||
305 | } | ||
306 | }) | ||
307 | } | ||
308 | } | ||