Skip to content

Commit 9270832

Browse files
committed
comments & test cases for IdentRenamers
1 parent 6bee3c8 commit 9270832

File tree

1 file changed

+63
-11
lines changed

1 file changed

+63
-11
lines changed

src/libsyntax/ext/expand.rs

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,15 +344,16 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
344344

345345
fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
346346
-> Gc<ast::Item> {
347-
let (modifiers, attrs) = it.attrs.partitioned(|attr| {
347+
// partition the attributes into ItemModifiers and others
348+
let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
348349
match fld.extsbox.find(&intern(attr.name().get())) {
349350
Some(&ItemModifier(_)) => true,
350351
_ => false
351352
}
352353
});
353-
354+
// update the attrs, leave everything else alone. Is this mutation really a good idea?
354355
it = box(GC) ast::Item {
355-
attrs: attrs,
356+
attrs: other_attrs,
356357
..(*it).clone()
357358
};
358359

@@ -1047,13 +1048,14 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
10471048
#[cfg(test)]
10481049
mod test {
10491050
use super::{pattern_bindings, expand_crate, contains_macro_escape};
1050-
use super::{PatIdentFinder};
1051+
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
10511052
use ast;
10521053
use ast::{Attribute_, AttrOuter, MetaWord};
10531054
use attr;
10541055
use codemap;
10551056
use codemap::Spanned;
10561057
use ext::mtwt;
1058+
use fold::Folder;
10571059
use parse;
10581060
use parse::token;
10591061
use util::parser_testing::{string_to_parser};
@@ -1091,7 +1093,24 @@ mod test {
10911093
path_finder.path_accumulator
10921094
}
10931095

1096+
/// A Visitor that extracts the identifiers from a thingy.
1097+
// as a side note, I'm starting to want to abstract over these....
1098+
struct IdentFinder{
1099+
ident_accumulator: Vec<ast::Ident>
1100+
}
10941101

1102+
impl Visitor<()> for IdentFinder {
1103+
fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
1104+
self.ident_accumulator.push(id);
1105+
}
1106+
}
1107+
1108+
/// Find the idents in a crate
1109+
fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
1110+
let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
1111+
visit::walk_crate(&mut ident_finder, the_crate, ());
1112+
ident_finder.ident_accumulator
1113+
}
10951114

10961115
// these following tests are quite fragile, in that they don't test what
10971116
// *kind* of failure occurs.
@@ -1316,7 +1335,7 @@ mod test {
13161335
// but *shouldn't* bind because it was inserted by a different macro....
13171336
// can't write this test case until we have macro-generating macros.
13181337

1319-
// FIXME #9383 : lambda var hygiene
1338+
// lambda var hygiene
13201339
// expands to fn q(x_1:int){fn g(x_2:int){x_2 + x_1};}
13211340
#[test]
13221341
fn issue_9383(){
@@ -1375,9 +1394,9 @@ mod test {
13751394
assert_eq!(varref_marks,binding_marks.clone());
13761395
}
13771396
} else {
1397+
let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
13781398
let fail = (varref.segments.len() == 1)
1379-
&& (mtwt::resolve(varref.segments.get(0).identifier)
1380-
== binding_name);
1399+
&& (varref_name == binding_name);
13811400
// temp debugging:
13821401
if fail {
13831402
let varref_idents : Vec<ast::Ident>
@@ -1388,15 +1407,18 @@ mod test {
13881407
println!("text of test case: \"{}\"", teststr);
13891408
println!("");
13901409
println!("uh oh, matches but shouldn't:");
1391-
println!("varref: {}",varref_idents);
1410+
println!("varref #{}: {}, resolves to {}",idx, varref_idents,
1411+
varref_name);
13921412
// good lord, you can't make a path with 0 segments, can you?
13931413
let string = token::get_ident(varref.segments
13941414
.get(0)
13951415
.identifier);
13961416
println!("varref's first segment's uint: {}, and string: \"{}\"",
13971417
varref.segments.get(0).identifier.name,
13981418
string.get());
1399-
println!("binding: {}", *bindings.get(binding_idx));
1419+
println!("binding #{}: {}, resolves to {}",
1420+
binding_idx, *bindings.get(binding_idx),
1421+
binding_name);
14001422
mtwt::with_sctable(|x| mtwt::display_sctable(x));
14011423
}
14021424
assert!(!fail);
@@ -1459,13 +1481,43 @@ foo_module!()
14591481
// 'None' is listed as an identifier pattern because we don't yet know that
14601482
// it's the name of a 0-ary variant, and that 'i' appears twice in succession.
14611483
#[test]
1462-
fn crate_idents(){
1484+
fn crate_bindings_test(){
14631485
let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
14641486
match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
14651487
let idents = crate_bindings(&the_crate);
14661488
assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
14671489
}
14681490

1469-
//
1491+
// test the IdentRenamer directly
1492+
#[test]
1493+
fn ident_renamer_test () {
1494+
let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
1495+
let f_ident = token::str_to_ident("f");
1496+
let x_ident = token::str_to_ident("x");
1497+
let int_ident = token::str_to_ident("int");
1498+
let renames = vec!((x_ident,16));
1499+
let mut renamer = IdentRenamer{renames: &renames};
1500+
let renamed_crate = renamer.fold_crate(the_crate);
1501+
let idents = crate_idents(&renamed_crate);
1502+
let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
1503+
assert_eq!(resolved,vec!(f_ident.name,16,int_ident.name,16,16,16));
1504+
}
1505+
1506+
// test the PatIdentRenamer; only PatIdents get renamed
1507+
#[test]
1508+
fn pat_ident_renamer_test () {
1509+
let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
1510+
let f_ident = token::str_to_ident("f");
1511+
let x_ident = token::str_to_ident("x");
1512+
let int_ident = token::str_to_ident("int");
1513+
let renames = vec!((x_ident,16));
1514+
let mut renamer = PatIdentRenamer{renames: &renames};
1515+
let renamed_crate = renamer.fold_crate(the_crate);
1516+
let idents = crate_idents(&renamed_crate);
1517+
let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
1518+
let x_name = x_ident.name;
1519+
assert_eq!(resolved,vec!(f_ident.name,16,int_ident.name,16,x_name,x_name));
1520+
}
1521+
14701522

14711523
}

0 commit comments

Comments
 (0)