diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_mbe/src/subtree_parser.rs | 42 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 63 | ||||
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 6 |
3 files changed, 39 insertions, 72 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 | ||
3 | use ra_parser::{TokenSource, TreeSink}; | 3 | use ra_parser::{TokenSource, TreeSink}; |
4 | use ra_syntax::{SyntaxKind}; | 4 | use ra_syntax::{SyntaxKind}; |
5 | use tt::buffer::TokenBuffer; | 5 | use tt::buffer::{TokenBuffer, Cursor}; |
6 | 6 | ||
7 | struct OffsetTokenSink { | 7 | struct OffsetTokenSink<'a> { |
8 | token_pos: usize, | 8 | cursor: Cursor<'a>, |
9 | error: bool, | 9 | error: bool, |
10 | } | 10 | } |
11 | 11 | ||
12 | impl TreeSink for OffsetTokenSink { | 12 | impl<'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 | |||
32 | impl<'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()), |
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 2ba0b1601..8d6fd3e43 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -11,8 +11,7 @@ struct TtToken { | |||
11 | } | 11 | } |
12 | 12 | ||
13 | pub(crate) struct SubtreeTokenSource<'a> { | 13 | pub(crate) struct SubtreeTokenSource<'a> { |
14 | start: Cursor<'a>, | 14 | cached_cursor: Cell<Cursor<'a>>, |
15 | cursor: Cell<Cursor<'a>>, | ||
16 | cached: RefCell<Vec<Option<TtToken>>>, | 15 | cached: RefCell<Vec<Option<TtToken>>>, |
17 | curr: (Token, usize), | 16 | curr: (Token, usize), |
18 | } | 17 | } |
@@ -34,19 +33,13 @@ impl<'a> SubtreeTokenSource<'a> { | |||
34 | 33 | ||
35 | let mut res = SubtreeTokenSource { | 34 | let mut res = SubtreeTokenSource { |
36 | curr: (Token { kind: EOF, is_jointed_to_next: false }, 0), | 35 | curr: (Token { kind: EOF, is_jointed_to_next: false }, 0), |
37 | start: cursor, | 36 | cached_cursor: Cell::new(cursor), |
38 | cursor: Cell::new(cursor), | ||
39 | cached: RefCell::new(Vec::with_capacity(10)), | 37 | cached: RefCell::new(Vec::with_capacity(10)), |
40 | }; | 38 | }; |
41 | res.curr = (res.mk_token(0), 0); | 39 | res.curr = (res.mk_token(0), 0); |
42 | res | 40 | res |
43 | } | 41 | } |
44 | 42 | ||
45 | pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> { | ||
46 | let res = self.collect_token_trees(parsed_tokens); | ||
47 | res | ||
48 | } | ||
49 | |||
50 | fn mk_token(&self, pos: usize) -> Token { | 43 | fn mk_token(&self, pos: usize) -> Token { |
51 | match self.get(pos) { | 44 | match self.get(pos) { |
52 | Some(tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next }, | 45 | Some(tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next }, |
@@ -61,7 +54,7 @@ impl<'a> SubtreeTokenSource<'a> { | |||
61 | } | 54 | } |
62 | 55 | ||
63 | while pos >= cached.len() { | 56 | while pos >= cached.len() { |
64 | let cursor = self.cursor.get(); | 57 | let cursor = self.cached_cursor.get(); |
65 | if cursor.eof() { | 58 | if cursor.eof() { |
66 | cached.push(None); | 59 | cached.push(None); |
67 | continue; | 60 | continue; |
@@ -70,16 +63,16 @@ impl<'a> SubtreeTokenSource<'a> { | |||
70 | match cursor.token_tree() { | 63 | match cursor.token_tree() { |
71 | Some(tt::TokenTree::Leaf(leaf)) => { | 64 | Some(tt::TokenTree::Leaf(leaf)) => { |
72 | cached.push(Some(convert_leaf(&leaf))); | 65 | cached.push(Some(convert_leaf(&leaf))); |
73 | self.cursor.set(cursor.bump()); | 66 | self.cached_cursor.set(cursor.bump()); |
74 | } | 67 | } |
75 | Some(tt::TokenTree::Subtree(subtree)) => { | 68 | Some(tt::TokenTree::Subtree(subtree)) => { |
76 | self.cursor.set(cursor.subtree().unwrap()); | 69 | self.cached_cursor.set(cursor.subtree().unwrap()); |
77 | cached.push(Some(convert_delim(subtree.delimiter, false))); | 70 | cached.push(Some(convert_delim(subtree.delimiter, false))); |
78 | } | 71 | } |
79 | None => { | 72 | None => { |
80 | if let Some(subtree) = cursor.end() { | 73 | if let Some(subtree) = cursor.end() { |
81 | cached.push(Some(convert_delim(subtree.delimiter, true))); | 74 | cached.push(Some(convert_delim(subtree.delimiter, true))); |
82 | self.cursor.set(cursor.bump()); | 75 | self.cached_cursor.set(cursor.bump()); |
83 | } | 76 | } |
84 | } | 77 | } |
85 | } | 78 | } |
@@ -87,48 +80,6 @@ impl<'a> SubtreeTokenSource<'a> { | |||
87 | 80 | ||
88 | return cached[pos].clone(); | 81 | return cached[pos].clone(); |
89 | } | 82 | } |
90 | |||
91 | fn collect_token_trees(&self, n: usize) -> Vec<tt::TokenTree> { | ||
92 | let mut res = vec![]; | ||
93 | |||
94 | let mut pos = 0; | ||
95 | let mut cursor = self.start; | ||
96 | let mut level = 0; | ||
97 | |||
98 | while pos < n { | ||
99 | if cursor.eof() { | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | match cursor.token_tree() { | ||
104 | Some(tt::TokenTree::Leaf(leaf)) => { | ||
105 | if level == 0 { | ||
106 | res.push(leaf.into()); | ||
107 | } | ||
108 | cursor = cursor.bump(); | ||
109 | pos += 1; | ||
110 | } | ||
111 | Some(tt::TokenTree::Subtree(subtree)) => { | ||
112 | if level == 0 { | ||
113 | res.push(subtree.into()); | ||
114 | } | ||
115 | pos += 1; | ||
116 | level += 1; | ||
117 | cursor = cursor.subtree().unwrap(); | ||
118 | } | ||
119 | |||
120 | None => { | ||
121 | if let Some(_) = cursor.end() { | ||
122 | level -= 1; | ||
123 | pos += 1; | ||
124 | cursor = cursor.bump(); | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | res | ||
131 | } | ||
132 | } | 83 | } |
133 | 84 | ||
134 | impl<'a> TokenSource for SubtreeTokenSource<'a> { | 85 | impl<'a> TokenSource for SubtreeTokenSource<'a> { |
@@ -147,7 +98,7 @@ impl<'a> TokenSource for SubtreeTokenSource<'a> { | |||
147 | return; | 98 | return; |
148 | } | 99 | } |
149 | 100 | ||
150 | self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1) | 101 | self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1); |
151 | } | 102 | } |
152 | 103 | ||
153 | /// Is the current token a specified keyword? | 104 | /// Is the current token a specified keyword? |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 058f65ffd..caeb842b1 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -298,11 +298,7 @@ fn delim_to_str(d: tt::Delimiter, closing: bool) -> SmolStr { | |||
298 | impl<'a> TreeSink for TtTreeSink<'a> { | 298 | impl<'a> TreeSink for TtTreeSink<'a> { |
299 | fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { | 299 | fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { |
300 | if kind == L_DOLLAR || kind == R_DOLLAR { | 300 | if kind == L_DOLLAR || kind == R_DOLLAR { |
301 | if let Some(_) = self.cursor.end() { | 301 | self.cursor = self.cursor.bump_subtree(); |
302 | self.cursor = self.cursor.bump(); | ||
303 | } else { | ||
304 | self.cursor = self.cursor.subtree().unwrap(); | ||
305 | } | ||
306 | return; | 302 | return; |
307 | } | 303 | } |
308 | 304 | ||