aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs64
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs48
2 files changed, 80 insertions, 32 deletions
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index e0f228ce9..3521b382a 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -148,30 +148,21 @@ fn convert_tt(
148 match child { 148 match child {
149 SyntaxElement::Token(token) => { 149 SyntaxElement::Token(token) => {
150 if token.kind().is_punct() { 150 if token.kind().is_punct() {
151 let mut prev = None; 151 assert!(token.text().len() == 1, "Input ast::token punct must be single char.");
152 for char in token.text().chars() { 152 let char = token.text().chars().next().unwrap();
153 if let Some(char) = prev { 153
154 token_trees.push( 154 let spacing = match child_iter.peek() {
155 tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Joint }) 155 Some(SyntaxElement::Token(token)) => {
156 .into(), 156 if token.kind().is_punct() {
157 ); 157 tt::Spacing::Joint
158 } 158 } else {
159 prev = Some(char) 159 tt::Spacing::Alone
160 }
161 if let Some(char) = prev {
162 let spacing = match child_iter.peek() {
163 Some(SyntaxElement::Token(token)) => {
164 if token.kind().is_punct() {
165 tt::Spacing::Joint
166 } else {
167 tt::Spacing::Alone
168 }
169 } 160 }
170 _ => tt::Spacing::Alone, 161 }
171 }; 162 _ => tt::Spacing::Alone,
163 };
172 164
173 token_trees.push(tt::Leaf::from(tt::Punct { char, spacing }).into()); 165 token_trees.push(tt::Leaf::from(tt::Punct { char, spacing }).into());
174 }
175 } else { 166 } else {
176 let child: tt::TokenTree = if token.kind() == SyntaxKind::TRUE_KW 167 let child: tt::TokenTree = if token.kind() == SyntaxKind::TRUE_KW
177 || token.kind() == SyntaxKind::FALSE_KW 168 || token.kind() == SyntaxKind::FALSE_KW
@@ -224,6 +215,15 @@ impl<'a, Q: Querier> TtTreeSink<'a, Q> {
224 } 215 }
225} 216}
226 217
218fn is_delimiter(kind: SyntaxKind) -> bool {
219 use SyntaxKind::*;
220
221 match kind {
222 L_PAREN | L_BRACK | L_CURLY | R_PAREN | R_BRACK | R_CURLY => true,
223 _ => false,
224 }
225}
226
227impl<'a, Q: Querier> TreeSink for TtTreeSink<'a, Q> { 227impl<'a, Q: Querier> TreeSink for TtTreeSink<'a, Q> {
228 fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { 228 fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
229 if kind == L_DOLLAR || kind == R_DOLLAR { 229 if kind == L_DOLLAR || kind == R_DOLLAR {
@@ -240,14 +240,18 @@ impl<'a, Q: Querier> TreeSink for TtTreeSink<'a, Q> {
240 self.buf.clear(); 240 self.buf.clear();
241 self.inner.token(kind, text); 241 self.inner.token(kind, text);
242 242
243 // // Add a white space to token 243 // Add a white space between tokens, only if both are not delimiters
244 // let (last_kind, _, last_joint_to_next ) = self.src_querier.token(self.token_pos-n_tokens as usize); 244 if !is_delimiter(kind) {
245 // if !last_joint_to_next && last_kind.is_punct() { 245 let (last_kind, _, last_joint_to_next) = self.src_querier.token(self.token_pos - 1);
246 // let (cur_kind, _, _ ) = self.src_querier.token(self.token_pos); 246 if !last_joint_to_next && last_kind.is_punct() {
247 // if cur_kind.is_punct() { 247 let (cur_kind, _, _) = self.src_querier.token(self.token_pos);
248 // self.inner.token(WHITESPACE, " ".into()); 248 if !is_delimiter(cur_kind) {
249 // } 249 if cur_kind.is_punct() {
250 // } 250 self.inner.token(WHITESPACE, " ".into());
251 }
252 }
253 }
254 }
251 } 255 }
252 256
253 fn start_node(&mut self, kind: SyntaxKind) { 257 fn start_node(&mut self, kind: SyntaxKind) {
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index eef642a9c..53bc305be 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -1,6 +1,5 @@
1use crate::ParseError; 1use crate::ParseError;
2use crate::subtree_parser::Parser; 2use crate::subtree_parser::Parser;
3use crate::subtree_source::TokenPeek;
4use smallvec::{SmallVec, smallvec}; 3use smallvec::{SmallVec, smallvec};
5 4
6#[derive(Debug, Clone)] 5#[derive(Debug, Clone)]
@@ -153,7 +152,7 @@ impl<'a> TtCursor<'a> {
153 pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { 152 pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
154 let parser = Parser::new(&mut self.pos, self.subtree); 153 let parser = Parser::new(&mut self.pos, self.subtree);
155 parser.parse_vis() 154 parser.parse_vis()
156 } 155 }
157 156
158 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { 157 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> {
159 if self.at_char(char) { 158 if self.at_char(char) {
@@ -262,3 +261,48 @@ impl<'a> TtCursor<'a> {
262 self.pos = memento.pos; 261 self.pos = memento.pos;
263 } 262 }
264} 263}
264
265pub(crate) struct TokenPeek<'a, I>
266where
267 I: Iterator<Item = &'a tt::TokenTree>,
268{
269 iter: itertools::MultiPeek<I>,
270}
271
272// helper function
273fn to_punct(tt: &tt::TokenTree) -> Option<&tt::Punct> {
274 if let tt::TokenTree::Leaf(tt::Leaf::Punct(pp)) = tt {
275 return Some(pp);
276 }
277 None
278}
279
280impl<'a, I> TokenPeek<'a, I>
281where
282 I: Iterator<Item = &'a tt::TokenTree>,
283{
284 pub fn new(iter: I) -> Self {
285 TokenPeek { iter: itertools::multipeek(iter) }
286 }
287
288 pub fn current_punct2(&mut self, p: &tt::Punct) -> Option<((char, char), bool)> {
289 if p.spacing != tt::Spacing::Joint {
290 return None;
291 }
292
293 self.iter.reset_peek();
294 let p1 = to_punct(self.iter.peek()?)?;
295 Some(((p.char, p1.char), p1.spacing == tt::Spacing::Joint))
296 }
297
298 pub fn current_punct3(&mut self, p: &tt::Punct) -> Option<((char, char, char), bool)> {
299 self.current_punct2(p).and_then(|((p0, p1), last_joint)| {
300 if !last_joint {
301 None
302 } else {
303 let p2 = to_punct(*self.iter.peek()?)?;
304 Some(((p0, p1, p2.char), p2.spacing == tt::Spacing::Joint))
305 }
306 })
307 }
308}