@@ -100,68 +100,70 @@ matching, by enforcing the following restrictions on its input:
100
100
*/
101
101
102
102
use quote:: { ToTokens , Tokens } ;
103
- use self :: visit:: { Visitor , RecursiveVisitor } ;
104
103
use std:: collections:: HashSet ;
105
104
use std:: fs:: File ;
106
105
use std:: io:: { Read , Write } ;
107
- use std:: mem;
108
106
use std:: path:: Path ;
109
107
use std:: slice;
110
108
use syn;
111
109
112
- mod visit;
113
-
114
110
pub fn expand_match_tokens ( from : & Path , to : & Path ) {
115
111
let mut source = String :: new ( ) ;
116
112
File :: open ( from) . unwrap ( ) . read_to_string ( & mut source) . unwrap ( ) ;
117
- let mut crate_ = syn:: parse_crate ( & source) . expect ( "Parsing rules.rs module" ) ;
118
- RecursiveVisitor { node_visitor : ExpanderVisitor } . visit_crate ( & mut crate_) ;
113
+ let tts = syn:: parse_token_trees ( & source) . expect ( "Parsing rules.rs module" ) ;
119
114
let mut tokens = Tokens :: new ( ) ;
120
- crate_ . to_tokens ( & mut tokens ) ;
115
+ tokens . append_all ( expand_tts ( & tts ) ) ;
121
116
let code = tokens. to_string ( ) . replace ( "{ " , "{\n " ) . replace ( " }" , "\n }" ) ;
122
117
File :: create ( to) . unwrap ( ) . write_all ( code. as_bytes ( ) ) . unwrap ( ) ;
123
118
}
124
119
125
- struct ExpanderVisitor ;
126
-
127
- impl Visitor for ExpanderVisitor {
128
- fn visit_expression ( & mut self , expr : & mut syn:: Expr ) {
129
- let tts;
130
- if let syn:: Expr :: Mac ( ref mut macro_) = * expr {
131
- if macro_. path == syn:: Path :: from ( "match_token" ) {
132
- tts = mem:: replace ( & mut macro_. tts , Vec :: new ( ) ) ;
133
- } else {
134
- return
120
+ fn expand_tts ( tts : & [ syn:: TokenTree ] ) -> Vec < syn:: TokenTree > {
121
+ use syn:: * ;
122
+
123
+ let mut expanded = Vec :: new ( ) ;
124
+ let mut tts = tts. iter ( ) ;
125
+ while let Some ( tt) = tts. next ( ) {
126
+ match * tt {
127
+ TokenTree :: Token ( Token :: Ident ( ref ident) ) if ident == "match_token" => {
128
+ let start = tts. clone ( ) ;
129
+ if let Some ( & TokenTree :: Token ( Token :: Not ) ) = tts. next ( ) {
130
+ if let Some ( & TokenTree :: Delimited ( Delimited { ref tts, .. } ) ) = tts. next ( ) {
131
+ let ( to_be_matched, arms) = parse_match_token_macro ( tts) ;
132
+ let tokens = expand_match_token_macro ( to_be_matched, arms) ;
133
+ let tts = syn:: parse_token_trees ( & tokens. to_string ( ) )
134
+ . expect ( "parsing macro expansion as token trees" ) ;
135
+ expanded. extend ( tts) ;
136
+ continue
137
+ }
138
+ }
139
+ tts = start
140
+ }
141
+ TokenTree :: Token ( _) => {
142
+ expanded. push ( tt. clone ( ) )
143
+ }
144
+ TokenTree :: Delimited ( Delimited { delim, ref tts } ) => {
145
+ expanded. push ( TokenTree :: Delimited ( Delimited {
146
+ delim : delim,
147
+ tts : expand_tts ( tts) ,
148
+ } ) )
135
149
}
136
- } else {
137
- return
138
150
}
139
- let ( to_be_matched, arms) = parse_match_token_macro ( tts) ;
140
- let tokens = expand_match_token_macro ( to_be_matched, arms) ;
141
- * expr = syn:: parse_expr ( & tokens. to_string ( ) ) . expect ( "Parsing a match expression" ) ;
142
151
}
152
+ expanded
143
153
}
144
154
145
- fn parse_match_token_macro ( tts : Vec < syn:: TokenTree > ) -> ( syn:: Ident , Vec < Arm > ) {
155
+ fn parse_match_token_macro ( tts : & [ syn:: TokenTree ] ) -> ( & syn:: Ident , Vec < Arm > ) {
146
156
use syn:: TokenTree :: Delimited ;
147
- use syn:: DelimToken :: { Brace , Paren } ;
148
-
149
- let mut tts = tts. into_iter ( ) ;
150
- let inner_tts = if let Some ( Delimited ( syn:: Delimited { delim : Paren , tts } ) ) = tts. next ( ) {
151
- tts
152
- } else {
153
- panic ! ( "expected one top-level () block" )
154
- } ;
155
- assert_eq ! ( tts. len( ) , 0 ) ;
157
+ use syn:: DelimToken :: Brace ;
156
158
157
- let mut tts = inner_tts . into_iter ( ) ;
158
- let ident = if let Some ( syn:: TokenTree :: Token ( syn:: Token :: Ident ( ident) ) ) = tts. next ( ) {
159
+ let mut tts = tts . iter ( ) ;
160
+ let ident = if let Some ( & syn:: TokenTree :: Token ( syn:: Token :: Ident ( ref ident) ) ) = tts. next ( ) {
159
161
ident
160
162
} else {
161
163
panic ! ( "expected ident" )
162
164
} ;
163
165
164
- let block = if let Some ( Delimited ( syn:: Delimited { delim : Brace , tts } ) ) = tts. next ( ) {
166
+ let block = if let Some ( & Delimited ( syn:: Delimited { delim : Brace , ref tts } ) ) = tts. next ( ) {
165
167
tts
166
168
} else {
167
169
panic ! ( "expected one {} block" )
@@ -310,7 +312,7 @@ fn parse_rhs(tts: &mut slice::Iter<syn::TokenTree>) -> RHS {
310
312
RHS :: Expression ( expression)
311
313
}
312
314
313
- fn expand_match_token_macro ( to_be_matched : syn:: Ident , mut arms : Vec < Arm > ) -> Tokens {
315
+ fn expand_match_token_macro ( to_be_matched : & syn:: Ident , mut arms : Vec < Arm > ) -> Tokens {
314
316
// Handle the last arm specially at the end.
315
317
let last_arm = arms. pop ( ) . unwrap ( ) ;
316
318
0 commit comments