Allow selective macro import
This commit is contained in:
parent
0816255c80
commit
aa69cbde82
19 changed files with 299 additions and 8 deletions
|
@ -552,7 +552,10 @@ impl<'a> PluginMetadata<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: span,
|
span: span,
|
||||||
imported_from: imported_from,
|
imported_from: imported_from,
|
||||||
export: false, // overridden in plugin/load.rs
|
// overridden in plugin/load.rs
|
||||||
|
export: false,
|
||||||
|
use_locally: false,
|
||||||
|
|
||||||
body: body,
|
body: body,
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
|
|
@ -87,8 +87,8 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the attributes relating to macro / plugin loading.
|
// Parse the attributes relating to macro / plugin loading.
|
||||||
let mut load_macros = false;
|
|
||||||
let mut load_registrar = false;
|
let mut load_registrar = false;
|
||||||
|
let mut macro_selection = Some(HashSet::new()); // None => load all
|
||||||
let mut reexport = HashSet::new();
|
let mut reexport = HashSet::new();
|
||||||
for attr in vi.attrs.iter() {
|
for attr in vi.attrs.iter() {
|
||||||
let mut used = true;
|
let mut used = true;
|
||||||
|
@ -98,7 +98,22 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||||
#[macro_use], #[plugin], and/or #[no_link]");
|
#[macro_use], #[plugin], and/or #[no_link]");
|
||||||
}
|
}
|
||||||
"plugin" => load_registrar = true,
|
"plugin" => load_registrar = true,
|
||||||
"macro_use" => load_macros = true,
|
"macro_use" => {
|
||||||
|
let names = attr.meta_item_list();
|
||||||
|
if names.is_none() {
|
||||||
|
// no names => load all
|
||||||
|
macro_selection = None;
|
||||||
|
}
|
||||||
|
if let (Some(sel), Some(names)) = (macro_selection.as_mut(), names) {
|
||||||
|
for name in names.iter() {
|
||||||
|
if let ast::MetaWord(ref name) = name.node {
|
||||||
|
sel.insert(name.clone());
|
||||||
|
} else {
|
||||||
|
self.sess.span_err(name.span, "bad macro import");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
"macro_reexport" => {
|
"macro_reexport" => {
|
||||||
let names = match attr.meta_item_list() {
|
let names = match attr.meta_item_list() {
|
||||||
Some(names) => names,
|
Some(names) => names,
|
||||||
|
@ -126,6 +141,11 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||||
let mut macros = vec![];
|
let mut macros = vec![];
|
||||||
let mut registrar = None;
|
let mut registrar = None;
|
||||||
|
|
||||||
|
let load_macros = match macro_selection.as_ref() {
|
||||||
|
Some(sel) => sel.len() != 0 || reexport.len() != 0,
|
||||||
|
None => true,
|
||||||
|
};
|
||||||
|
|
||||||
if load_macros || load_registrar {
|
if load_macros || load_registrar {
|
||||||
let pmd = self.reader.read_plugin_metadata(vi);
|
let pmd = self.reader.read_plugin_metadata(vi);
|
||||||
if load_macros {
|
if load_macros {
|
||||||
|
@ -137,9 +157,12 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for mut def in macros.into_iter() {
|
for mut def in macros.into_iter() {
|
||||||
if reexport.contains(&token::get_ident(def.ident)) {
|
let name = token::get_ident(def.ident);
|
||||||
def.export = true;
|
def.use_locally = match macro_selection.as_ref() {
|
||||||
}
|
None => true,
|
||||||
|
Some(sel) => sel.contains(&name),
|
||||||
|
};
|
||||||
|
def.export = reexport.contains(&name);
|
||||||
self.plugins.macros.push(def);
|
self.plugins.macros.push(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1709,6 +1709,7 @@ pub struct MacroDef {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub imported_from: Option<Ident>,
|
pub imported_from: Option<Ident>,
|
||||||
pub export: bool,
|
pub export: bool,
|
||||||
|
pub use_locally: bool,
|
||||||
pub body: Vec<TokenTree>,
|
pub body: Vec<TokenTree>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -574,8 +574,10 @@ impl<'a> ExtCtxt<'a> {
|
||||||
if def.export {
|
if def.export {
|
||||||
self.exported_macros.push(def.clone());
|
self.exported_macros.push(def.clone());
|
||||||
}
|
}
|
||||||
let ext = macro_rules::compile(self, &def);
|
if def.use_locally {
|
||||||
self.syntax_env.insert(def.ident.name, ext);
|
let ext = macro_rules::compile(self, &def);
|
||||||
|
self.syntax_env.insert(def.ident.name, ext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit `msg` attached to `sp`, and stop compilation immediately.
|
/// Emit `msg` attached to `sp`, and stop compilation immediately.
|
||||||
|
|
|
@ -636,6 +636,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
|
||||||
span: it.span,
|
span: it.span,
|
||||||
imported_from: None,
|
imported_from: None,
|
||||||
export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
|
export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
|
||||||
|
use_locally: true,
|
||||||
body: tts,
|
body: tts,
|
||||||
};
|
};
|
||||||
fld.cx.insert_macro(def);
|
fld.cx.insert_macro(def);
|
||||||
|
|
15
src/test/auxiliary/macro_reexport_2_no_use.rs
Normal file
15
src/test/auxiliary/macro_reexport_2_no_use.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#![crate_type = "dylib"]
|
||||||
|
|
||||||
|
#[macro_reexport(reexported)]
|
||||||
|
#[no_link]
|
||||||
|
extern crate macro_reexport_1;
|
19
src/test/auxiliary/two_macros.rs
Normal file
19
src/test/auxiliary/two_macros.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// force-host
|
||||||
|
|
||||||
|
#![feature(macro_rules)]
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! macro_one { () => ("one") }
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! macro_two { () => ("two") }
|
19
src/test/compile-fail/empty-macro-use.rs
Normal file
19
src/test/compile-fail/empty-macro-use.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use()]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_two!(); //~ ERROR macro undefined
|
||||||
|
}
|
20
src/test/compile-fail/macro-reexport-not-locally-visible.rs
Normal file
20
src/test/compile-fail/macro-reexport-not-locally-visible.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:macro_reexport_1.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_reexport(reexported)]
|
||||||
|
#[no_link]
|
||||||
|
extern crate macro_reexport_1;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(reexported!(), 3u); //~ ERROR macro undefined
|
||||||
|
}
|
15
src/test/compile-fail/macro-use-bad-args-1.rs
Normal file
15
src/test/compile-fail/macro-use-bad-args-1.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#[macro_use(foo(bar))] //~ ERROR bad macro import
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
15
src/test/compile-fail/macro-use-bad-args-2.rs
Normal file
15
src/test/compile-fail/macro-use-bad-args-2.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#[macro_use(foo="bar")] //~ ERROR bad macro import
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
19
src/test/compile-fail/macro-use-wrong-name.rs
Normal file
19
src/test/compile-fail/macro-use-wrong-name.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use(macro_one)]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_two!(); //~ ERROR macro undefined
|
||||||
|
}
|
18
src/test/compile-fail/missing-macro-use.rs
Normal file
18
src/test/compile-fail/missing-macro-use.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_two!(); //~ ERROR macro undefined
|
||||||
|
}
|
20
src/test/run-pass/macro-reexport-no-intermediate-use.rs
Normal file
20
src/test/run-pass/macro-reexport-no-intermediate-use.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:macro_reexport_1.rs
|
||||||
|
// aux-build:macro_reexport_2_no_use.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use] #[no_link]
|
||||||
|
extern crate macro_reexport_2_no_use;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(reexported!(), 3u);
|
||||||
|
}
|
21
src/test/run-pass/macro-use-all-and-none.rs
Normal file
21
src/test/run-pass/macro-use-all-and-none.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
#[macro_use()]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_one!();
|
||||||
|
macro_two!();
|
||||||
|
}
|
20
src/test/run-pass/macro-use-all.rs
Normal file
20
src/test/run-pass/macro-use-all.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_one!();
|
||||||
|
macro_two!();
|
||||||
|
}
|
20
src/test/run-pass/macro-use-both.rs
Normal file
20
src/test/run-pass/macro-use-both.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use(macro_one, macro_two)]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_one!();
|
||||||
|
macro_two!();
|
||||||
|
}
|
19
src/test/run-pass/macro-use-one.rs
Normal file
19
src/test/run-pass/macro-use-one.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use(macro_two)]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_two!();
|
||||||
|
}
|
21
src/test/run-pass/two-macro-use.rs
Normal file
21
src/test/run-pass/two-macro-use.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// aux-build:two_macros.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#[macro_use(macro_one)]
|
||||||
|
#[macro_use(macro_two)]
|
||||||
|
extern crate two_macros;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
macro_one!();
|
||||||
|
macro_two!();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue