Store referece in tokenbuffer

This commit is contained in:
Edwin Cheng 2019-06-03 00:54:33 +08:00
parent ccec71165b
commit 54ea251bd4
3 changed files with 28 additions and 26 deletions

View file

@ -10,7 +10,7 @@ struct OffsetTokenSink<'a> {
} }
impl<'a> OffsetTokenSink<'a> { impl<'a> OffsetTokenSink<'a> {
pub fn collect(&self, begin: Cursor<'a>) -> Vec<tt::TokenTree> { pub fn collect(&self, begin: Cursor<'a>) -> Vec<&'a tt::TokenTree> {
if !self.cursor.is_root() { if !self.cursor.is_root() {
return vec![]; return vec![];
} }
@ -114,7 +114,7 @@ impl<'a> Parser<'a> {
1 => Some(res[0].clone()), 1 => Some(res[0].clone()),
_ => Some(tt::TokenTree::Subtree(tt::Subtree { _ => Some(tt::TokenTree::Subtree(tt::Subtree {
delimiter: tt::Delimiter::None, delimiter: tt::Delimiter::None,
token_trees: res, token_trees: res.into_iter().cloned().collect(),
})), })),
} }
} }

View file

@ -49,7 +49,8 @@ fn token_tree_to_syntax_node<F>(tt: &tt::Subtree, f: F) -> Result<TreeArc<Syntax
where where
F: Fn(&mut ra_parser::TokenSource, &mut ra_parser::TreeSink), F: Fn(&mut ra_parser::TokenSource, &mut ra_parser::TreeSink),
{ {
let buffer = TokenBuffer::new(&[tt.clone().into()]); let tokens = [tt.clone().into()];
let buffer = TokenBuffer::new(&tokens);
let mut token_source = SubtreeTokenSource::new(&buffer); let mut token_source = SubtreeTokenSource::new(&buffer);
let mut tree_sink = TtTreeSink::new(buffer.begin()); let mut tree_sink = TtTreeSink::new(buffer.begin());
f(&mut token_source, &mut tree_sink); f(&mut token_source, &mut tree_sink);
@ -385,7 +386,8 @@ mod tests {
"#, "#,
); );
let expansion = expand(&rules, "literals!(foo);"); let expansion = expand(&rules, "literals!(foo);");
let buffer = tt::buffer::TokenBuffer::new(&[expansion.clone().into()]); let tts = &[expansion.clone().into()];
let buffer = tt::buffer::TokenBuffer::new(tts);
let mut tt_src = SubtreeTokenSource::new(&buffer); let mut tt_src = SubtreeTokenSource::new(&buffer);
let mut tokens = vec![]; let mut tokens = vec![];
while tt_src.current().kind != EOF { while tt_src.current().kind != EOF {

View file

@ -1,4 +1,4 @@
use crate::{TokenTree, Subtree, Leaf}; use crate::{TokenTree, Subtree};
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
struct EntryId(usize); struct EntryId(usize);
@ -9,10 +9,10 @@ struct EntryPtr(EntryId, usize);
/// Internal type which is used instead of `TokenTree` to represent a token tree /// Internal type which is used instead of `TokenTree` to represent a token tree
/// within a `TokenBuffer`. /// within a `TokenBuffer`.
#[derive(Debug)] #[derive(Debug)]
enum Entry { enum Entry<'t> {
// Mimicking types from proc-macro. // Mimicking types from proc-macro.
Subtree(Subtree, EntryId), Subtree(&'t TokenTree, EntryId),
Leaf(Leaf), Leaf(&'t TokenTree),
// End entries contain a pointer to the entry from the containing // End entries contain a pointer to the entry from the containing
// token tree, or None if this is the outermost level. // token tree, or None if this is the outermost level.
End(Option<EntryPtr>), End(Option<EntryPtr>),
@ -21,12 +21,12 @@ enum Entry {
/// A token tree buffer /// A token tree buffer
/// The safe version of `syn` [`TokenBuffer`](https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L41) /// The safe version of `syn` [`TokenBuffer`](https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L41)
#[derive(Debug)] #[derive(Debug)]
pub struct TokenBuffer { pub struct TokenBuffer<'t> {
buffers: Vec<Box<[Entry]>>, buffers: Vec<Box<[Entry<'t>]>>,
} }
impl TokenBuffer { impl<'t> TokenBuffer<'t> {
pub fn new(tokens: &[TokenTree]) -> TokenBuffer { pub fn new(tokens: &'t [TokenTree]) -> TokenBuffer<'t> {
let mut buffers = vec![]; let mut buffers = vec![];
let idx = TokenBuffer::new_inner(tokens, &mut buffers, None); let idx = TokenBuffer::new_inner(tokens, &mut buffers, None);
@ -36,21 +36,21 @@ impl TokenBuffer {
} }
fn new_inner( fn new_inner(
tokens: &[TokenTree], tokens: &'t [TokenTree],
buffers: &mut Vec<Box<[Entry]>>, buffers: &mut Vec<Box<[Entry<'t>]>>,
next: Option<EntryPtr>, next: Option<EntryPtr>,
) -> usize { ) -> usize {
let mut entries = vec![]; let mut entries = vec![];
let mut children = vec![]; let mut children = vec![];
for (idx, tt) in tokens.iter().cloned().enumerate() { for (idx, tt) in tokens.iter().enumerate() {
match tt { match tt {
TokenTree::Leaf(leaf) => { TokenTree::Leaf(_) => {
entries.push(Entry::Leaf(leaf)); entries.push(Entry::Leaf(tt));
} }
TokenTree::Subtree(subtree) => { TokenTree::Subtree(subtree) => {
entries.push(Entry::End(None)); entries.push(Entry::End(None));
children.push((idx, subtree)); children.push((idx, (subtree, tt)));
} }
} }
} }
@ -59,13 +59,13 @@ impl TokenBuffer {
let res = buffers.len(); let res = buffers.len();
buffers.push(entries.into_boxed_slice()); buffers.push(entries.into_boxed_slice());
for (child_idx, subtree) in children { for (child_idx, (subtree, tt)) in children {
let idx = TokenBuffer::new_inner( let idx = TokenBuffer::new_inner(
&subtree.token_trees, &subtree.token_trees,
buffers, buffers,
Some(EntryPtr(EntryId(res), child_idx + 1)), Some(EntryPtr(EntryId(res), child_idx + 1)),
); );
buffers[res].as_mut()[child_idx] = Entry::Subtree(subtree, EntryId(idx)); buffers[res].as_mut()[child_idx] = Entry::Subtree(tt, EntryId(idx));
} }
res res
@ -86,7 +86,7 @@ impl TokenBuffer {
/// A safe version of `Cursor` from `syn` crate https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L125 /// A safe version of `Cursor` from `syn` crate https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L125
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct Cursor<'a> { pub struct Cursor<'a> {
buffer: &'a TokenBuffer, buffer: &'a TokenBuffer<'a>,
ptr: EntryPtr, ptr: EntryPtr,
} }
@ -113,7 +113,7 @@ impl<'a> Cursor<'a> {
match self.entry() { match self.entry() {
Some(Entry::End(Some(ptr))) => { Some(Entry::End(Some(ptr))) => {
let idx = ptr.1; let idx = ptr.1;
if let Some(Entry::Subtree(subtree, _)) = if let Some(Entry::Subtree(TokenTree::Subtree(subtree), _)) =
self.buffer.entry(&EntryPtr(ptr.0, idx - 1)) self.buffer.entry(&EntryPtr(ptr.0, idx - 1))
{ {
return Some(subtree); return Some(subtree);
@ -125,7 +125,7 @@ impl<'a> Cursor<'a> {
} }
} }
fn entry(self) -> Option<(&'a Entry)> { fn entry(self) -> Option<(&'a Entry<'a>)> {
self.buffer.entry(&self.ptr) self.buffer.entry(&self.ptr)
} }
@ -141,10 +141,10 @@ impl<'a> Cursor<'a> {
} }
/// If the cursor is pointing at a `TokenTree`, returns it /// If the cursor is pointing at a `TokenTree`, returns it
pub fn token_tree(self) -> Option<(TokenTree)> { pub fn token_tree(self) -> Option<(&'a TokenTree)> {
match self.entry() { match self.entry() {
Some(Entry::Leaf(leaf)) => Some(leaf.clone().into()), Some(Entry::Leaf(tt)) => Some(tt),
Some(Entry::Subtree(subtree, _)) => Some(subtree.clone().into()), Some(Entry::Subtree(tt, _)) => Some(tt),
Some(Entry::End(_)) => None, Some(Entry::End(_)) => None,
None => None, None => None,
} }