@@ -100,68 +100,70 @@ matching, by enforcing the following restrictions on its input:
100100*/
101101
102102use quote:: { ToTokens , Tokens } ;
103- use self :: visit:: { Visitor , RecursiveVisitor } ;
104103use std:: collections:: HashSet ;
105104use std:: fs:: File ;
106105use std:: io:: { Read , Write } ;
107- use std:: mem;
108106use std:: path:: Path ;
109107use std:: slice;
110108use syn;
111109
112- mod visit;
113-
114110pub fn expand_match_tokens ( from : & Path , to : & Path ) {
115111 let mut source = String :: new ( ) ;
116112 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" ) ;
119114 let mut tokens = Tokens :: new ( ) ;
120- crate_ . to_tokens ( & mut tokens ) ;
115+ tokens . append_all ( expand_tts ( & tts ) ) ;
121116 let code = tokens. to_string ( ) . replace ( "{ " , "{\n " ) . replace ( " }" , "\n }" ) ;
122117 File :: create ( to) . unwrap ( ) . write_all ( code. as_bytes ( ) ) . unwrap ( ) ;
123118}
124119
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+ } ) )
135149 }
136- } else {
137- return
138150 }
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" ) ;
142151 }
152+ expanded
143153}
144154
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 > ) {
146156 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 ;
156158
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 ( ) {
159161 ident
160162 } else {
161163 panic ! ( "expected ident" )
162164 } ;
163165
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 ( ) {
165167 tts
166168 } else {
167169 panic ! ( "expected one {} block" )
@@ -310,7 +312,7 @@ fn parse_rhs(tts: &mut slice::Iter<syn::TokenTree>) -> RHS {
310312 RHS :: Expression ( expression)
311313}
312314
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 {
314316 // Handle the last arm specially at the end.
315317 let last_arm = arms. pop ( ) . unwrap ( ) ;
316318
0 commit comments