aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-30 21:20:02 +0100
committerAleksey Kladov <[email protected]>2018-07-30 21:20:02 +0100
commit70b337292117a9bb90e85056dcb4069f8bbc6c0a (patch)
tree4a5f28a2f14d53e5a07b1735ec60931093fd7280
parent27a40e0a8844310960f12294fe7cd1f5b6d25fcb (diff)
Don't allocate when traversing children
-rw-r--r--src/yellow/syntax.rs22
-rw-r--r--tests/data/parser/inline/0041_type_param_bounds.rs1
-rw-r--r--tests/data/parser/inline/0041_type_param_bounds.txt33
-rw-r--r--tests/data/parser/inline/0042_type_param_default.rs1
-rw-r--r--tests/data/parser/inline/0042_type_param_default.txt21
5 files changed, 66 insertions, 12 deletions
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<SyntaxRoot> {}
11impl<'a> TreeRoot for &'a SyntaxRoot {} 11impl<'a> TreeRoot for &'a SyntaxRoot {}
12 12
13#[derive(Clone, Copy)] 13#[derive(Clone, Copy)]
14pub struct SyntaxNode<ROOT: TreeRoot = Arc<SyntaxRoot>> { 14pub struct SyntaxNode<R: TreeRoot = Arc<SyntaxRoot>> {
15 pub(crate) root: ROOT, 15 pub(crate) root: R,
16 // Guaranteed to not dangle, because `root` holds a 16 // Guaranteed to not dangle, because `root` holds a
17 // strong reference to red's ancestor 17 // strong reference to red's ancestor
18 red: ptr::NonNull<RedNode>, 18 red: ptr::NonNull<RedNode>,
@@ -52,7 +52,7 @@ impl SyntaxNode<Arc<SyntaxRoot>> {
52 } 52 }
53} 53}
54 54
55impl<ROOT: TreeRoot> SyntaxNode<ROOT> { 55impl<R: TreeRoot> SyntaxNode<R> {
56 pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> { 56 pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> {
57 SyntaxNode { 57 SyntaxNode {
58 root: &*self.root, 58 root: &*self.root,
@@ -73,20 +73,18 @@ impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
73 self.red().green().text() 73 self.red().green().text()
74 } 74 }
75 75
76 pub fn children(&self) -> Vec<SyntaxNode<ROOT>> { 76 pub fn children<'a>(&'a self) -> impl Iterator<Item=SyntaxNode<R>> + 'a {
77 let red = self.red(); 77 let red = self.red();
78 let n_children = red.n_children(); 78 let n_children = red.n_children();
79 let mut res = Vec::with_capacity(n_children); 79 (0..n_children).map(move |i| {
80 for i in 0..n_children { 80 SyntaxNode {
81 res.push(SyntaxNode {
82 root: self.root.clone(), 81 root: self.root.clone(),
83 red: red.nth_child(i), 82 red: red.nth_child(i),
84 }); 83 }
85 } 84 })
86 res
87 } 85 }
88 86
89 pub fn parent(&self) -> Option<SyntaxNode<ROOT>> { 87 pub fn parent(&self) -> Option<SyntaxNode<R>> {
90 let parent = self.red().parent()?; 88 let parent = self.red().parent()?;
91 Some(SyntaxNode { 89 Some(SyntaxNode {
92 root: self.root.clone(), 90 root: self.root.clone(),
@@ -99,7 +97,7 @@ impl<ROOT: TreeRoot> SyntaxNode<ROOT> {
99 } 97 }
100} 98}
101 99
102impl<ROOT: TreeRoot> fmt::Debug for SyntaxNode<ROOT> { 100impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> {
103 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 101 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
104 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; 102 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
105 if has_short_text(self.kind()) { 103 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<T: 'a + ?Sized + (Copy)>;
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 @@
1FILE@[0; 35)
2 STRUCT_ITEM@[0; 35)
3 STRUCT_KW@[0; 6)
4 NAME@[6; 8)
5 WHITESPACE@[6; 7)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 33)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 32)
10 IDENT@[9; 10) "T"
11 COLON@[10; 11)
12 WHITESPACE@[11; 12)
13 LIFETIME@[12; 14) "'a"
14 WHITESPACE@[14; 15)
15 PLUS@[15; 16)
16 WHITESPACE@[16; 17)
17 QUESTION@[17; 18)
18 PATH@[18; 24)
19 PATH_SEGMENT@[18; 24)
20 NAME_REF@[18; 24)
21 IDENT@[18; 23) "Sized"
22 WHITESPACE@[23; 24)
23 PLUS@[24; 25)
24 WHITESPACE@[25; 26)
25 L_PAREN@[26; 27)
26 PATH@[27; 31)
27 PATH_SEGMENT@[27; 31)
28 NAME_REF@[27; 31)
29 IDENT@[27; 31) "Copy"
30 R_PAREN@[31; 32)
31 R_ANGLE@[32; 33)
32 SEMI@[33; 34)
33 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<T = i32>;
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 @@
1FILE@[0; 19)
2 STRUCT_ITEM@[0; 19)
3 STRUCT_KW@[0; 6)
4 NAME@[6; 8)
5 WHITESPACE@[6; 7)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 17)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 16)
10 IDENT@[9; 10) "T"
11 WHITESPACE@[10; 11)
12 EQ@[11; 12)
13 PATH_TYPE@[12; 16)
14 PATH@[12; 16)
15 PATH_SEGMENT@[12; 16)
16 NAME_REF@[12; 16)
17 WHITESPACE@[12; 13)
18 IDENT@[13; 16) "i32"
19 R_ANGLE@[16; 17)
20 SEMI@[17; 18)
21 WHITESPACE@[18; 19)