id: ast::DUMMY_NODE_ID,
span: span,
imported_from: imported_from,
+ export: false, // overridden in plugin/load.rs
body: body,
});
true
use std::mem;
use std::os;
use std::dynamic_lib::DynamicLibrary;
+use std::collections::HashSet;
use syntax::ast;
use syntax::attr;
+use syntax::parse::token;
use syntax::visit;
use syntax::visit::Visitor;
use syntax::attr::AttrMetaMethods;
// Parse the attributes relating to macro / plugin loading.
let mut load_macros = false;
let mut load_registrar = false;
+ let mut reexport = HashSet::new();
for attr in vi.attrs.iter() {
let mut used = true;
match attr.name().get() {
}
"plugin" => load_registrar = true,
"macro_use" => load_macros = true,
+ "macro_reexport" => {
+ let names = match attr.meta_item_list() {
+ Some(names) => names,
+ None => {
+ self.sess.span_err(attr.span, "bad macro reexport");
+ continue;
+ }
+ };
+
+ for name in names.iter() {
+ if let ast::MetaWord(ref name) = name.node {
+ reexport.insert(name.clone());
+ } else {
+ self.sess.span_err(name.span, "bad macro reexport");
+ }
+ }
+ }
_ => used = false,
}
if used {
}
}
- self.plugins.macros.extend(macros.into_iter());
+ for mut def in macros.into_iter() {
+ if reexport.contains(&token::get_ident(def.ident)) {
+ def.export = true;
+ }
+ self.plugins.macros.push(def);
+ }
+
if let Some((lib, symbol)) = registrar {
self.dylink_registrar(vi, lib, symbol);
}
deriving_hash_type_parameter: sess.features.borrow().default_type_params,
enable_quotes: sess.features.borrow().quote,
recursion_limit: sess.recursion_limit.get(),
- reexported_macros: syntax::ext::tt::reexport::gather(sess.diagnostic(),
- &krate),
};
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
cfg,
#![reexport_test_harness_main = "test_main"]
-#![macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
- unreachable, unimplemented, write, writeln, vec)]
-
#[cfg(all(test, stage0))]
#[phase(plugin, link)]
extern crate log;
#[cfg(not(stage0))]
#[macro_use]
+#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
+ unreachable, unimplemented, write, writeln)]
extern crate core;
#[cfg(stage0)]
#[cfg(not(stage0))]
#[macro_use]
+#[macro_reexport(vec)]
extern crate "collections" as core_collections;
extern crate "rand" as core_rand;
pub id: NodeId,
pub span: Span,
pub imported_from: Option<Ident>,
+ pub export: bool,
pub body: Vec<TokenTree>,
}
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
use ext;
use ext::expand;
+use ext::tt::macro_rules;
use parse;
use parse::parser;
use parse::token;
}
}
}
+
+ pub fn insert_macro(&mut self, def: ast::MacroDef) {
+ if def.export {
+ self.exported_macros.push(def.clone());
+ }
+ let ext = macro_rules::compile(self, &def);
+ self.syntax_env.insert(def.ident.name, ext);
+ }
+
/// Emit `msg` attached to `sp`, and stop compilation immediately.
///
/// `span_err` should be strongly preferred where-ever possible:
use ast_util::path_to_ident;
use ext::mtwt;
use ext::build::AstBuilder;
-use ext::tt::macro_rules;
use attr;
use attr::AttrMetaMethods;
use codemap;
id: ast::DUMMY_NODE_ID,
span: it.span,
imported_from: None,
+ export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
body: tts,
};
- let ext = macro_rules::compile(fld.cx, &def);
- fld.cx.syntax_env.insert(def.ident.name, ext);
-
- if attr::contains_name(def.attrs.as_slice(), "macro_export") {
- fld.cx.exported_macros.push(def);
- }
+ fld.cx.insert_macro(def);
// macro_rules! has a side effect but expands to nothing.
fld.cx.bt_pop();
pub deriving_hash_type_parameter: bool,
pub enable_quotes: bool,
pub recursion_limit: uint,
- pub reexported_macros: Vec<String>,
}
impl ExpansionConfig {
deriving_hash_type_parameter: false,
enable_quotes: false,
recursion_limit: 64,
- reexported_macros: vec![],
}
}
}
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
let mut expander = MacroExpander::new(&mut cx);
- for def in imported_macros.iter() {
- let ext = macro_rules::compile(expander.cx, def);
- expander.cx.syntax_env.insert(def.ident.name, ext);
-
- if expander.cx.ecfg.reexported_macros.iter()
- .any(|e| e[] == token::get_ident(def.ident).get()) {
-
- expander.cx.exported_macros.push(def.clone());
- }
+ for def in imported_macros.into_iter() {
+ expander.cx.insert_macro(def);
}
for (name, extension) in user_exts.into_iter() {
+++ /dev/null
-// Copyright 2014 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.
-
-//! Defines the crate attribute syntax for macro re-export.
-
-use ast;
-use attr::AttrMetaMethods;
-use diagnostic::SpanHandler;
-
-/// Return a vector of the names of all macros re-exported from the crate.
-pub fn gather(diag: &SpanHandler, krate: &ast::Crate) -> Vec<String> {
- let usage = "malformed macro_reexport attribute, expected \
- #![macro_reexport(ident, ident, ...)]";
-
- let mut reexported: Vec<String> = vec!();
- for attr in krate.attrs.iter() {
- if !attr.check_name("macro_reexport") {
- continue;
- }
-
- match attr.meta_item_list() {
- None => diag.span_err(attr.span, usage),
- Some(list) => for mi in list.iter() {
- match mi.node {
- ast::MetaWord(ref word)
- => reexported.push(word.to_string()),
- _ => diag.span_err(mi.span, usage),
- }
- }
- }
- }
-
- reexported
-}
pub mod transcribe;
pub mod macro_parser;
pub mod macro_rules;
- pub mod reexport;
}
}
#![crate_type = "dylib"]
-#![macro_reexport(reexported)]
-
+#[macro_reexport(reexported)]
#[macro_use] #[no_link]
extern crate macro_reexport_1;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_reexport] //~ ERROR malformed macro_reexport attribute
+#[macro_reexport] //~ ERROR bad macro reexport
+extern crate std;
fn main() { }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_reexport="foo"] //~ ERROR malformed macro_reexport attribute
+#[macro_reexport="foo"] //~ ERROR bad macro reexport
+extern crate std;
fn main() { }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_reexport(foo="bar")] //~ ERROR malformed macro_reexport attribute
+#[macro_reexport(foo="bar")] //~ ERROR bad macro reexport
+extern crate std;
fn main() { }