aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs42
-rw-r--r--crates/ra_mbe/src/subtree_source.rs63
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs6
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
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()),
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
13pub(crate) struct SubtreeTokenSource<'a> { 13pub(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
134impl<'a> TokenSource for SubtreeTokenSource<'a> { 85impl<'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 {
298impl<'a> TreeSink for TtTreeSink<'a> { 298impl<'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