@@ -1421,38 +1421,52 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
1421
1421
return ret;
1422
1422
}
1423
1423
1424
- // given a function from idents to idents, produce
1425
- // an ast_fold that applies that function:
1426
- pub fn fun_to_ident_folder ( f : @fn ( ast:: Ident ) ->ast:: Ident ) -> @ast_fold {
1427
- let afp = default_ast_fold ( ) ;
1428
- let f_pre = @AstFoldFns {
1429
- fold_ident : |id, _| f ( id) ,
1430
- .. * afp
1431
- } ;
1432
- make_fold ( f_pre)
1424
+ // a function in SyntaxContext -> SyntaxContext
1425
+ pub trait CtxtFn {
1426
+ fn f ( & self , ast:: SyntaxContext ) -> ast:: SyntaxContext ;
1433
1427
}
1434
1428
1435
- // update the ctxts in a path to get a rename node
1436
- pub fn new_ident_renamer ( from : ast:: Ident ,
1437
- to : ast:: Name ) ->
1438
- @ fn ( ast :: Ident ) ->ast :: Ident {
1439
- | id : ast :: Ident |
1440
- ast :: Ident {
1441
- name : id . name ,
1442
- ctxt : new_rename ( from, to, id . ctxt )
1429
+ pub struct Renamer {
1430
+ from : ast:: Ident ,
1431
+ to : ast:: Name
1432
+ }
1433
+
1434
+ impl CtxtFn for Renamer {
1435
+ fn f ( & self , ctxt : ast :: SyntaxContext ) -> ast :: SyntaxContext {
1436
+ new_rename ( self . from , self . to , ctxt)
1443
1437
}
1444
1438
}
1445
1439
1446
- // update the ctxts in a path to get a mark node
1447
- pub fn new_ident_marker ( mark : Mrk ) ->
1448
- @fn ( ast:: Ident ) ->ast:: Ident {
1449
- |id : ast:: Ident |
1450
- ast:: Ident {
1451
- name : id. name ,
1452
- ctxt : new_mark ( mark, id. ctxt )
1440
+ pub struct Marker { mark : Mrk }
1441
+
1442
+ impl CtxtFn for Marker {
1443
+ fn f ( & self , ctxt : ast:: SyntaxContext ) -> ast:: SyntaxContext {
1444
+ new_mark ( self . mark , ctxt)
1445
+ }
1446
+ }
1447
+
1448
+ // given a function from ctxts to ctxts, produce
1449
+ // an ast_fold that applies that function to all ctxts:
1450
+ pub fn fun_to_ctxt_folder < T : ' static + CtxtFn > ( cf : @T ) -> @AstFoldFns {
1451
+ let afp = default_ast_fold ( ) ;
1452
+ let fi : @fn ( ast:: Ident , @ast_fold ) -> ast:: Ident =
1453
+ |ast:: Ident { name, ctxt} , _| {
1454
+ ast:: Ident { name : name, ctxt : cf. f ( ctxt) }
1455
+ } ;
1456
+ @AstFoldFns {
1457
+ fold_ident : fi,
1458
+ // check that it works, then add the fold_expr clause....
1459
+ .. * afp
1453
1460
}
1454
1461
}
1455
1462
1463
+ // just a convenience:
1464
+ pub fn new_mark_folder ( m : Mrk ) -> @AstFoldFns { fun_to_ctxt_folder ( @Marker { mark : m} ) }
1465
+ pub fn new_rename_folder ( from : ast:: Ident , to : ast:: Name ) -> @AstFoldFns {
1466
+ fun_to_ctxt_folder ( @Renamer { from : from, to : to} )
1467
+ }
1468
+
1469
+ /*
1456
1470
// perform resolution (in the MTWT sense) on all of the
1457
1471
// idents in the tree. This is the final step in expansion.
1458
1472
// FIXME #6993: this function could go away, along with
@@ -1465,25 +1479,26 @@ pub fn new_ident_resolver() ->
1465
1479
ctxt : EMPTY_CTXT
1466
1480
}
1467
1481
}
1482
+ */
1468
1483
1469
1484
// apply a given mark to the given token trees. Used prior to expansion of a macro.
1470
1485
fn mark_tts ( tts : & [ token_tree ] , m : Mrk ) -> ~[ token_tree ] {
1471
- fold_tts ( tts, new_ident_marker ( m) )
1486
+ fold_tts ( tts, new_mark_folder ( m) as @ ast_fold )
1472
1487
}
1473
1488
1474
1489
// apply a given mark to the given expr. Used following the expansion of a macro.
1475
1490
fn mark_expr ( expr : @ast:: Expr , m : Mrk ) -> @ast:: Expr {
1476
- fun_to_ident_folder ( new_ident_marker ( m ) ) . fold_expr ( expr)
1491
+ new_mark_folder ( m ) . fold_expr ( expr)
1477
1492
}
1478
1493
1479
1494
// apply a given mark to the given stmt. Used following the expansion of a macro.
1480
1495
fn mark_stmt ( expr : & ast:: Stmt , m : Mrk ) -> @ast:: Stmt {
1481
- fun_to_ident_folder ( new_ident_marker ( m ) ) . fold_stmt ( expr) . unwrap ( )
1496
+ new_mark_folder ( m ) . fold_stmt ( expr) . unwrap ( )
1482
1497
}
1483
1498
1484
1499
// apply a given mark to the given item. Used following the expansion of a macro.
1485
1500
fn mark_item ( expr : @ast:: item , m : Mrk ) -> Option < @ast:: item > {
1486
- fun_to_ident_folder ( new_ident_marker ( m ) ) . fold_item ( expr)
1501
+ new_mark_folder ( m ) . fold_item ( expr)
1487
1502
}
1488
1503
1489
1504
#[ cfg( test) ]
@@ -1499,8 +1514,8 @@ mod test {
1499
1514
use print:: pprust;
1500
1515
use std;
1501
1516
use std:: vec;
1502
- use util:: parser_testing:: { string_to_crate_and_sess , string_to_item , string_to_pat } ;
1503
- use util:: parser_testing:: { strs_to_idents} ;
1517
+ use util:: parser_testing:: { string_to_crate , string_to_crate_and_sess , string_to_item } ;
1518
+ use util:: parser_testing:: { string_to_pat , strs_to_idents} ;
1504
1519
use visit;
1505
1520
1506
1521
// make sure that fail! is present
@@ -1601,30 +1616,31 @@ mod test {
1601
1616
1602
1617
#[ test]
1603
1618
fn renaming ( ) {
1604
- let item_ast = string_to_item ( @"fn a ( ) -> int { let b = 13 ; b } " ) . unwrap ( ) ;
1619
+ let item_ast = string_to_crate ( @"fn f ( ) -> int { a } " ) ;
1605
1620
let a_name = intern ( "a" ) ;
1606
1621
let a2_name = gensym ( "a2" ) ;
1607
- let renamer = new_ident_renamer ( ast:: Ident { name : a_name, ctxt : EMPTY_CTXT } ,
1622
+ let renamer = new_rename_folder ( ast:: Ident { name : a_name, ctxt : EMPTY_CTXT } ,
1608
1623
a2_name) ;
1609
- let renamed_ast = fun_to_ident_folder ( renamer) . fold_item ( item_ast) . unwrap ( ) ;
1610
- let resolver = new_ident_resolver ( ) ;
1611
- let resolver_fold = fun_to_ident_folder ( resolver ) ;
1612
- let resolved_ast = resolver_fold . fold_item ( renamed_ast ) . unwrap ( ) ;
1613
- let resolved_as_str = pprust :: item_to_str ( resolved_ast ,
1614
- get_ident_interner ( ) ) ;
1615
- assert_eq ! ( resolved_as_str , ~" fn a2 ( ) -> int { let b = 13 ; b } ");
1624
+ let renamed_ast = renamer. fold_crate ( item_ast) ;
1625
+ let varrefs = @ mut ~ [ ] ;
1626
+ visit :: walk_crate ( & mut new_path_finder ( varrefs ) , & renamed_ast , ( ) ) ;
1627
+ match varrefs {
1628
+ @ [ Path { segments : [ ref seg ] , _ } ] => assert_eq ! ( mtwt_resolve ( seg . identifier ) , a2_name ) ,
1629
+ _ => assert_eq ! ( 0 , 1 )
1630
+ }
1616
1631
1617
1632
// try a double-rename, with pending_renames.
1618
1633
let a3_name = gensym ( "a3" ) ;
1619
1634
let ctxt2 = new_rename ( ast:: Ident :: new ( a_name) , a2_name, EMPTY_CTXT ) ;
1620
1635
let pending_renames = @mut ~[ ( ast:: Ident :: new ( a_name) , a2_name) ,
1621
1636
( ast:: Ident { name : a_name, ctxt : ctxt2} , a3_name) ] ;
1622
- let double_renamed = renames_to_fold(pending_renames).fold_item(item_ast).unwrap();
1623
- let resolved_again = resolver_fold.fold_item(double_renamed).unwrap();
1624
- let double_renamed_as_str = pprust::item_to_str(resolved_again,
1625
- get_ident_interner());
1626
- assert_eq!(double_renamed_as_str,~" fn a3( ) -> int { let b = 13 ; b } ");
1627
-
1637
+ let double_renamed = renames_to_fold ( pending_renames) . fold_crate ( item_ast) ;
1638
+ let varrefs = @mut ~[ ] ;
1639
+ visit:: walk_crate ( & mut new_path_finder ( varrefs) , & double_renamed, ( ) ) ;
1640
+ match varrefs {
1641
+ @[ Path { segments : [ ref seg] , _} ] => assert_eq ! ( mtwt_resolve( seg. identifier) , a2_name) ,
1642
+ _ => assert_eq ! ( 0 , 1 )
1643
+ }
1628
1644
}
1629
1645
1630
1646
fn fake_print_crate ( s : @pprust:: ps , crate : & ast:: Crate ) {
0 commit comments