mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 18:12:51 +00:00
implement tt -> ast
This commit is contained in:
parent
83d6be6cec
commit
8eac450f41
@ -24,7 +24,7 @@ use ra_syntax::SmolStr;
|
||||
|
||||
pub use tt::{Delimiter, Punct};
|
||||
|
||||
pub use crate::syntax_bridge::ast_to_token_tree;
|
||||
pub use crate::syntax_bridge::{ast_to_token_tree, token_tree_to_ast_item_list};
|
||||
|
||||
/// This struct contains AST for a single `macro_rules` definition. What might
|
||||
/// be very confusing is that AST has almost exactly the same shape as
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_parser::TokenSource;
|
||||
use ra_parser::{TokenSource, TreeSink, ParseError};
|
||||
use ra_syntax::{
|
||||
AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr,
|
||||
AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr, SyntaxTreeBuilder, TreeArc,
|
||||
ast, SyntaxKind::*, TextUnit
|
||||
};
|
||||
|
||||
@ -21,8 +21,12 @@ pub fn ast_to_token_tree(ast: &ast::TokenTree) -> Option<(tt::Subtree, TokenMap)
|
||||
}
|
||||
|
||||
/// Parses the token tree (result of macro expansion) as a sequence of items
|
||||
pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> ast::SourceFile {
|
||||
unimplemented!()
|
||||
pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> TreeArc<ast::SourceFile> {
|
||||
let token_source = TtTokenSource::new(tt);
|
||||
let mut tree_sink = TtTreeSink::new(&token_source.tokens);
|
||||
ra_parser::parse(&token_source, &mut tree_sink);
|
||||
let syntax = tree_sink.inner.finish();
|
||||
ast::SourceFile::cast(&syntax).unwrap().to_owned()
|
||||
}
|
||||
|
||||
impl TokenMap {
|
||||
@ -166,3 +170,49 @@ impl TokenSource for TtTokenSource {
|
||||
self.tokens[pos].text == *kw
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TtTreeSink<'a> {
|
||||
buf: String,
|
||||
tokens: &'a [Tok],
|
||||
text_pos: TextUnit,
|
||||
token_pos: usize,
|
||||
inner: SyntaxTreeBuilder,
|
||||
}
|
||||
|
||||
impl<'a> TtTreeSink<'a> {
|
||||
fn new(tokens: &'a [Tok]) -> TtTreeSink {
|
||||
TtTreeSink {
|
||||
buf: String::new(),
|
||||
tokens,
|
||||
text_pos: 0.into(),
|
||||
token_pos: 0,
|
||||
inner: SyntaxTreeBuilder::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TreeSink for TtTreeSink<'a> {
|
||||
fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) {
|
||||
for _ in 0..n_tokens {
|
||||
self.buf += self.tokens[self.token_pos].text.as_str();
|
||||
self.token_pos += 1;
|
||||
}
|
||||
self.text_pos += TextUnit::of_str(&self.buf);
|
||||
let text = SmolStr::new(self.buf.as_str());
|
||||
self.buf.clear();
|
||||
self.inner.leaf(kind, text)
|
||||
}
|
||||
|
||||
fn start_branch(&mut self, kind: SyntaxKind) {
|
||||
self.inner.start_branch(kind);
|
||||
}
|
||||
|
||||
fn finish_branch(&mut self) {
|
||||
self.inner.finish_branch();
|
||||
}
|
||||
|
||||
fn error(&mut self, error: ParseError) {
|
||||
self.inner.error(error, self.text_pos)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user