diff options
author | Aleksey Kladov <[email protected]> | 2019-02-23 14:21:56 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-02-23 14:21:56 +0000 |
commit | 8eac450f41c6d94215f5d8c02235cd5917abaa69 (patch) | |
tree | 93b6145789f64d2c2c7f2a607c23ed64ced92dc1 /crates/ra_mbe | |
parent | 83d6be6cecb19659e289eba63f12ac33dceb3b56 (diff) |
implement tt -> ast
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r-- | crates/ra_mbe/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 58 |
2 files changed, 55 insertions, 5 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index cdca3cafb..768f335fa 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs | |||
@@ -24,7 +24,7 @@ use ra_syntax::SmolStr; | |||
24 | 24 | ||
25 | pub use tt::{Delimiter, Punct}; | 25 | pub use tt::{Delimiter, Punct}; |
26 | 26 | ||
27 | pub use crate::syntax_bridge::ast_to_token_tree; | 27 | pub use crate::syntax_bridge::{ast_to_token_tree, token_tree_to_ast_item_list}; |
28 | 28 | ||
29 | /// This struct contains AST for a single `macro_rules` definition. What might | 29 | /// This struct contains AST for a single `macro_rules` definition. What might |
30 | /// be very confusing is that AST has almost exactly the same shape as | 30 | /// be very confusing is that AST has almost exactly the same shape as |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 24a043175..521b96d68 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_parser::TokenSource; | 1 | use ra_parser::{TokenSource, TreeSink, ParseError}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr, | 3 | AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr, SyntaxTreeBuilder, TreeArc, |
4 | ast, SyntaxKind::*, TextUnit | 4 | ast, SyntaxKind::*, TextUnit |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -21,8 +21,12 @@ pub fn ast_to_token_tree(ast: &ast::TokenTree) -> Option<(tt::Subtree, TokenMap) | |||
21 | } | 21 | } |
22 | 22 | ||
23 | /// Parses the token tree (result of macro expansion) as a sequence of items | 23 | /// Parses the token tree (result of macro expansion) as a sequence of items |
24 | pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> ast::SourceFile { | 24 | pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> TreeArc<ast::SourceFile> { |
25 | unimplemented!() | 25 | let token_source = TtTokenSource::new(tt); |
26 | let mut tree_sink = TtTreeSink::new(&token_source.tokens); | ||
27 | ra_parser::parse(&token_source, &mut tree_sink); | ||
28 | let syntax = tree_sink.inner.finish(); | ||
29 | ast::SourceFile::cast(&syntax).unwrap().to_owned() | ||
26 | } | 30 | } |
27 | 31 | ||
28 | impl TokenMap { | 32 | impl TokenMap { |
@@ -166,3 +170,49 @@ impl TokenSource for TtTokenSource { | |||
166 | self.tokens[pos].text == *kw | 170 | self.tokens[pos].text == *kw |
167 | } | 171 | } |
168 | } | 172 | } |
173 | |||
174 | #[derive(Default)] | ||
175 | struct TtTreeSink<'a> { | ||
176 | buf: String, | ||
177 | tokens: &'a [Tok], | ||
178 | text_pos: TextUnit, | ||
179 | token_pos: usize, | ||
180 | inner: SyntaxTreeBuilder, | ||
181 | } | ||
182 | |||
183 | impl<'a> TtTreeSink<'a> { | ||
184 | fn new(tokens: &'a [Tok]) -> TtTreeSink { | ||
185 | TtTreeSink { | ||
186 | buf: String::new(), | ||
187 | tokens, | ||
188 | text_pos: 0.into(), | ||
189 | token_pos: 0, | ||
190 | inner: SyntaxTreeBuilder::default(), | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | impl<'a> TreeSink for TtTreeSink<'a> { | ||
196 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { | ||
197 | for _ in 0..n_tokens { | ||
198 | self.buf += self.tokens[self.token_pos].text.as_str(); | ||
199 | self.token_pos += 1; | ||
200 | } | ||
201 | self.text_pos += TextUnit::of_str(&self.buf); | ||
202 | let text = SmolStr::new(self.buf.as_str()); | ||
203 | self.buf.clear(); | ||
204 | self.inner.leaf(kind, text) | ||
205 | } | ||
206 | |||
207 | fn start_branch(&mut self, kind: SyntaxKind) { | ||
208 | self.inner.start_branch(kind); | ||
209 | } | ||
210 | |||
211 | fn finish_branch(&mut self) { | ||
212 | self.inner.finish_branch(); | ||
213 | } | ||
214 | |||
215 | fn error(&mut self, error: ParseError) { | ||
216 | self.inner.error(error, self.text_pos) | ||
217 | } | ||
218 | } | ||