From 70b337292117a9bb90e85056dcb4069f8bbc6c0a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Jul 2018 23:20:02 +0300 Subject: Don't allocate when traversing children --- src/yellow/syntax.rs | 22 +++++++-------- tests/data/parser/inline/0041_type_param_bounds.rs | 1 + .../data/parser/inline/0041_type_param_bounds.txt | 33 ++++++++++++++++++++++ .../data/parser/inline/0042_type_param_default.rs | 1 + .../data/parser/inline/0042_type_param_default.txt | 21 ++++++++++++++ 5 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 tests/data/parser/inline/0041_type_param_bounds.rs create mode 100644 tests/data/parser/inline/0041_type_param_bounds.txt create mode 100644 tests/data/parser/inline/0042_type_param_default.rs create mode 100644 tests/data/parser/inline/0042_type_param_default.txt diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs index 19a9b8ac2..5c31a3f35 100644 --- a/src/yellow/syntax.rs +++ b/src/yellow/syntax.rs @@ -11,8 +11,8 @@ impl TreeRoot for Arc {} impl<'a> TreeRoot for &'a SyntaxRoot {} #[derive(Clone, Copy)] -pub struct SyntaxNode> { - pub(crate) root: ROOT, +pub struct SyntaxNode> { + pub(crate) root: R, // Guaranteed to not dangle, because `root` holds a // strong reference to red's ancestor red: ptr::NonNull, @@ -52,7 +52,7 @@ impl SyntaxNode> { } } -impl SyntaxNode { +impl SyntaxNode { pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> { SyntaxNode { root: &*self.root, @@ -73,20 +73,18 @@ impl SyntaxNode { self.red().green().text() } - pub fn children(&self) -> Vec> { + pub fn children<'a>(&'a self) -> impl Iterator> + 'a { let red = self.red(); let n_children = red.n_children(); - let mut res = Vec::with_capacity(n_children); - for i in 0..n_children { - res.push(SyntaxNode { + (0..n_children).map(move |i| { + SyntaxNode { root: self.root.clone(), red: red.nth_child(i), - }); - } - res + } + }) } - pub fn parent(&self) -> Option> { + pub fn parent(&self) -> Option> { let parent = self.red().parent()?; Some(SyntaxNode { root: self.root.clone(), @@ -99,7 +97,7 @@ impl SyntaxNode { } } -impl fmt::Debug for SyntaxNode { +impl fmt::Debug for SyntaxNode { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; if has_short_text(self.kind()) { diff --git a/tests/data/parser/inline/0041_type_param_bounds.rs b/tests/data/parser/inline/0041_type_param_bounds.rs new file mode 100644 index 000000000..919bde0ee --- /dev/null +++ b/tests/data/parser/inline/0041_type_param_bounds.rs @@ -0,0 +1 @@ +struct S; diff --git a/tests/data/parser/inline/0041_type_param_bounds.txt b/tests/data/parser/inline/0041_type_param_bounds.txt new file mode 100644 index 000000000..d607bd416 --- /dev/null +++ b/tests/data/parser/inline/0041_type_param_bounds.txt @@ -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) diff --git a/tests/data/parser/inline/0042_type_param_default.rs b/tests/data/parser/inline/0042_type_param_default.rs new file mode 100644 index 000000000..540eacb02 --- /dev/null +++ b/tests/data/parser/inline/0042_type_param_default.rs @@ -0,0 +1 @@ +struct S; diff --git a/tests/data/parser/inline/0042_type_param_default.txt b/tests/data/parser/inline/0042_type_param_default.txt new file mode 100644 index 000000000..9642a9084 --- /dev/null +++ b/tests/data/parser/inline/0042_type_param_default.txt @@ -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) -- cgit v1.2.3