提交 49686007 编写于 作者: J Jeffrey Seyfried

Refactor away `metadata::creader::Macros`.

上级 53de24bb
...@@ -148,17 +148,6 @@ enum LoadResult { ...@@ -148,17 +148,6 @@ enum LoadResult {
Loaded(Library), Loaded(Library),
} }
pub struct Macros {
pub macro_rules: Vec<ast::MacroDef>,
/// An array of pairs where the first element is the name of the custom
/// derive (e.g. the trait being derived) and the second element is the
/// index of the definition.
pub custom_derive_registrar: Option<DefIndex>,
pub svh: Svh,
pub dylib: Option<PathBuf>,
}
impl<'a> CrateLoader<'a> { impl<'a> CrateLoader<'a> {
pub fn new(sess: &'a Session, pub fn new(sess: &'a Session,
cstore: &'a CStore, cstore: &'a CStore,
...@@ -554,18 +543,13 @@ fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> Extens ...@@ -554,18 +543,13 @@ fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> Extens
} }
} }
pub fn read_macros(&mut self, item: &ast::Item) -> Macros { pub fn read_macros(&mut self, item: &ast::Item) -> LoadedMacros {
let ci = self.extract_crate_info(item).unwrap(); let ci = self.extract_crate_info(item).unwrap();
let ekrate = self.read_extension_crate(item.span, &ci); let ekrate = self.read_extension_crate(item.span, &ci);
let root = ekrate.metadata.get_root(); let root = ekrate.metadata.get_root();
let source_name = format!("<{} macros>", item.ident); let source_name = format!("<{} macros>", item.ident);
let mut ret = Macros { let mut macro_rules = Vec::new();
macro_rules: Vec::new(),
custom_derive_registrar: None,
svh: root.hash,
dylib: None,
};
for def in root.macro_defs.decode(&*ekrate.metadata) { for def in root.macro_defs.decode(&*ekrate.metadata) {
// NB: Don't use parse::parse_tts_from_source_str because it parses with // NB: Don't use parse::parse_tts_from_source_str because it parses with
// quote_depth > 0. // quote_depth > 0.
...@@ -589,7 +573,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros { ...@@ -589,7 +573,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
attr::mark_used(attr); attr::mark_used(attr);
} }
ret.macro_rules.push(ast::MacroDef { macro_rules.push(ast::MacroDef {
ident: ast::Ident::with_empty_ctxt(def.name), ident: ast::Ident::with_empty_ctxt(def.name),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span: local_span, span: local_span,
...@@ -602,9 +586,24 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros { ...@@ -602,9 +586,24 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
.insert(local_span, (def.name.as_str().to_string(), def.span)); .insert(local_span, (def.name.as_str().to_string(), def.span));
} }
match root.macro_derive_registrar { if let Some(id) = root.macro_derive_registrar {
Some(id) => ret.custom_derive_registrar = Some(id), let dylib = match ekrate.dylib.clone() {
Some(dylib) => dylib,
None => span_bug!(item.span, "proc-macro crate not dylib"),
};
if ekrate.target_only {
let message = format!("proc-macro crate is not available for \
triple `{}` (only found {})",
config::host_triple(),
self.sess.opts.target_triple);
self.sess.span_fatal(item.span, &message);
}
// custom derive crates currently should not have any macro_rules!
// exported macros, enforced elsewhere
assert_eq!(macro_rules.len(), 0);
LoadedMacros::ProcMacros(self.load_derive_macros(item, id, root.hash, dylib))
} else {
// If this crate is not a proc-macro crate then we might be able to // If this crate is not a proc-macro crate then we might be able to
// register it with the local crate store to prevent loading the // register it with the local crate store to prevent loading the
// metadata twice. // metadata twice.
...@@ -612,27 +611,9 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros { ...@@ -612,27 +611,9 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
// If it's a proc-macro crate, though, then we definitely don't // If it's a proc-macro crate, though, then we definitely don't
// want to register it with the local crate store as we're just // want to register it with the local crate store as we're just
// going to use it as we would a plugin. // going to use it as we would a plugin.
None => { ekrate.register(self);
ekrate.register(self); LoadedMacros::MacroRules(macro_rules)
return ret
}
}
self.cstore.add_used_for_derive_macros(item);
ret.dylib = ekrate.dylib.clone();
if ret.dylib.is_none() {
span_bug!(item.span, "proc-macro crate not dylib");
} }
if ekrate.target_only {
let message = format!("proc-macro crate is not available for \
triple `{}` (only found {})",
config::host_triple(),
self.sess.opts.target_triple);
self.sess.span_fatal(item.span, &message);
}
return ret
} }
/// Load custom derive macros. /// Load custom derive macros.
...@@ -642,7 +623,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros { ...@@ -642,7 +623,7 @@ pub fn read_macros(&mut self, item: &ast::Item) -> Macros {
/// implemented as dynamic libraries, but we have a possible future where /// implemented as dynamic libraries, but we have a possible future where
/// custom derive (and other macro-1.1 style features) are implemented via /// custom derive (and other macro-1.1 style features) are implemented via
/// executables and custom IPC. /// executables and custom IPC.
fn load_derive_macros(&mut self, span: Span, macros: &Macros, index: DefIndex) fn load_derive_macros(&mut self, item: &ast::Item, index: DefIndex, svh: Svh, path: PathBuf)
-> Vec<(ast::Name, SyntaxExtension)> { -> Vec<(ast::Name, SyntaxExtension)> {
use std::{env, mem}; use std::{env, mem};
use proc_macro::TokenStream; use proc_macro::TokenStream;
...@@ -650,19 +631,20 @@ fn load_derive_macros(&mut self, span: Span, macros: &Macros, index: DefIndex) ...@@ -650,19 +631,20 @@ fn load_derive_macros(&mut self, span: Span, macros: &Macros, index: DefIndex)
use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::dynamic_lib::DynamicLibrary;
use syntax_ext::deriving::custom::CustomDerive; use syntax_ext::deriving::custom::CustomDerive;
self.cstore.add_used_for_derive_macros(item);
// Make sure the path contains a / or the linker will search for it. // Make sure the path contains a / or the linker will search for it.
let path = macros.dylib.as_ref().unwrap();
let path = env::current_dir().unwrap().join(path); let path = env::current_dir().unwrap().join(path);
let lib = match DynamicLibrary::open(Some(&path)) { let lib = match DynamicLibrary::open(Some(&path)) {
Ok(lib) => lib, Ok(lib) => lib,
Err(err) => self.sess.span_fatal(span, &err), Err(err) => self.sess.span_fatal(item.span, &err),
}; };
let sym = self.sess.generate_derive_registrar_symbol(&macros.svh, index); let sym = self.sess.generate_derive_registrar_symbol(&svh, index);
let registrar = unsafe { let registrar = unsafe {
let sym = match lib.symbol(&sym) { let sym = match lib.symbol(&sym) {
Ok(f) => f, Ok(f) => f,
Err(err) => self.sess.span_fatal(span, &err), Err(err) => self.sess.span_fatal(item.span, &err),
}; };
mem::transmute::<*mut u8, fn(&mut Registry)>(sym) mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
}; };
...@@ -1079,16 +1061,6 @@ fn process_item(&mut self, item: &ast::Item, definitions: &hir_map::Definitions) ...@@ -1079,16 +1061,6 @@ fn process_item(&mut self, item: &ast::Item, definitions: &hir_map::Definitions)
} }
fn load_macros(&mut self, extern_crate: &ast::Item) -> LoadedMacros { fn load_macros(&mut self, extern_crate: &ast::Item) -> LoadedMacros {
let macros = self.read_macros(extern_crate); self.read_macros(extern_crate)
if let Some(index) = macros.custom_derive_registrar {
// custom derive crates currently should not have any macro_rules!
// exported macros, enforced elsewhere
assert_eq!(macros.macro_rules.len(), 0);
let custom_derives = self.load_derive_macros(extern_crate.span, &macros, index);
LoadedMacros::ProcMacros(custom_derives)
} else {
LoadedMacros::MacroRules(macros.macro_rules)
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册