1
1
//! FIXME: write short doc here
2
2
3
- use crate :: { Subtree , TokenTree } ;
3
+ use crate :: { Leaf , Subtree , TokenTree } ;
4
4
5
5
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
6
6
struct EntryId ( usize ) ;
@@ -13,7 +13,7 @@ struct EntryPtr(EntryId, usize);
13
13
#[ derive( Debug ) ]
14
14
enum Entry < ' t > {
15
15
// Mimicking types from proc-macro.
16
- Subtree ( & ' t TokenTree , EntryId ) ,
16
+ Subtree ( Option < & ' t TokenTree > , & ' t Subtree , EntryId ) ,
17
17
Leaf ( & ' t TokenTree ) ,
18
18
// End entries contain a pointer to the entry from the containing
19
19
// token tree, or None if this is the outermost level.
@@ -27,49 +27,76 @@ pub struct TokenBuffer<'t> {
27
27
buffers : Vec < Box < [ Entry < ' t > ] > > ,
28
28
}
29
29
30
- impl < ' t > TokenBuffer < ' t > {
31
- pub fn new ( tokens : & ' t [ TokenTree ] ) -> TokenBuffer < ' t > {
32
- let mut buffers = vec ! [ ] ;
33
-
34
- let idx = TokenBuffer :: new_inner ( tokens, & mut buffers, None ) ;
35
- assert_eq ! ( idx, 0 ) ;
36
-
37
- TokenBuffer { buffers }
38
- }
30
+ trait TokenList < ' a > {
31
+ fn entries ( & self ) -> ( Vec < ( usize , ( & ' a Subtree , Option < & ' a TokenTree > ) ) > , Vec < Entry < ' a > > ) ;
32
+ }
39
33
40
- fn new_inner (
41
- tokens : & ' t [ TokenTree ] ,
42
- buffers : & mut Vec < Box < [ Entry < ' t > ] > > ,
43
- next : Option < EntryPtr > ,
44
- ) -> usize {
34
+ impl < ' a > TokenList < ' a > for & ' a [ TokenTree ] {
35
+ fn entries ( & self ) -> ( Vec < ( usize , ( & ' a Subtree , Option < & ' a TokenTree > ) ) > , Vec < Entry < ' a > > ) {
45
36
// Must contain everything in tokens and then the Entry::End
46
- let start_capacity = tokens . len ( ) + 1 ;
37
+ let start_capacity = self . len ( ) + 1 ;
47
38
let mut entries = Vec :: with_capacity ( start_capacity) ;
48
39
let mut children = vec ! [ ] ;
49
-
50
- for ( idx, tt) in tokens. iter ( ) . enumerate ( ) {
40
+ for ( idx, tt) in self . iter ( ) . enumerate ( ) {
51
41
match tt {
52
42
TokenTree :: Leaf ( _) => {
53
43
entries. push ( Entry :: Leaf ( tt) ) ;
54
44
}
55
45
TokenTree :: Subtree ( subtree) => {
56
46
entries. push ( Entry :: End ( None ) ) ;
57
- children. push ( ( idx, ( subtree, tt ) ) ) ;
47
+ children. push ( ( idx, ( subtree, Some ( tt ) ) ) ) ;
58
48
}
59
49
}
60
50
}
51
+ ( children, entries)
52
+ }
53
+ }
54
+
55
+ impl < ' a > TokenList < ' a > for & ' a Subtree {
56
+ fn entries ( & self ) -> ( Vec < ( usize , ( & ' a Subtree , Option < & ' a TokenTree > ) ) > , Vec < Entry < ' a > > ) {
57
+ // Must contain everything in tokens and then the Entry::End
58
+ let mut entries = vec ! [ ] ;
59
+ let mut children = vec ! [ ] ;
60
+ entries. push ( Entry :: End ( None ) ) ;
61
+ children. push ( ( 0usize , ( * self , None ) ) ) ;
62
+ ( children, entries)
63
+ }
64
+ }
65
+
66
+ impl < ' t > TokenBuffer < ' t > {
67
+ pub fn from_tokens ( tokens : & ' t [ TokenTree ] ) -> TokenBuffer < ' t > {
68
+ Self :: new ( tokens)
69
+ }
70
+
71
+ pub fn from_subtree ( subtree : & ' t Subtree ) -> TokenBuffer < ' t > {
72
+ Self :: new ( subtree)
73
+ }
74
+
75
+ fn new < T : TokenList < ' t > > ( tokens : T ) -> TokenBuffer < ' t > {
76
+ let mut buffers = vec ! [ ] ;
77
+ let idx = TokenBuffer :: new_inner ( tokens, & mut buffers, None ) ;
78
+ assert_eq ! ( idx, 0 ) ;
79
+ TokenBuffer { buffers }
80
+ }
81
+
82
+ fn new_inner < T : TokenList < ' t > > (
83
+ tokens : T ,
84
+ buffers : & mut Vec < Box < [ Entry < ' t > ] > > ,
85
+ next : Option < EntryPtr > ,
86
+ ) -> usize {
87
+ let ( children, mut entries) = tokens. entries ( ) ;
61
88
62
89
entries. push ( Entry :: End ( next) ) ;
63
90
let res = buffers. len ( ) ;
64
91
buffers. push ( entries. into_boxed_slice ( ) ) ;
65
92
66
93
for ( child_idx, ( subtree, tt) ) in children {
67
94
let idx = TokenBuffer :: new_inner (
68
- & subtree. token_trees ,
95
+ subtree. token_trees . as_slice ( ) ,
69
96
buffers,
70
97
Some ( EntryPtr ( EntryId ( res) , child_idx + 1 ) ) ,
71
98
) ;
72
- buffers[ res] . as_mut ( ) [ child_idx] = Entry :: Subtree ( tt, EntryId ( idx) ) ;
99
+ buffers[ res] . as_mut ( ) [ child_idx] = Entry :: Subtree ( tt, subtree , EntryId ( idx) ) ;
73
100
}
74
101
75
102
res
@@ -87,6 +114,24 @@ impl<'t> TokenBuffer<'t> {
87
114
}
88
115
}
89
116
117
+ #[ derive( Debug ) ]
118
+ pub enum TokenTreeRef < ' a > {
119
+ Subtree ( & ' a Subtree , Option < & ' a TokenTree > ) ,
120
+ Leaf ( & ' a Leaf , & ' a TokenTree ) ,
121
+ }
122
+
123
+ impl < ' a > TokenTreeRef < ' a > {
124
+ pub fn cloned ( & self ) -> TokenTree {
125
+ match & self {
126
+ TokenTreeRef :: Subtree ( subtree, tt) => match tt {
127
+ Some ( it) => ( * it) . clone ( ) ,
128
+ None => ( * subtree) . clone ( ) . into ( ) ,
129
+ } ,
130
+ TokenTreeRef :: Leaf ( _, tt) => ( * tt) . clone ( ) ,
131
+ }
132
+ }
133
+ }
134
+
90
135
/// A safe version of `Cursor` from `syn` crate https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L125
91
136
#[ derive( Copy , Clone , Debug ) ]
92
137
pub struct Cursor < ' a > {
@@ -114,12 +159,11 @@ impl<'a> Cursor<'a> {
114
159
match self . entry ( ) {
115
160
Some ( Entry :: End ( Some ( ptr) ) ) => {
116
161
let idx = ptr. 1 ;
117
- if let Some ( Entry :: Subtree ( TokenTree :: Subtree ( subtree) , _) ) =
162
+ if let Some ( Entry :: Subtree ( _ , subtree, _) ) =
118
163
self . buffer . entry ( & EntryPtr ( ptr. 0 , idx - 1 ) )
119
164
{
120
165
return Some ( subtree) ;
121
166
}
122
-
123
167
None
124
168
}
125
169
_ => None ,
@@ -134,18 +178,21 @@ impl<'a> Cursor<'a> {
134
178
/// a cursor into that subtree
135
179
pub fn subtree ( self ) -> Option < Cursor < ' a > > {
136
180
match self . entry ( ) {
137
- Some ( Entry :: Subtree ( _, entry_id) ) => {
181
+ Some ( Entry :: Subtree ( _, _ , entry_id) ) => {
138
182
Some ( Cursor :: create ( self . buffer , EntryPtr ( * entry_id, 0 ) ) )
139
183
}
140
184
_ => None ,
141
185
}
142
186
}
143
187
144
188
/// If the cursor is pointing at a `TokenTree`, returns it
145
- pub fn token_tree ( self ) -> Option < & ' a TokenTree > {
189
+ pub fn token_tree ( self ) -> Option < TokenTreeRef < ' a > > {
146
190
match self . entry ( ) {
147
- Some ( Entry :: Leaf ( tt) ) => Some ( tt) ,
148
- Some ( Entry :: Subtree ( tt, _) ) => Some ( tt) ,
191
+ Some ( Entry :: Leaf ( tt) ) => match tt {
192
+ TokenTree :: Leaf ( leaf) => Some ( TokenTreeRef :: Leaf ( leaf, * tt) ) ,
193
+ TokenTree :: Subtree ( subtree) => Some ( TokenTreeRef :: Subtree ( subtree, Some ( tt) ) ) ,
194
+ } ,
195
+ Some ( Entry :: Subtree ( tt, subtree, _) ) => Some ( TokenTreeRef :: Subtree ( subtree, * tt) ) ,
149
196
Some ( Entry :: End ( _) ) => None ,
150
197
None => None ,
151
198
}
@@ -172,7 +219,7 @@ impl<'a> Cursor<'a> {
172
219
/// a cursor into that subtree
173
220
pub fn bump_subtree ( self ) -> Cursor < ' a > {
174
221
match self . entry ( ) {
175
- Some ( Entry :: Subtree ( _, _) ) => self . subtree ( ) . unwrap ( ) ,
222
+ Some ( Entry :: Subtree ( _, _, _ ) ) => self . subtree ( ) . unwrap ( ) ,
176
223
_ => self . bump ( ) ,
177
224
}
178
225
}
0 commit comments