@@ -14,6 +14,14 @@ use codemap::{Span, Spanned};
14
14
use parse:: token;
15
15
use opt_vec:: OptVec ;
16
16
17
+ // this file defines an ast_fold trait for objects that can perform
18
+ // a "fold" on Rust ASTs. It also contains a structure that implements
19
+ // that trait, and a "default_fold" whose fields contain closures
20
+ // that perform "default traversals", visiting all of the sub-elements
21
+ // and re-assembling the result. The "fun_to_ident_folder" in the
22
+ // test module provides a simple example of creating a very simple
23
+ // fold that only looks at identifiers.
24
+
17
25
pub trait ast_fold {
18
26
fn fold_crate ( @self , & Crate ) -> Crate ;
19
27
fn fold_view_item ( @self , & view_item ) -> view_item ;
@@ -35,6 +43,7 @@ pub trait ast_fold {
35
43
fn fold_ident ( @self , Ident ) -> Ident ;
36
44
fn fold_path ( @self , & Path ) -> Path ;
37
45
fn fold_local ( @self , @Local ) -> @Local ;
46
+ fn fold_mac ( @self , & mac ) -> mac ;
38
47
fn map_exprs ( @self , @fn ( @Expr ) -> @Expr , & [ @Expr ] ) -> ~[ @Expr ] ;
39
48
fn new_id ( @self , NodeId ) -> NodeId ;
40
49
fn new_span ( @self , Span ) -> Span ;
@@ -64,6 +73,7 @@ pub struct AstFoldFns {
64
73
fold_ident : @fn ( Ident , @ast_fold ) -> Ident ,
65
74
fold_path : @fn ( & Path , @ast_fold ) -> Path ,
66
75
fold_local : @fn ( @Local , @ast_fold ) -> @Local ,
76
+ fold_mac : @fn ( & mac_ , Span , @ast_fold ) -> ( mac_ , Span ) ,
67
77
map_exprs : @fn ( @fn ( @Expr ) -> @Expr , & [ @Expr ] ) -> ~[ @Expr ] ,
68
78
new_id : @fn ( NodeId ) -> NodeId ,
69
79
new_span : @fn ( Span ) -> Span
@@ -112,19 +122,6 @@ fn fold_arg_(a: arg, fld: @ast_fold) -> arg {
112
122
}
113
123
}
114
124
115
- //used in noop_fold_expr, and possibly elsewhere in the future
116
- fn fold_mac_ ( m : & mac , fld : @ast_fold ) -> mac {
117
- Spanned {
118
- node : match m. node {
119
- mac_invoc_tt( ref p, ref tts, ctxt) =>
120
- mac_invoc_tt ( fld. fold_path ( p) ,
121
- fold_tts ( * tts, fld) ,
122
- ctxt)
123
- } ,
124
- span : fld. new_span ( m. span )
125
- }
126
- }
127
-
128
125
// build a new vector of tts by appling the ast_fold's fold_ident to
129
126
// all of the identifiers in the token trees.
130
127
pub fn fold_tts ( tts : & [ token_tree ] , f : @ast_fold ) -> ~[ token_tree ] {
@@ -326,10 +323,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
326
323
)
327
324
}
328
325
item_mac( ref m) => {
329
- // It would probably be nicer
330
- // to expose this in the ast_fold trait, but I'll defer
331
- // that work.
332
- item_mac ( fold_mac_ ( m, fld) )
326
+ item_mac ( fld. fold_mac ( m) )
333
327
}
334
328
}
335
329
}
@@ -398,7 +392,6 @@ pub fn noop_fold_block(b: &Block, fld: @ast_fold) -> Block {
398
392
}
399
393
400
394
fn noop_fold_stmt ( s : & Stmt_ , fld : @ast_fold ) -> Option < Stmt_ > {
401
- let fold_mac = |x| fold_mac_ ( x, fld) ;
402
395
match * s {
403
396
StmtDecl ( d, nid) => {
404
397
match fld. fold_decl ( d) {
@@ -412,7 +405,7 @@ fn noop_fold_stmt(s: &Stmt_, fld: @ast_fold) -> Option<Stmt_> {
412
405
StmtSemi ( e, nid) => {
413
406
Some ( StmtSemi ( fld. fold_expr ( e) , fld. new_id ( nid) ) )
414
407
}
415
- StmtMac ( ref mac, semi) => Some ( StmtMac ( fold_mac ( mac) , semi) )
408
+ StmtMac ( ref mac, semi) => Some ( StmtMac ( fld . fold_mac ( mac) , semi) )
416
409
}
417
410
}
418
411
@@ -480,6 +473,12 @@ fn noop_fold_decl(d: &Decl_, fld: @ast_fold) -> Option<Decl_> {
480
473
}
481
474
}
482
475
476
+ // lift a function in ast-thingy X fold -> ast-thingy to a function
477
+ // in (ast-thingy X span X fold) -> (ast-thingy X fold). Basically,
478
+ // carries the span around.
479
+ // It seems strange to me that the call to new_fold doesn't happen
480
+ // here but instead in the impl down below.... probably just an
481
+ // accident?
483
482
pub fn wrap < T > ( f : @fn ( & T , @ast_fold ) -> T )
484
483
-> @fn ( & T , Span , @ast_fold ) -> ( T , Span ) {
485
484
let result: @fn ( & T , Span , @ast_fold ) -> ( T , Span ) = |x, s, fld| {
@@ -498,8 +497,6 @@ pub fn noop_fold_expr(e: &Expr_, fld: @ast_fold) -> Expr_ {
498
497
}
499
498
let fold_field = |x| fold_field_ ( x, fld) ;
500
499
501
- let fold_mac = |x| fold_mac_ ( x, fld) ;
502
-
503
500
match * e {
504
501
ExprVstore ( e, v) => {
505
502
ExprVstore ( fld. fold_expr ( e) , v)
@@ -631,7 +628,7 @@ pub fn noop_fold_expr(e: &Expr_, fld: @ast_fold) -> Expr_ {
631
628
.. ( * a) . clone ( )
632
629
} )
633
630
}
634
- ExprMac ( ref mac) => ExprMac ( fold_mac ( mac) ) ,
631
+ ExprMac ( ref mac) => ExprMac ( fld . fold_mac ( mac) ) ,
635
632
ExprStruct ( ref path, ref fields, maybe_expr) => {
636
633
ExprStruct (
637
634
fld. fold_path ( path) ,
@@ -644,7 +641,6 @@ pub fn noop_fold_expr(e: &Expr_, fld: @ast_fold) -> Expr_ {
644
641
}
645
642
646
643
pub fn noop_fold_ty ( t : & ty_ , fld : @ast_fold ) -> ty_ {
647
- let fold_mac = |x| fold_mac_ ( x, fld) ;
648
644
fn fold_mt ( mt : & mt , fld : @ast_fold ) -> mt {
649
645
mt {
650
646
ty : ~fld. fold_ty ( mt. ty ) ,
@@ -700,7 +696,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
700
696
)
701
697
}
702
698
ty_typeof( e) => ty_typeof ( fld. fold_expr ( e) ) ,
703
- ty_mac( ref mac) => ty_mac ( fold_mac ( mac) )
699
+ ty_mac( ref mac) => ty_mac ( fld . fold_mac ( mac) )
704
700
}
705
701
}
706
702
@@ -787,6 +783,19 @@ fn noop_fold_local(l: @Local, fld: @ast_fold) -> @Local {
787
783
}
788
784
}
789
785
786
+ // the default macro traversal. visit the path
787
+ // using fold_path, and the tts using fold_tts,
788
+ // and the span using new_span
789
+ fn noop_fold_mac ( m : & mac_ , fld : @ast_fold ) -> mac_ {
790
+ match * m {
791
+ mac_invoc_tt( ref p, ref tts, ctxt) =>
792
+ mac_invoc_tt ( fld. fold_path ( p) ,
793
+ fold_tts ( * tts, fld) ,
794
+ ctxt)
795
+ }
796
+ }
797
+
798
+
790
799
/* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
791
800
value */
792
801
fn noop_map_exprs ( f : @fn ( @Expr ) -> @Expr , es : & [ @Expr ] ) -> ~[ @Expr ] {
@@ -819,6 +828,7 @@ pub fn default_ast_fold() -> ast_fold_fns {
819
828
fold_ident : noop_fold_ident,
820
829
fold_path : noop_fold_path,
821
830
fold_local : noop_fold_local,
831
+ fold_mac : wrap ( noop_fold_mac) ,
822
832
map_exprs : noop_map_exprs,
823
833
new_id : noop_id,
824
834
new_span : noop_span,
@@ -924,6 +934,10 @@ impl ast_fold for AstFoldFns {
924
934
fn fold_local ( @self , x : @Local ) -> @Local {
925
935
( self . fold_local ) ( x, self as @ast_fold )
926
936
}
937
+ fn fold_mac ( @self , x : & mac ) -> mac {
938
+ let ( n, s) = ( self . fold_mac ) ( & x. node , x. span , self as @ast_fold ) ;
939
+ Spanned { node : n, span : ( self . new_span ) ( s) }
940
+ }
927
941
fn map_exprs ( @self ,
928
942
f : @fn ( @Expr ) -> @Expr ,
929
943
e : & [ @Expr ] )
0 commit comments