aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/subtree_parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src/subtree_parser.rs')
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs42
1 files changed, 31 insertions, 11 deletions
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
index 9cc989b23..1f12e42ef 100644
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ b/crates/ra_mbe/src/subtree_parser.rs
@@ -2,16 +2,38 @@ use crate::subtree_source::SubtreeTokenSource;
2 2
3use ra_parser::{TokenSource, TreeSink}; 3use ra_parser::{TokenSource, TreeSink};
4use ra_syntax::{SyntaxKind}; 4use ra_syntax::{SyntaxKind};
5use tt::buffer::TokenBuffer; 5use tt::buffer::{TokenBuffer, Cursor};
6 6
7struct OffsetTokenSink { 7struct OffsetTokenSink<'a> {
8 token_pos: usize, 8 cursor: Cursor<'a>,
9 error: bool, 9 error: bool,
10} 10}
11 11
12impl TreeSink for OffsetTokenSink { 12impl<'a> OffsetTokenSink<'a> {
13 pub fn collect(&self, begin: Cursor<'a>) -> Vec<tt::TokenTree> {
14 if !self.cursor.is_root() {
15 return vec![];
16 }
17
18 let mut curr = begin;
19 let mut res = vec![];
20
21 while self.cursor != curr {
22 if let Some(token) = curr.token_tree() {
23 res.push(token);
24 }
25 curr = curr.bump();
26 }
27
28 res
29 }
30}
31
32impl<'a> TreeSink for OffsetTokenSink<'a> {
13 fn token(&mut self, _kind: SyntaxKind, n_tokens: u8) { 33 fn token(&mut self, _kind: SyntaxKind, n_tokens: u8) {
14 self.token_pos += n_tokens as usize; 34 for _ in 0..n_tokens {
35 self.cursor = self.cursor.bump_subtree();
36 }
15 } 37 }
16 fn start_node(&mut self, _kind: SyntaxKind) {} 38 fn start_node(&mut self, _kind: SyntaxKind) {}
17 fn finish_node(&mut self) {} 39 fn finish_node(&mut self) {}
@@ -72,23 +94,21 @@ impl<'a> Parser<'a> {
72 { 94 {
73 let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]); 95 let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]);
74 let mut src = SubtreeTokenSource::new(&buffer); 96 let mut src = SubtreeTokenSource::new(&buffer);
75 let mut sink = OffsetTokenSink { token_pos: 0, error: false }; 97 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false };
76 98
77 f(&mut src, &mut sink); 99 f(&mut src, &mut sink);
78 100
79 let r = self.finish(sink.token_pos, &mut src); 101 let r = self.finish(buffer.begin(), &mut sink);
80 if sink.error { 102 if sink.error {
81 return None; 103 return None;
82 } 104 }
83 r 105 r
84 } 106 }
85 107
86 fn finish(self, parsed_token: usize, src: &mut SubtreeTokenSource) -> Option<tt::TokenTree> { 108 fn finish(self, begin: Cursor, sink: &mut OffsetTokenSink) -> Option<tt::TokenTree> {
87 let res = src.bump_n(parsed_token); 109 let res = sink.collect(begin);
88 *self.cur_pos += res.len(); 110 *self.cur_pos += res.len();
89 111
90 let res: Vec<_> = res.into_iter().collect();
91
92 match res.len() { 112 match res.len() {
93 0 => None, 113 0 => None,
94 1 => Some(res[0].clone()), 114 1 => Some(res[0].clone()),