aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/syntax_bridge.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/syntax_bridge.rs')
-rw-r--r--crates/mbe/src/syntax_bridge.rs39
1 files changed, 38 insertions, 1 deletions
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index 0cdc175be..5a91781fc 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -10,8 +10,8 @@ use syntax::{
10}; 10};
11use tt::buffer::{Cursor, TokenBuffer}; 11use tt::buffer::{Cursor, TokenBuffer};
12 12
13use crate::subtree_source::SubtreeTokenSource;
14use crate::ExpandError; 13use crate::ExpandError;
14use crate::{subtree_source::SubtreeTokenSource, tt_iter::TtIter};
15 15
16#[derive(Debug, PartialEq, Eq, Clone, Copy)] 16#[derive(Debug, PartialEq, Eq, Clone, Copy)]
17pub enum TokenTextRange { 17pub enum TokenTextRange {
@@ -112,6 +112,43 @@ pub fn parse_to_token_tree(text: &str) -> Option<(tt::Subtree, TokenMap)> {
112 Some((subtree, conv.id_alloc.map)) 112 Some((subtree, conv.id_alloc.map))
113} 113}
114 114
115/// Split token tree with seperate expr: $($e:expr)SEP*
116pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char) -> Vec<tt::Subtree> {
117 if tt.token_trees.is_empty() {
118 return Vec::new();
119 }
120
121 let mut iter = TtIter::new(tt);
122 let mut res = Vec::new();
123
124 while iter.peek_n(0).is_some() {
125 let expanded = iter.expect_fragment(FragmentKind::Expr);
126 if expanded.err.is_some() {
127 break;
128 }
129
130 res.push(match expanded.value {
131 None => break,
132 Some(tt @ tt::TokenTree::Leaf(_)) => {
133 tt::Subtree { delimiter: None, token_trees: vec![tt.into()] }
134 }
135 Some(tt::TokenTree::Subtree(tt)) => tt,
136 });
137
138 let mut fork = iter.clone();
139 if fork.expect_char(sep).is_err() {
140 break;
141 }
142 iter = fork;
143 }
144
145 if iter.peek_n(0).is_some() {
146 res.push(tt::Subtree { delimiter: None, token_trees: iter.into_iter().cloned().collect() });
147 }
148
149 res
150}
151
115impl TokenMap { 152impl TokenMap {
116 pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> { 153 pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> {
117 let &(token_id, _) = self.entries.iter().find(|(_, range)| match range { 154 let &(token_id, _) = self.entries.iter().find(|(_, range)| match range {