提交 977b380c 编写于 作者: J John Clements

cleanup and shiny new more-functional interface

上级 a18a6318
......@@ -614,14 +614,10 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// oh dear heaven... this is going to include the enum
// names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones.
let mut name_finder = new_name_finder(Vec::new());
name_finder.visit_pat(&*expanded_pat,());
// generate fresh names, push them to a new pending list
let mut new_pending_renames = Vec::new();
for ident in name_finder.ident_accumulator.iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
}
let idents = pattern_bindings(expanded_pat);
let mut new_pending_renames =
idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
let rewritten_pat = {
let mut rename_fld =
IdentRenamer{renames: &mut new_pending_renames};
......@@ -668,10 +664,8 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// code duplicated from 'let', above. Perhaps this can be lifted
// into a separate function:
let expanded_pat = fld.fold_pat(*first_pat);
let mut name_finder = new_name_finder(Vec::new());
name_finder.visit_pat(&*expanded_pat,());
let mut new_pending_renames = Vec::new();
for ident in name_finder.ident_accumulator.iter() {
for ident in pattern_bindings(expanded_pat).iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
}
......@@ -681,8 +675,6 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// ones have already been applied):
rename_fld.fold_pat(expanded_pat)
};
/*
*/
ast::Arm {
attrs: arm.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(),
pats: arm.pats.iter().map(|x| fld.fold_pat(*x)).collect(),
......@@ -695,7 +687,7 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// a visitor that extracts the pat_ident (binding) paths
// from a given thingy and puts them in a mutable
// array (passed in to the traversal).
// array
#[deriving(Clone)]
struct NameFinderContext {
ident_accumulator: Vec<ast::Ident> ,
......@@ -735,13 +727,11 @@ fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
}
// return a visitor that extracts the pat_ident paths
// from a given thingy and puts them in a mutable
// array (passed in to the traversal)
fn new_name_finder(idents: Vec<ast::Ident> ) -> NameFinderContext {
NameFinderContext {
ident_accumulator: idents,
}
// find the pat_ident paths in a pattern
fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
name_finder.visit_pat(pat,());
name_finder.ident_accumulator
}
// expand a block. pushes a new exts_frame, then calls expand_block_elts
......@@ -1046,7 +1036,8 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
#[cfg(test)]
mod test {
use super::{new_name_finder, expand_crate, contains_macro_escape};
use super::{pattern_bindings, expand_crate, contains_macro_escape};
use super::{NameFinderContext};
use ast;
use ast::{Attribute_, AttrOuter, MetaWord};
use attr;
......@@ -1076,22 +1067,22 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
match *expr {
ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
self.path_accumulator.push(p.clone());
// not calling visit_path, should be fine.
// not calling visit_path, but it should be fine.
}
_ => visit::walk_expr(self,expr,())
}
}
}
// return a visitor that extracts the paths
// from a given thingy and puts them in a mutable
// array (passed in to the traversal)
fn new_path_finder(paths: Vec<ast::Path> ) -> PathExprFinderContext {
PathExprFinderContext {
path_accumulator: paths
}
// find the variable references in a crate
fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
let mut path_finder = PathExprFinderContext{path_accumulator:Vec::new()};
visit::walk_crate(&mut path_finder, the_crate, ());
path_finder.path_accumulator
}
// these following tests are quite fragile, in that they don't test what
// *kind* of failure occurs.
......@@ -1183,6 +1174,14 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
}
// find the pat_ident paths in a crate
fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
visit::walk_crate(&mut name_finder, the_crate, ());
name_finder.ident_accumulator
}
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
//let expanded_ast = expand_crate_str(crate_str);
// println!("expanded: {:?}\n",expanded_ast);
......@@ -1315,15 +1314,8 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
(ref str,ref conns, bic) => (str.to_owned(), conns.clone(), bic)
};
let cr = expand_crate_str(teststr.to_string());
// find the bindings:
let mut name_finder = new_name_finder(Vec::new());
visit::walk_crate(&mut name_finder,&cr,());
let bindings = name_finder.ident_accumulator;
// find the varrefs:
let mut path_finder = new_path_finder(Vec::new());
visit::walk_crate(&mut path_finder,&cr,());
let varrefs = path_finder.path_accumulator;
let bindings = crate_bindings(&cr);
let varrefs = crate_varrefs(&cr);
// must be one check clause for each binding:
assert_eq!(bindings.len(),bound_connections.len());
......@@ -1392,10 +1384,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
".to_string();
let cr = expand_crate_str(crate_str);
// find the xx binding
let mut name_finder = new_name_finder(Vec::new());
visit::walk_crate(&mut name_finder, &cr, ());
let bindings = name_finder.ident_accumulator;
let bindings = crate_bindings(&cr);
let cxbinds: Vec<&ast::Ident> =
bindings.iter().filter(|b| {
let ident = token::get_ident(**b);
......@@ -1408,10 +1397,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
_ => fail!("expected just one binding for ext_cx")
};
let resolved_binding = mtwt::resolve(*cxbind);
// find all the xx varrefs:
let mut path_finder = new_path_finder(Vec::new());
visit::walk_crate(&mut path_finder, &cr, ());
let varrefs = path_finder.path_accumulator;
let varrefs = crate_varrefs(&cr);
// the xx binding should bind all of the xx varrefs:
for (idx,v) in varrefs.iter().filter(|p| {
......@@ -1437,10 +1423,8 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
fn pat_idents(){
let pat = string_to_pat(
"(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_string());
let mut pat_idents = new_name_finder(Vec::new());
pat_idents.visit_pat(pat, ());
assert_eq!(pat_idents.ident_accumulator,
strs_to_idents(vec!("a","c","b","d")));
let idents = pattern_bindings(pat);
assert_eq!(idents, strs_to_idents(vec!("a","c","b","d")));
}
// test the list of identifier patterns gathered by the visitor. Note that
......@@ -1450,11 +1434,8 @@ fn pat_idents(){
fn crate_idents(){
let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
let mut idents = new_name_finder(Vec::new());
//visit::walk_crate(&mut idents, &the_crate, ());
idents.visit_mod(&the_crate.module, the_crate.span, ast::CRATE_NODE_ID, ());
assert_eq!(idents.ident_accumulator,
strs_to_idents(vec!("a","b","None","i","i","z","y")));
let idents = crate_bindings(&the_crate);
assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册