adding test case to check marking/unmarking
This commit is contained in:
parent
b7c0512b27
commit
91d3c36430
@ -23,7 +23,7 @@
|
||||
use parse;
|
||||
use parse::{parse_item_from_source_str};
|
||||
use parse::token;
|
||||
use parse::token::{fresh_name, ident_to_str, intern};
|
||||
use parse::token::{fresh_mark, fresh_name, ident_to_str, intern};
|
||||
use visit;
|
||||
use visit::Visitor;
|
||||
|
||||
@ -67,7 +67,9 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
|
||||
},
|
||||
});
|
||||
|
||||
let expanded = match expandfun(cx, mac.span, *tts) {
|
||||
let fm = fresh_mark();
|
||||
let marked_tts = mark_tts(*tts,fm);
|
||||
let expanded = match expandfun(cx, mac.span, marked_tts) {
|
||||
MRExpr(e) => e,
|
||||
MRAny(expr_maker,_,_) => expr_maker(),
|
||||
_ => {
|
||||
@ -259,6 +261,12 @@ fn mk_simple_path(ident: ast::Ident, span: Span) -> ast::Path {
|
||||
}
|
||||
}
|
||||
|
||||
// apply a fresh mark to the given token trees. Used prior to expansion of a macro.
|
||||
fn mark_tts(tts : &[token_tree], m : Mrk) -> ~[token_tree] {
|
||||
fold_tts(tts,new_ident_marker(m))
|
||||
}
|
||||
|
||||
|
||||
// This is a secondary mechanism for invoking syntax extensions on items:
|
||||
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
|
||||
// attribute prefixing an item, and are interpreted by feeding the item
|
||||
@ -1285,7 +1293,7 @@ pub fn new_ident_renamer(from: ast::Ident,
|
||||
|
||||
|
||||
// update the ctxts in a path to get a mark node
|
||||
pub fn new_ident_marker(mark: uint) ->
|
||||
pub fn new_ident_marker(mark: Mrk) ->
|
||||
@fn(ast::Ident)->ast::Ident {
|
||||
|id : ast::Ident|
|
||||
ast::Ident{
|
||||
@ -1461,18 +1469,18 @@ fn expand_and_resolve_and_pretty_print (crate_str : @str) -> ~str {
|
||||
|
||||
#[test]
|
||||
fn automatic_renaming () {
|
||||
// "fn a() -> int { let b = 13; let c = b; b+c }"
|
||||
// --> b & c should get new names, in the expr too.
|
||||
// "macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}"
|
||||
// --> one should be renamed, one should not.
|
||||
|
||||
let teststrs =
|
||||
~[// b & c should get new names throughout, in the expr too:
|
||||
@"fn a() -> int { let b = 13; let c = b; b+c }",
|
||||
// the use of b before the + should be renamed, the other one not:
|
||||
@"macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}",
|
||||
// the b before the plus should not be renamed (requires marks)
|
||||
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}"];
|
||||
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}",
|
||||
// the z flows into and out of two macros (g & f) along one path, and one (just g) along the
|
||||
// other, so the result of the whole thing should be "let z_123 = 3; z_123"
|
||||
@"macro_rules! g (($x:ident) => ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)}))
|
||||
fn a(){g!(z)}"
|
||||
];
|
||||
for s in teststrs.iter() {
|
||||
// we need regexps to test these!
|
||||
std::io::println(expand_and_resolve_and_pretty_print(*s));
|
||||
|
@ -126,7 +126,7 @@ fn fold_mac_(m: &mac, fld: @ast_fold) -> mac {
|
||||
|
||||
// build a new vector of tts by appling the given function to
|
||||
// all of the identifiers in the token trees.
|
||||
pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
|
||||
pub fn fold_tts(tts : &[token_tree], f: @fn(Ident)->Ident) -> ~[token_tree] {
|
||||
do tts.map |tt| {
|
||||
match *tt {
|
||||
tt_tok(span, ref tok) =>
|
||||
@ -145,7 +145,7 @@ pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
|
||||
}
|
||||
|
||||
// apply ident folder if it's an ident, otherwise leave it alone
|
||||
fn maybe_fold_ident(t : &token::Token, f: @fn(ident)->ident) -> token::Token {
|
||||
fn maybe_fold_ident(t : &token::Token, f: @fn(Ident)->Ident) -> token::Token {
|
||||
match *t {
|
||||
token::IDENT(id,followed_by_colons) =>
|
||||
token::IDENT(f(id),followed_by_colons),
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use ast;
|
||||
use ast::Name;
|
||||
use ast::{Name, Mrk};
|
||||
use ast_util;
|
||||
use parse::token;
|
||||
use util::interner::StrInterner;
|
||||
@ -557,6 +557,11 @@ pub fn fresh_name(src_name : &ast::Ident) -> Name {
|
||||
gensym(fmt!("%s_%u",ident_to_str(src_name),num))
|
||||
}
|
||||
|
||||
// create a fresh mark.
|
||||
pub fn fresh_mark() -> Mrk {
|
||||
gensym("mark")
|
||||
}
|
||||
|
||||
/**
|
||||
* All the valid words that have meaning in the Rust language.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user