aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/subtree_parser.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-17 13:53:01 +0100
committerGitHub <[email protected]>2019-09-17 13:53:01 +0100
commit9421d2a953516b392ae35446bc4f2206dd993c84 (patch)
treee6c7b46cabe1f10f7da28f3db209df2260045fa8 /crates/ra_mbe/src/subtree_parser.rs
parent8eb2697b7d2a98c952b3acd1711829a13e13cab1 (diff)
parent4551182f94fe81c314f79ddf8916a5520cfd03b0 (diff)
Merge #1858
1858: use usual token tree for macro expansions r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src/subtree_parser.rs')
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs91
1 files changed, 0 insertions, 91 deletions
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
deleted file mode 100644
index 4440c69ff..000000000
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ /dev/null
@@ -1,91 +0,0 @@
1use crate::subtree_source::SubtreeTokenSource;
2
3use ra_parser::{FragmentKind, TokenSource, TreeSink};
4use ra_syntax::SyntaxKind;
5use tt::buffer::{Cursor, TokenBuffer};
6
7struct OffsetTokenSink<'a> {
8 cursor: Cursor<'a>,
9 error: bool,
10}
11
12impl<'a> OffsetTokenSink<'a> {
13 pub fn collect(&self, begin: Cursor<'a>) -> Vec<&'a 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> {
33 fn token(&mut self, _kind: SyntaxKind, n_tokens: u8) {
34 for _ in 0..n_tokens {
35 self.cursor = self.cursor.bump_subtree();
36 }
37 }
38 fn start_node(&mut self, _kind: SyntaxKind) {}
39 fn finish_node(&mut self) {}
40 fn error(&mut self, _error: ra_parser::ParseError) {
41 self.error = true;
42 }
43}
44
45pub(crate) struct Parser<'a> {
46 subtree: &'a tt::Subtree,
47 cur_pos: &'a mut usize,
48}
49
50impl<'a> Parser<'a> {
51 pub fn new(cur_pos: &'a mut usize, subtree: &'a tt::Subtree) -> Parser<'a> {
52 Parser { cur_pos, subtree }
53 }
54
55 pub fn parse_fragment(self, fragment_kind: FragmentKind) -> Option<tt::TokenTree> {
56 self.parse(|token_source, tree_skink| {
57 ra_parser::parse_fragment(token_source, tree_skink, fragment_kind)
58 })
59 }
60
61 fn parse<F>(self, f: F) -> Option<tt::TokenTree>
62 where
63 F: FnOnce(&mut dyn TokenSource, &mut dyn TreeSink),
64 {
65 let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]);
66 let mut src = SubtreeTokenSource::new(&buffer);
67 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false };
68
69 f(&mut src, &mut sink);
70
71 let r = self.finish(buffer.begin(), &mut sink);
72 if sink.error {
73 return None;
74 }
75 r
76 }
77
78 fn finish(self, begin: Cursor, sink: &mut OffsetTokenSink) -> Option<tt::TokenTree> {
79 let res = sink.collect(begin);
80 *self.cur_pos += res.len();
81
82 match res.len() {
83 0 => None,
84 1 => Some(res[0].clone()),
85 _ => Some(tt::TokenTree::Subtree(tt::Subtree {
86 delimiter: tt::Delimiter::None,
87 token_trees: res.into_iter().cloned().collect(),
88 })),
89 }
90 }
91}