mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Don't allocate when traversing children
This commit is contained in:
parent
27a40e0a88
commit
70b3372921
5 changed files with 66 additions and 12 deletions
|
@ -11,8 +11,8 @@ impl TreeRoot for Arc<SyntaxRoot> {}
|
||||||
impl<'a> TreeRoot for &'a SyntaxRoot {}
|
impl<'a> TreeRoot for &'a SyntaxRoot {}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct SyntaxNode<ROOT: TreeRoot = Arc<SyntaxRoot>> {
|
pub struct SyntaxNode<R: TreeRoot = Arc<SyntaxRoot>> {
|
||||||
pub(crate) root: ROOT,
|
pub(crate) root: R,
|
||||||
// Guaranteed to not dangle, because `root` holds a
|
// Guaranteed to not dangle, because `root` holds a
|
||||||
// strong reference to red's ancestor
|
// strong reference to red's ancestor
|
||||||
red: ptr::NonNull<RedNode>,
|
red: ptr::NonNull<RedNode>,
|
||||||
|
@ -52,7 +52,7 @@ impl SyntaxNode<Arc<SyntaxRoot>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
|
impl<R: TreeRoot> SyntaxNode<R> {
|
||||||
pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> {
|
pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> {
|
||||||
SyntaxNode {
|
SyntaxNode {
|
||||||
root: &*self.root,
|
root: &*self.root,
|
||||||
|
@ -73,20 +73,18 @@ impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
|
||||||
self.red().green().text()
|
self.red().green().text()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn children(&self) -> Vec<SyntaxNode<ROOT>> {
|
pub fn children<'a>(&'a self) -> impl Iterator<Item=SyntaxNode<R>> + 'a {
|
||||||
let red = self.red();
|
let red = self.red();
|
||||||
let n_children = red.n_children();
|
let n_children = red.n_children();
|
||||||
let mut res = Vec::with_capacity(n_children);
|
(0..n_children).map(move |i| {
|
||||||
for i in 0..n_children {
|
SyntaxNode {
|
||||||
res.push(SyntaxNode {
|
|
||||||
root: self.root.clone(),
|
root: self.root.clone(),
|
||||||
red: red.nth_child(i),
|
red: red.nth_child(i),
|
||||||
});
|
}
|
||||||
}
|
})
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parent(&self) -> Option<SyntaxNode<ROOT>> {
|
pub fn parent(&self) -> Option<SyntaxNode<R>> {
|
||||||
let parent = self.red().parent()?;
|
let parent = self.red().parent()?;
|
||||||
Some(SyntaxNode {
|
Some(SyntaxNode {
|
||||||
root: self.root.clone(),
|
root: self.root.clone(),
|
||||||
|
@ -99,7 +97,7 @@ impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ROOT: TreeRoot> fmt::Debug for SyntaxNode<ROOT> {
|
impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
|
write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
|
||||||
if has_short_text(self.kind()) {
|
if has_short_text(self.kind()) {
|
||||||
|
|
1
tests/data/parser/inline/0041_type_param_bounds.rs
Normal file
1
tests/data/parser/inline/0041_type_param_bounds.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
struct S<T: 'a + ?Sized + (Copy)>;
|
33
tests/data/parser/inline/0041_type_param_bounds.txt
Normal file
33
tests/data/parser/inline/0041_type_param_bounds.txt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
FILE@[0; 35)
|
||||||
|
STRUCT_ITEM@[0; 35)
|
||||||
|
STRUCT_KW@[0; 6)
|
||||||
|
NAME@[6; 8)
|
||||||
|
WHITESPACE@[6; 7)
|
||||||
|
IDENT@[7; 8) "S"
|
||||||
|
TYPE_PARAM_LIST@[8; 33)
|
||||||
|
L_ANGLE@[8; 9)
|
||||||
|
TYPE_PARAM@[9; 32)
|
||||||
|
IDENT@[9; 10) "T"
|
||||||
|
COLON@[10; 11)
|
||||||
|
WHITESPACE@[11; 12)
|
||||||
|
LIFETIME@[12; 14) "'a"
|
||||||
|
WHITESPACE@[14; 15)
|
||||||
|
PLUS@[15; 16)
|
||||||
|
WHITESPACE@[16; 17)
|
||||||
|
QUESTION@[17; 18)
|
||||||
|
PATH@[18; 24)
|
||||||
|
PATH_SEGMENT@[18; 24)
|
||||||
|
NAME_REF@[18; 24)
|
||||||
|
IDENT@[18; 23) "Sized"
|
||||||
|
WHITESPACE@[23; 24)
|
||||||
|
PLUS@[24; 25)
|
||||||
|
WHITESPACE@[25; 26)
|
||||||
|
L_PAREN@[26; 27)
|
||||||
|
PATH@[27; 31)
|
||||||
|
PATH_SEGMENT@[27; 31)
|
||||||
|
NAME_REF@[27; 31)
|
||||||
|
IDENT@[27; 31) "Copy"
|
||||||
|
R_PAREN@[31; 32)
|
||||||
|
R_ANGLE@[32; 33)
|
||||||
|
SEMI@[33; 34)
|
||||||
|
WHITESPACE@[34; 35)
|
1
tests/data/parser/inline/0042_type_param_default.rs
Normal file
1
tests/data/parser/inline/0042_type_param_default.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
struct S<T = i32>;
|
21
tests/data/parser/inline/0042_type_param_default.txt
Normal file
21
tests/data/parser/inline/0042_type_param_default.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FILE@[0; 19)
|
||||||
|
STRUCT_ITEM@[0; 19)
|
||||||
|
STRUCT_KW@[0; 6)
|
||||||
|
NAME@[6; 8)
|
||||||
|
WHITESPACE@[6; 7)
|
||||||
|
IDENT@[7; 8) "S"
|
||||||
|
TYPE_PARAM_LIST@[8; 17)
|
||||||
|
L_ANGLE@[8; 9)
|
||||||
|
TYPE_PARAM@[9; 16)
|
||||||
|
IDENT@[9; 10) "T"
|
||||||
|
WHITESPACE@[10; 11)
|
||||||
|
EQ@[11; 12)
|
||||||
|
PATH_TYPE@[12; 16)
|
||||||
|
PATH@[12; 16)
|
||||||
|
PATH_SEGMENT@[12; 16)
|
||||||
|
NAME_REF@[12; 16)
|
||||||
|
WHITESPACE@[12; 13)
|
||||||
|
IDENT@[13; 16) "i32"
|
||||||
|
R_ANGLE@[16; 17)
|
||||||
|
SEMI@[17; 18)
|
||||||
|
WHITESPACE@[18; 19)
|
Loading…
Reference in a new issue