use attr::AttrMetaMethods;
use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+use crateid::CrateId;
use ext::base::*;
use fold::*;
use parse;
use std::cast;
use std::unstable::dynamic_lib::DynamicLibrary;
use std::os;
-use std::vec_ng::Vec;
pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
match e.node {
format!("expected macro name without module \
separators"));
// let compilation continue
- return MacResult::raw_dummy_expr(e.span);
+ return DummyResult::raw_expr(e.span);
}
let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname);
extnamestr.get()));
// let compilation continue
- return MacResult::raw_dummy_expr(e.span);
+ return DummyResult::raw_expr(e.span);
}
Some(&NormalTT(ref expandfun, exp_span)) => {
fld.cx.bt_push(ExpnInfo {
let expanded = match expandfun.expand(fld.cx,
mac_span.call_site,
- marked_before.as_slice()) {
- MRExpr(e) => e,
- MRAny(any_macro) => any_macro.make_expr(),
- _ => {
+ marked_before.as_slice()).make_expr() {
+ Some(e) => e,
+ None => {
fld.cx.span_err(
pth.span,
format!(
extnamestr.get()
)
);
- return MacResult::raw_dummy_expr(e.span);
+ return DummyResult::raw_expr(e.span);
}
};
format!("'{}' is not a tt-style macro",
extnamestr.get())
);
- return MacResult::raw_dummy_expr(e.span);
+ return DummyResult::raw_expr(e.span);
}
};
let it = expand_item_modifiers(it, fld);
let mut decorator_items = SmallVector::zero();
- for attr in it.attrs.rev_iter() {
+ for attr in it.attrs.iter().rev() {
let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) {
let mut items: SmallVector<@ast::Item> = SmallVector::zero();
dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| items.push(item));
- decorator_items.extend(&mut items.move_iter()
+ decorator_items.extend(items.move_iter()
.flat_map(|item| expand_item(item, fld).move_iter()));
fld.cx.bt_pop();
}
};
- let items = match expanded {
- MRItem(it) => {
- mark_item(it,fm).move_iter()
- .flat_map(|i| fld.fold_item(i).move_iter())
- .collect()
- }
- MRExpr(_) => {
- fld.cx.span_err(pth.span,
- format!("expr macro in item position: {}",
- extnamestr.get()));
- return SmallVector::zero();
- }
- MRAny(any_macro) => {
- any_macro.make_items().move_iter()
- .flat_map(|i| mark_item(i, fm).move_iter())
- .flat_map(|i| fld.fold_item(i).move_iter())
- .collect()
- }
- MRDef(MacroDef { name, ext }) => {
+ let items = match expanded.make_def() {
+ Some(MacroDef { name, ext }) => {
// yikes... no idea how to apply the mark to this. I'm afraid
// we're going to have to wait-and-see on this one.
fld.extsbox.insert(intern(name), ext);
SmallVector::zero()
}
}
+ None => {
+ match expanded.make_items() {
+ Some(items) => {
+ items.move_iter()
+ .flat_map(|i| mark_item(i, fm).move_iter())
+ .flat_map(|i| fld.fold_item(i).move_iter())
+ .collect()
+ }
+ None => {
+ fld.cx.span_err(pth.span,
+ format!("expr macro in item position: {}",
+ extnamestr.get()));
+ return SmallVector::zero();
+ }
+ }
+ }
};
fld.cx.bt_pop();
return items;
}
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
- let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
+ let MacroCrate { lib, macros, registrar_symbol } =
+ fld.cx.ecfg.loader.load_crate(krate);
let crate_name = match krate.node {
ast::ViewItemExternCrate(name, _, _) => name,
};
let name = format!("<{} macros>", token::get_ident(crate_name));
- let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
- for source in exported_macros.iter() {
+ for source in macros.iter() {
let item = parse::parse_item_from_source_str(name.clone(),
(*source).clone(),
fld.cx.cfg(),
// Make sure the path contains a / or the linker will search for it.
let path = os::make_absolute(&path);
- let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
+ let registrar = match registrar_symbol {
Some(registrar) => registrar,
None => return
};
let expanded = match expandfun.expand(fld.cx,
mac_span.call_site,
- marked_tts.as_slice()) {
- MRExpr(e) => {
- @codemap::Spanned {
- node: StmtExpr(e, ast::DUMMY_NODE_ID),
- span: e.span,
- }
- }
- MRAny(any_macro) => any_macro.make_stmt(),
- _ => {
+ marked_tts.as_slice()).make_stmt() {
+ Some(stmt) => stmt,
+ None => {
fld.cx.span_err(pth.span,
format!("non-stmt macro in stmt pos: {}",
extnamestr));
// expand the elements of a block.
pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
- let new_view_items = b.view_items.map(|x| fld.fold_view_item(x));
+ let new_view_items = b.view_items.iter().map(|x| fld.fold_view_item(x)).collect();
let new_stmts =
b.stmts.iter().flat_map(|x| {
let renamed_stmt = {
}
}
-pub struct MacroExpander<'a> {
- extsbox: SyntaxEnv,
- cx: &'a mut ExtCtxt<'a>,
+pub struct MacroExpander<'a, 'b> {
+ pub extsbox: SyntaxEnv,
+ pub cx: &'a mut ExtCtxt<'b>,
}
-impl<'a> Folder for MacroExpander<'a> {
+impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr {
expand_expr(expr, self)
}
}
pub struct ExpansionConfig<'a> {
- loader: &'a mut CrateLoader,
- deriving_hash_type_parameter: bool,
+ pub loader: &'a mut CrateLoader,
+ pub deriving_hash_type_parameter: bool,
+ pub crate_id: CrateId,
}
-pub fn expand_crate(parse_sess: @parse::ParseSess,
+pub fn expand_crate(parse_sess: &parse::ParseSess,
cfg: ExpansionConfig,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
use ext::mtwt;
use parse;
use parse::token;
- use util::parser_testing::{string_to_crate_and_sess};
+ use util::parser_testing::{string_to_parser};
use util::parser_testing::{string_to_pat, strs_to_idents};
use visit;
use visit::Visitor;
- use std::vec_ng::Vec;
-
// a visitor that extracts the paths
// from a given thingy and puts them in a mutable
// array (passed in to the traversal)
fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
fail!("lolwut")
}
-
- fn get_exported_macros(&mut self, _: ast::CrateNum) -> Vec<~str> {
- fail!("lolwut")
- }
-
- fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
- fail!("lolwut")
- }
}
// these following tests are quite fragile, in that they don't test what
// make sure that macros can leave scope
#[should_fail]
#[test] fn macros_cant_escape_fns_test () {
- let src = ~"fn bogus() {macro_rules! z (() => (3+4))}\
- fn inty() -> int { z!() }";
+ let src = "fn bogus() {macro_rules! z (() => (3+4))}\
+ fn inty() -> int { z!() }".to_owned();
let sess = parse::new_parse_sess();
let crate_ast = parse::parse_crate_from_source_str(
- ~"<test>",
+ "<test>".to_owned(),
src,
- Vec::new(),sess);
+ Vec::new(), &sess);
// should fail:
let mut loader = ErrLoader;
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
+ crate_id: from_str("test").unwrap(),
};
- expand_crate(sess,cfg,crate_ast);
+ expand_crate(&sess,cfg,crate_ast);
}
// make sure that macros can leave scope for modules
#[should_fail]
#[test] fn macros_cant_escape_mods_test () {
- let src = ~"mod foo {macro_rules! z (() => (3+4))}\
- fn inty() -> int { z!() }";
+ let src = "mod foo {macro_rules! z (() => (3+4))}\
+ fn inty() -> int { z!() }".to_owned();
let sess = parse::new_parse_sess();
let crate_ast = parse::parse_crate_from_source_str(
- ~"<test>",
+ "<test>".to_owned(),
src,
- Vec::new(),sess);
+ Vec::new(), &sess);
// should fail:
let mut loader = ErrLoader;
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
+ crate_id: from_str("test").unwrap(),
};
- expand_crate(sess,cfg,crate_ast);
+ expand_crate(&sess,cfg,crate_ast);
}
// macro_escape modules shouldn't cause macros to leave scope
#[test] fn macros_can_escape_flattened_mods_test () {
- let src = ~"#[macro_escape] mod foo {macro_rules! z (() => (3+4))}\
- fn inty() -> int { z!() }";
+ let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4))}\
+ fn inty() -> int { z!() }".to_owned();
let sess = parse::new_parse_sess();
let crate_ast = parse::parse_crate_from_source_str(
- ~"<test>",
+ "<test>".to_owned(),
src,
- Vec::new(), sess);
+ Vec::new(), &sess);
// should fail:
let mut loader = ErrLoader;
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
+ crate_id: from_str("test").unwrap(),
};
- expand_crate(sess, cfg, crate_ast);
+ expand_crate(&sess, cfg, crate_ast);
}
#[test] fn test_contains_flatten (){
//}
fn expand_crate_str(crate_str: ~str) -> ast::Crate {
- let (crate_ast,ps) = string_to_crate_and_sess(crate_str);
+ let ps = parse::new_parse_sess();
+ let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
// the cfg argument actually does matter, here...
let mut loader = ErrLoader;
let cfg = ::syntax::ext::expand::ExpansionConfig {
loader: &mut loader,
deriving_hash_type_parameter: false,
+ crate_id: from_str("test").unwrap(),
};
- expand_crate(ps,cfg,crate_ast)
+ expand_crate(&ps,cfg,crate_ast)
}
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
//}
#[test] fn macro_tokens_should_match(){
- expand_crate_str(~"macro_rules! m((a)=>(13)) fn main(){m!(a);}");
+ expand_crate_str("macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_owned());
}
// renaming tests expand a crate and then check that the bindings match
}
#[test] fn fmt_in_macro_used_inside_module_macro() {
- let crate_str = ~"macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
+ let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))
foo_module!()
-";
+".to_owned();
let cr = expand_crate_str(crate_str);
// find the xx binding
let mut name_finder = new_name_finder(Vec::new());
#[test]
fn pat_idents(){
- let pat = string_to_pat(~"(a,Foo{x:c @ (b,9),y:Bar(4,d)})");
+ let pat = string_to_pat("(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_owned());
let mut pat_idents = new_name_finder(Vec::new());
pat_idents.visit_pat(pat, ());
assert_eq!(pat_idents.ident_accumulator,