From f1ad425199b0d89dab275a8c8f6f29a73d316f70 Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 10 Jul 2014 15:41:11 -0700 Subject: [PATCH] use side table to store exported macros Per discussion with @sfackler, refactored the expander to change the way that exported macros are collected. Specifically, a crate now contains a side table of spans that exported macros go into. This has two benefits. First, the encoder doesn't need to scan through the expanded crate in order to discover exported macros. Second, the expander can drop all expanded macros from the crate, with the pleasant result that a fully expanded crate contains no macro invocations (which include macro definitions). --- src/librustc/driver/session.rs | 3 ++- src/librustc/metadata/encoder.rs | 44 ++++++++++++-------------------- src/libsyntax/ast.rs | 2 ++ src/libsyntax/ext/base.rs | 7 ++++- src/libsyntax/ext/expand.rs | 9 ++++--- src/libsyntax/fold.rs | 1 + src/libsyntax/parse/parser.rs | 3 ++- 7 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 50f61f8f06a..946aa62f91c 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -28,7 +28,8 @@ use syntax::{ast, codemap}; use std::os; use std::cell::{Cell, RefCell}; - +// Represents the data associated with a compilation +// session for a single crate. pub struct Session { pub targ_cfg: config::Config, pub opts: config::Options, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index fbf0288418a..7c4eda6dd71 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1584,37 +1584,25 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) { } } -struct MacroDefVisitor<'a, 'b, 'c> { - ecx: &'a EncodeContext<'b>, - ebml_w: &'a mut Encoder<'c> +/// Given a span, write the text of that span into the output stream +/// as an exported macro +fn encode_macro_def(ecx: &EncodeContext, + ebml_w: &mut Encoder, + span: &syntax::codemap::Span) { + let def = ecx.tcx.sess.codemap().span_to_snippet(*span) + .expect("Unable to find source for macro"); + ebml_w.start_tag(tag_macro_def); + ebml_w.wr_str(def.as_slice()); + ebml_w.end_tag(); } -impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> { - fn visit_item(&mut self, item: &Item, _: ()) { - match item.node { - ItemMac(..) => { - let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span) - .expect("Unable to find source for macro"); - self.ebml_w.start_tag(tag_macro_def); - self.ebml_w.wr_str(def.as_slice()); - self.ebml_w.end_tag(); - } - _ => {} - } - visit::walk_item(self, item, ()); - } -} - -fn encode_macro_defs<'a>(ecx: &'a EncodeContext, - krate: &Crate, - ebml_w: &'a mut Encoder) { +/// Serialize the text of the exported macros +fn encode_macro_defs(ecx: &EncodeContext, + krate: &Crate, + ebml_w: &mut Encoder) { ebml_w.start_tag(tag_exported_macros); - { - let mut visitor = MacroDefVisitor { - ecx: ecx, - ebml_w: ebml_w, - }; - visit::walk_crate(&mut visitor, krate, ()); + for span in krate.exported_macros.iter() { + encode_macro_def(ecx, ebml_w, span); } ebml_w.end_tag(); } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ebfc45d22ce..4a48d3f7028 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -249,6 +249,7 @@ pub struct Crate { pub attrs: Vec, pub config: CrateConfig, pub span: Span, + pub exported_macros: Vec } pub type MetaItem = Spanned; @@ -1245,6 +1246,7 @@ mod test { hi: BytePos(20), expn_info: None, }, + exported_macros: Vec::new(), }; // doesn't matter which encoder we use.... let _f = &e as &serialize::Encodable; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7ff680497bf..dcb69ae8f7e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -410,6 +410,7 @@ pub struct ExtCtxt<'a> { pub mod_path: Vec , pub trace_mac: bool, + pub exported_macros: Vec } impl<'a> ExtCtxt<'a> { @@ -421,7 +422,8 @@ impl<'a> ExtCtxt<'a> { backtrace: None, mod_path: Vec::new(), ecfg: ecfg, - trace_mac: false + trace_mac: false, + exported_macros: Vec::new(), } } @@ -539,6 +541,9 @@ impl<'a> ExtCtxt<'a> { pub fn name_of(&self, st: &str) -> ast::Name { token::intern(st) } + pub fn push_exported_macro(&mut self, span: codemap::Span) { + self.exported_macros.push(span); + } } /// Extract a string literal from the macro expanded version of `expr`, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b7d72ae4deb..e8a78e85d89 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -518,10 +518,9 @@ fn expand_item_mac(it: Gc, fld: &mut MacroExpander) // create issue to recommend refactoring here? fld.extsbox.insert(intern(name.as_slice()), ext); if attr::contains_name(it.attrs.as_slice(), "macro_export") { - SmallVector::one(it) - } else { - SmallVector::zero() + fld.cx.push_exported_macro(it.span); } + SmallVector::zero() } None => { match expanded.make_items() { @@ -1039,6 +1038,7 @@ pub struct ExportedMacros { pub fn expand_crate(parse_sess: &parse::ParseSess, cfg: ExpansionConfig, + // these are the macros being imported to this crate: macros: Vec, user_exts: Vec, c: Crate) -> Crate { @@ -1066,7 +1066,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, expander.extsbox.insert(name, extension); } - let ret = expander.fold_crate(c); + let mut ret = expander.fold_crate(c); + ret.exported_macros = expander.cx.exported_macros.clone(); parse_sess.span_diagnostic.handler().abort_if_errors(); return ret; } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index bcdf920e5dd..f7cb1ae1934 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -713,6 +713,7 @@ pub fn noop_fold_crate(c: Crate, folder: &mut T) -> Crate { attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(), config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(), span: folder.new_span(c.span), + exported_macros: c.exported_macros.iter().map(|sp| folder.new_span(*sp)).collect(), } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 743eeed9da5..84db2bc5a22 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5386,7 +5386,8 @@ impl<'a> Parser<'a> { module: m, attrs: inner, config: self.cfg.clone(), - span: mk_sp(lo, self.span.lo) + span: mk_sp(lo, self.span.lo), + exported_macros: Vec::new(), } }