1
- use std:: { iter:: FusedIterator , mem, slice, sync :: Arc } ;
1
+ use std:: { ffi :: c_void , fmt , iter:: FusedIterator , mem, slice} ;
2
2
3
- use erasable:: Thin ;
4
- use slice_dst:: SliceWithHeader ;
3
+ use triomphe:: { Arc , ThinArc } ;
5
4
6
5
use crate :: {
7
- green:: { GreenElement , GreenElementRef , PackedGreenElement , SyntaxKind } ,
8
- GreenToken , TextSize ,
6
+ green:: { GreenElement , GreenElementRef , SyntaxKind } ,
7
+ GreenToken , NodeOrToken , TextSize ,
9
8
} ;
10
9
11
- #[ repr( align( 2 ) ) ] // NB: this is an at-least annotation
12
10
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
13
11
pub ( super ) struct GreenNodeHead {
14
12
kind : SyntaxKind ,
@@ -17,23 +15,51 @@ pub(super) struct GreenNodeHead {
17
15
18
16
/// Internal node in the immutable tree.
19
17
/// It has other nodes and tokens as children.
20
- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
21
- #[ repr( transparent) ]
18
+ #[ derive( Clone , PartialEq , Eq , Hash ) ]
22
19
pub struct GreenNode {
23
- pub ( super ) data : Thin < Arc < SliceWithHeader < GreenNodeHead , PackedGreenElement > > > ,
20
+ data : ThinArc < GreenNodeHead , GreenChild > ,
21
+ }
22
+
23
+ impl fmt:: Debug for GreenNode {
24
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
25
+ f. debug_struct ( "GreenNode" )
26
+ . field ( "kind" , & self . kind ( ) )
27
+ . field ( "text_len" , & self . text_len ( ) )
28
+ . field ( "n_children" , & self . children ( ) . len ( ) )
29
+ . finish ( )
30
+ }
24
31
}
25
32
33
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
26
34
enum GreenChild {
27
35
Node {
28
36
// offset: TextSize,
29
- node : GreenNode
37
+ node : GreenNode ,
30
38
} ,
31
39
Token {
32
40
// offset: TextSize,
33
- token : GreenToken
41
+ token : GreenToken ,
34
42
} ,
35
43
}
36
44
45
+ impl From < GreenElement > for GreenChild {
46
+ fn from ( e : GreenElement ) -> Self {
47
+ match e {
48
+ NodeOrToken :: Node ( node) => GreenChild :: Node { node } ,
49
+ NodeOrToken :: Token ( token) => GreenChild :: Token { token } ,
50
+ }
51
+ }
52
+ }
53
+
54
+ impl GreenChild {
55
+ fn as_ref ( & self ) -> GreenElementRef {
56
+ match self {
57
+ GreenChild :: Node { node } => NodeOrToken :: Node ( node) ,
58
+ GreenChild :: Token { token } => NodeOrToken :: Token ( token) ,
59
+ }
60
+ }
61
+ }
62
+
37
63
#[ cfg( target_pointer_width = "64" ) ]
38
64
const _: ( ) = {
39
65
let cond = mem:: size_of :: < GreenChild > ( ) == mem:: size_of :: < usize > ( ) * 2 ;
@@ -49,30 +75,33 @@ impl GreenNode {
49
75
I :: IntoIter : ExactSizeIterator ,
50
76
{
51
77
let mut text_len: TextSize = 0 . into ( ) ;
52
- let children = children
53
- . into_iter ( )
54
- . inspect ( |it| text_len += it. text_len ( ) )
55
- . map ( PackedGreenElement :: from) ;
56
- let mut data: Arc < _ > =
57
- SliceWithHeader :: new ( GreenNodeHead { kind, text_len : 0 . into ( ) } , children) ;
78
+ let children =
79
+ children. into_iter ( ) . inspect ( |it| text_len += it. text_len ( ) ) . map ( GreenChild :: from) ;
80
+
81
+ let data =
82
+ ThinArc :: from_header_and_iter ( GreenNodeHead { kind, text_len : 0 . into ( ) } , children) ;
58
83
59
84
// XXX: fixup `text_len` after construction, because we can't iterate
60
85
// `children` twice.
61
- Arc :: get_mut ( & mut data) . unwrap ( ) . header . text_len = text_len;
86
+ let data = {
87
+ let mut data = Arc :: from_thin ( data) ;
88
+ Arc :: get_mut ( & mut data) . unwrap ( ) . header . header . text_len = text_len;
89
+ Arc :: into_thin ( data)
90
+ } ;
62
91
63
- GreenNode { data : data . into ( ) }
92
+ GreenNode { data }
64
93
}
65
94
66
95
/// Kind of this node.
67
96
#[ inline]
68
97
pub fn kind ( & self ) -> SyntaxKind {
69
- self . data . header . kind
98
+ self . data . header . header . kind
70
99
}
71
100
72
101
/// Returns the length of the text covered by this node.
73
102
#[ inline]
74
103
pub fn text_len ( & self ) -> TextSize {
75
- self . data . header . text_len
104
+ self . data . header . header . text_len
76
105
}
77
106
78
107
/// Children of this node.
@@ -81,15 +110,14 @@ impl GreenNode {
81
110
Children { inner : self . data . slice . iter ( ) }
82
111
}
83
112
84
- pub ( crate ) fn ptr ( & self ) -> * const u8 {
85
- let r: & SliceWithHeader < _ , _ > = & * self . data ;
86
- r as * const _ as _
113
+ pub fn ptr ( & self ) -> * const c_void {
114
+ self . data . heap_ptr ( )
87
115
}
88
116
}
89
117
90
118
#[ derive( Debug , Clone ) ]
91
119
pub struct Children < ' a > {
92
- inner : slice:: Iter < ' a , PackedGreenElement > ,
120
+ inner : slice:: Iter < ' a , GreenChild > ,
93
121
}
94
122
95
123
// NB: forward everything stable that iter::Slice specializes as of Rust 1.39.0
@@ -105,7 +133,7 @@ impl<'a> Iterator for Children<'a> {
105
133
106
134
#[ inline]
107
135
fn next ( & mut self ) -> Option < GreenElementRef < ' a > > {
108
- self . inner . next ( ) . map ( PackedGreenElement :: as_ref)
136
+ self . inner . next ( ) . map ( GreenChild :: as_ref)
109
137
}
110
138
111
139
#[ inline]
@@ -123,7 +151,7 @@ impl<'a> Iterator for Children<'a> {
123
151
124
152
#[ inline]
125
153
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
126
- self . inner . nth ( n) . map ( PackedGreenElement :: as_ref)
154
+ self . inner . nth ( n) . map ( GreenChild :: as_ref)
127
155
}
128
156
129
157
#[ inline]
@@ -150,12 +178,12 @@ impl<'a> Iterator for Children<'a> {
150
178
impl < ' a > DoubleEndedIterator for Children < ' a > {
151
179
#[ inline]
152
180
fn next_back ( & mut self ) -> Option < Self :: Item > {
153
- self . inner . next_back ( ) . map ( PackedGreenElement :: as_ref)
181
+ self . inner . next_back ( ) . map ( GreenChild :: as_ref)
154
182
}
155
183
156
184
#[ inline]
157
185
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
158
- self . inner . nth_back ( n) . map ( PackedGreenElement :: as_ref)
186
+ self . inner . nth_back ( n) . map ( GreenChild :: as_ref)
159
187
}
160
188
161
189
#[ inline]
0 commit comments