mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Store referece in tokenbuffer
This commit is contained in:
parent
ccec71165b
commit
54ea251bd4
3 changed files with 28 additions and 26 deletions
|
@ -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(),
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue