diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 152 | ||||
| -rw-r--r-- | src/libsyntax/ext/registrar.rs | 58 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 8 |
4 files changed, 41 insertions, 196 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 521b7ee0063..e81421cff04 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -95,9 +95,6 @@ impl IdentMacroExpander for BasicIdentMacroExpander { pub type IdentMacroExpanderFn = fn(&mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult>; -pub type MacroCrateRegistrationFun = - fn(|ast::Name, SyntaxExtension|); - /// The result of a macro expansion. The return values of the various /// methods are spliced into the AST at the callsite of the macro (or /// just into the compiler's internal macro table, for `make_def`). @@ -268,6 +265,8 @@ pub enum SyntaxExtension { IdentTT(Box<IdentMacroExpander:'static>, Option<Span>), } +pub type NamedSyntaxExtension = (Name, SyntaxExtension); + pub struct BlockInfo { // should macros escape from this scope? pub macros_escape: bool, @@ -392,16 +391,6 @@ pub fn syntax_expander_table() -> SyntaxEnv { syntax_expanders } -pub struct MacroCrate { - pub lib: Option<Path>, - pub macros: Vec<String>, - pub registrar_symbol: Option<String>, -} - -pub trait CrateLoader { - fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate; -} - // One of these is made during expansion and incrementally updated as we go; // when a macro expansion occurs, the resulting nodes have the backtrace() // -> expn_info of their expansion context stored into their span. @@ -409,7 +398,7 @@ pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, pub backtrace: Option<@ExpnInfo>, - pub ecfg: expand::ExpansionConfig<'a>, + pub ecfg: expand::ExpansionConfig, pub mod_path: Vec<ast::Ident> , pub trace_mac: bool, @@ -417,7 +406,7 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, - ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> { + ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 03001acc5d0..bb335e7bed0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -29,10 +29,6 @@ use visit; use visit::Visitor; use util::small_vector::SmallVector; -use std::mem; -use std::os; -use std::unstable::dynamic_lib::DynamicLibrary; - pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { match e.node { // expr_mac should really be expr_ext or something; it's the @@ -497,96 +493,6 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander) return items; } -// load macros from syntax-phase crates -pub fn expand_view_item(vi: &ast::ViewItem, - fld: &mut MacroExpander) - -> ast::ViewItem { - match vi.node { - ast::ViewItemExternCrate(..) => { - let should_load = vi.attrs.iter().any(|attr| { - attr.check_name("phase") && - attr.meta_item_list().map_or(false, |phases| { - attr::contains_name(phases, "syntax") - }) - }); - - if should_load { - load_extern_macros(vi, fld); - } - } - ast::ViewItemUse(_) => {} - } - - noop_fold_view_item(vi, fld) -} - -fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { - let MacroCrate { lib, macros, registrar_symbol } = - fld.cx.ecfg.loader.load_crate(krate); - - let crate_name = match krate.node { - ast::ViewItemExternCrate(name, _, _) => name, - _ => unreachable!() - }; - let name = format!("<{} macros>", token::get_ident(crate_name)); - let name = name.to_string(); - - for source in macros.iter() { - let item = parse::parse_item_from_source_str(name.clone(), - (*source).clone(), - fld.cx.cfg(), - fld.cx.parse_sess()) - .expect("expected a serialized item"); - expand_item_mac(item, fld); - } - - let path = match lib { - Some(path) => path, - None => return - }; - // Make sure the path contains a / or the linker will search for it. - let path = os::make_absolute(&path); - - let registrar = match registrar_symbol { - Some(registrar) => registrar, - None => return - }; - - debug!("load_extern_macros: mapped crate {} to path {} and registrar {:s}", - crate_name, path.display(), registrar); - - let lib = match DynamicLibrary::open(Some(&path)) { - Ok(lib) => lib, - // this is fatal: there are almost certainly macros we need - // inside this crate, so continue would spew "macro undefined" - // errors - Err(err) => fld.cx.span_fatal(krate.span, err.as_slice()) - }; - - unsafe { - let registrar: MacroCrateRegistrationFun = - match lib.symbol(registrar.as_slice()) { - Ok(registrar) => registrar, - // again fatal if we can't register macros - Err(err) => fld.cx.span_fatal(krate.span, err.as_slice()) - }; - registrar(|name, extension| { - let extension = match extension { - NormalTT(ext, _) => NormalTT(ext, Some(krate.span)), - IdentTT(ext, _) => IdentTT(ext, Some(krate.span)), - ItemDecorator(ext) => ItemDecorator(ext), - ItemModifier(ext) => ItemModifier(ext), - }; - fld.extsbox.insert(name, extension); - }); - - // Intentionally leak the dynamic library. We can't ever unload it - // since the library can do things that will outlive the expansion - // phase (e.g. make an @-box cycle or launch a task). - mem::forget(lib); - } -} - // expand a stmt pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> { // why the copying here and not in expand_expr? @@ -969,10 +875,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_item(item, self) } - fn fold_view_item(&mut self, vi: &ast::ViewItem) -> ast::ViewItem { - expand_view_item(vi, self) - } - fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> { expand_stmt(stmt, self) } @@ -986,14 +888,20 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } } -pub struct ExpansionConfig<'a> { - pub loader: &'a mut CrateLoader, +pub struct ExpansionConfig { pub deriving_hash_type_parameter: bool, pub crate_id: CrateId, } +pub struct ExportedMacros { + pub crate_name: Ident, + pub macros: Vec<String>, +} + pub fn expand_crate(parse_sess: &parse::ParseSess, cfg: ExpansionConfig, + macros: Vec<ExportedMacros>, + user_exts: Vec<NamedSyntaxExtension>, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); let mut expander = MacroExpander { @@ -1001,6 +909,24 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, cx: &mut cx, }; + for ExportedMacros { crate_name, macros } in macros.move_iter() { + let name = format!("<{} macros>", token::get_ident(crate_name)) + .into_string(); + + for source in macros.move_iter() { + let item = parse::parse_item_from_source_str(name.clone(), + source, + expander.cx.cfg(), + expander.cx.parse_sess()) + .expect("expected a serialized item"); + expand_item_mac(item, &mut expander); + } + } + + for (name, extension) in user_exts.move_iter() { + expander.extsbox.insert(name, extension); + } + let ret = expander.fold_crate(c); parse_sess.span_diagnostic.handler().abort_if_errors(); return ret; @@ -1093,7 +1019,6 @@ mod test { use attr; use codemap; use codemap::Spanned; - use ext::base::{CrateLoader, MacroCrate}; use ext::mtwt; use parse; use parse::token; @@ -1137,14 +1062,6 @@ mod test { } } - struct ErrLoader; - - impl CrateLoader for ErrLoader { - fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate { - fail!("lolwut") - } - } - // these following tests are quite fragile, in that they don't test what // *kind* of failure occurs. @@ -1159,13 +1076,11 @@ mod test { src, 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,vec!(),vec!(),crate_ast); } // make sure that macros can leave scope for modules @@ -1178,14 +1093,11 @@ mod test { "<test>".to_string(), src, 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,vec!(),vec!(),crate_ast); } // macro_escape modules shouldn't cause macros to leave scope @@ -1198,13 +1110,11 @@ mod test { src, 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, vec!(), vec!(), crate_ast); } #[test] fn test_contains_flatten (){ @@ -1237,13 +1147,11 @@ mod test { 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,vec!(),vec!(),crate_ast) } //fn expand_and_resolve(crate_str: @str) -> ast::crate { diff --git a/src/libsyntax/ext/registrar.rs b/src/libsyntax/ext/registrar.rs deleted file mode 100644 index b76708147e1..00000000000 --- a/src/libsyntax/ext/registrar.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast; -use attr; -use codemap::Span; -use diagnostic; -use visit; -use visit::Visitor; - -struct MacroRegistrarContext { - registrars: Vec<(ast::NodeId, Span)> , -} - -impl Visitor<()> for MacroRegistrarContext { - fn visit_item(&mut self, item: &ast::Item, _: ()) { - match item.node { - ast::ItemFn(..) => { - if attr::contains_name(item.attrs.as_slice(), - "macro_registrar") { - self.registrars.push((item.id, item.span)); - } - } - _ => {} - } - - visit::walk_item(self, item, ()); - } -} - -pub fn find_macro_registrar(diagnostic: &diagnostic::SpanHandler, - krate: &ast::Crate) -> Option<ast::NodeId> { - let mut ctx = MacroRegistrarContext { registrars: Vec::new() }; - visit::walk_crate(&mut ctx, krate, ()); - - match ctx.registrars.len() { - 0 => None, - 1 => { - let (node_id, _) = ctx.registrars.pop().unwrap(); - Some(node_id) - }, - _ => { - diagnostic.handler().err("multiple macro registration functions found"); - for &(_, span) in ctx.registrars.iter() { - diagnostic.span_note(span, "one is here"); - } - diagnostic.handler().abort_if_errors(); - unreachable!(); - } - } -} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 1ab420eb69b..754518f5fea 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -32,8 +32,15 @@ This API is completely unstable and subject to change. extern crate serialize; extern crate term; + +#[cfg(stage0)] #[phase(syntax, link)] extern crate log; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + extern crate fmt_macros; extern crate debug; @@ -74,7 +81,6 @@ pub mod ext { pub mod asm; pub mod base; pub mod expand; - pub mod registrar; pub mod quote; |
