aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/subtree_source.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-05-25 13:31:53 +0100
committerEdwin Cheng <[email protected]>2019-05-25 13:41:03 +0100
commitfcb1eef3232c3fc673bf5f98595708e108c3950c (patch)
tree326a3961c5ca99cb50a12fb94f3398116af4a2f1 /crates/ra_mbe/src/subtree_source.rs
parentef00b5af1c7a7a7cac685eff661a10252825d84a (diff)
Change TokenSource to iteration based
Diffstat (limited to 'crates/ra_mbe/src/subtree_source.rs')
-rw-r--r--crates/ra_mbe/src/subtree_source.rs59
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 @@
1use ra_parser::{TokenSource}; 1use ra_parser::{TokenSource, Token};
2use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T}; 2use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T};
3use std::cell::{RefCell, Cell}; 3use std::cell::{RefCell, Cell};
4use std::sync::Arc;
4use tt::buffer::{TokenBuffer, Cursor}; 5use tt::buffer::{TokenBuffer, Cursor};
5 6
6pub(crate) trait Querier { 7pub(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
119pub(crate) struct SubtreeTokenSource<'a> { 120pub(crate) struct SubtreeTokenSource<'a> {
120 walker: SubtreeWalk<'a>, 121 walker: Arc<SubtreeWalk<'a>>,
122 curr: (Token, usize),
121} 123}
122 124
123impl<'a> SubtreeTokenSource<'a> { 125impl<'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
141impl<'a> TokenSource for SubtreeTokenSource<'a> { 152impl<'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 }