diff options
Diffstat (limited to 'crates/ra_mbe/src/subtree_source.rs')
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 972af4a7c..c4f79f38a 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | use ra_parser::{TokenSource}; | 1 | use ra_parser::{TokenSource, Token}; |
2 | use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T}; | 2 | use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T}; |
3 | use std::cell::{RefCell, Cell}; | 3 | use std::cell::{RefCell, Cell}; |
4 | use std::sync::Arc; | ||
4 | use tt::buffer::{TokenBuffer, Cursor}; | 5 | use tt::buffer::{TokenBuffer, Cursor}; |
5 | 6 | ||
6 | pub(crate) trait Querier { | 7 | pub(crate) trait Querier { |
@@ -65,7 +66,7 @@ impl<'a> SubtreeWalk<'a> { | |||
65 | return cached[pos].clone(); | 66 | return cached[pos].clone(); |
66 | } | 67 | } |
67 | 68 | ||
68 | fn collect_token_trees(&mut self, n: usize) -> Vec<tt::TokenTree> { | 69 | fn collect_token_trees(&self, n: usize) -> Vec<tt::TokenTree> { |
69 | let mut res = vec![]; | 70 | let mut res = vec![]; |
70 | 71 | ||
71 | let mut pos = 0; | 72 | let mut pos = 0; |
@@ -117,43 +118,59 @@ impl<'a> Querier for SubtreeWalk<'a> { | |||
117 | } | 118 | } |
118 | 119 | ||
119 | pub(crate) struct SubtreeTokenSource<'a> { | 120 | pub(crate) struct SubtreeTokenSource<'a> { |
120 | walker: SubtreeWalk<'a>, | 121 | walker: Arc<SubtreeWalk<'a>>, |
122 | curr: (Token, usize), | ||
121 | } | 123 | } |
122 | 124 | ||
123 | impl<'a> SubtreeTokenSource<'a> { | 125 | impl<'a> SubtreeTokenSource<'a> { |
124 | pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> { | 126 | pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> { |
125 | SubtreeTokenSource { walker: SubtreeWalk::new(buffer.begin()) } | 127 | let mut res = SubtreeTokenSource { |
128 | walker: Arc::new(SubtreeWalk::new(buffer.begin())), | ||
129 | curr: (Token { kind: EOF, is_jointed_to_next: false }, 0), | ||
130 | }; | ||
131 | res.curr = (res.mk_token(0), 0); | ||
132 | res | ||
126 | } | 133 | } |
127 | 134 | ||
128 | pub fn querier<'b>(&'a self) -> &'b SubtreeWalk<'a> | 135 | pub fn querier(&self) -> Arc<SubtreeWalk<'a>> { |
129 | where | 136 | self.walker.clone() |
130 | 'a: 'b, | ||
131 | { | ||
132 | &self.walker | ||
133 | } | 137 | } |
134 | 138 | ||
135 | pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> { | 139 | pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> { |
136 | let res = self.walker.collect_token_trees(parsed_tokens); | 140 | let res = self.walker.collect_token_trees(parsed_tokens); |
137 | res | 141 | res |
138 | } | 142 | } |
143 | |||
144 | fn mk_token(&self, pos: usize) -> Token { | ||
145 | match self.walker.get(pos) { | ||
146 | Some(tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next }, | ||
147 | None => Token { kind: EOF, is_jointed_to_next: false }, | ||
148 | } | ||
149 | } | ||
139 | } | 150 | } |
140 | 151 | ||
141 | impl<'a> TokenSource for SubtreeTokenSource<'a> { | 152 | impl<'a> TokenSource for SubtreeTokenSource<'a> { |
142 | fn token_kind(&self, pos: usize) -> SyntaxKind { | 153 | fn current(&self) -> Token { |
143 | if let Some(tok) = self.walker.get(pos) { | 154 | self.curr.0 |
144 | tok.kind | ||
145 | } else { | ||
146 | SyntaxKind::EOF | ||
147 | } | ||
148 | } | 155 | } |
149 | fn is_token_joint_to_next(&self, pos: usize) -> bool { | 156 | |
150 | match self.walker.get(pos) { | 157 | /// Lookahead n token |
151 | Some(t) => t.is_joint_to_next, | 158 | fn lookahead_nth(&self, n: usize) -> Token { |
152 | _ => false, | 159 | self.mk_token(self.curr.1 + n) |
160 | } | ||
161 | |||
162 | /// bump cursor to next token | ||
163 | fn bump(&mut self) { | ||
164 | if self.current().kind == EOF { | ||
165 | return; | ||
153 | } | 166 | } |
167 | |||
168 | self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1) | ||
154 | } | 169 | } |
155 | fn is_keyword(&self, pos: usize, kw: &str) -> bool { | 170 | |
156 | match self.walker.get(pos) { | 171 | /// Is the current token a specified keyword? |
172 | fn is_keyword(&self, kw: &str) -> bool { | ||
173 | match self.walker.get(self.curr.1) { | ||
157 | Some(t) => t.text == *kw, | 174 | Some(t) => t.text == *kw, |
158 | _ => false, | 175 | _ => false, |
159 | } | 176 | } |