From 6226ce56c1d555e3722ae301a9f12bdec49f20d0 Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 17 Jul 2014 09:45:31 -0700 Subject: [PATCH] repair macro docs In f1ad425199b0d89dab275a8c8f6f29a73d316f70, I changed the handling of macros, to prevent macro invocations from occurring in fully expanded source. Instead, I added a side table. It contained only the spans of the macros, because this was the only information required in order to make macro export work. However, librustdoc was also affected by this change, since it extracts macro information in a similar way. As a result of the earlier change, exported macros were no longer documented. In order to repair this, I've adjusted the side table to contain whole items, rather than just the spans. --- src/librustc/metadata/encoder.rs | 4 ++-- src/librustdoc/visit_ast.rs | 32 ++++++++++++++++++++++++-------- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/base.rs | 11 ++++------- src/libsyntax/ext/expand.rs | 6 +++--- src/libsyntax/fold.rs | 2 +- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index a3389ef86e551..5769c4c86ed78 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1612,8 +1612,8 @@ fn encode_macro_defs(ecx: &EncodeContext, krate: &Crate, ebml_w: &mut Encoder) { ebml_w.start_tag(tag_exported_macros); - for span in krate.exported_macros.iter() { - encode_macro_def(ecx, ebml_w, span); + for item in krate.exported_macros.iter() { + encode_macro_def(ecx, ebml_w, &item.span); } ebml_w.end_tag(); } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b7ef0956a7c76..b7460f1607431 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -26,6 +26,14 @@ use std::gc::{Gc, GC}; use core; use doctree::*; +// looks to me like the first two of these are actually +// output parameters, maybe only mutated once; perhaps +// better simply to have the visit method return a tuple +// containing them? + +// also, is there some reason that this doesn't use the 'visit' +// framework from syntax? + pub struct RustdocVisitor<'a> { pub module: Module, pub attrs: Vec, @@ -64,6 +72,9 @@ impl<'a> RustdocVisitor<'a> { ast::CRATE_NODE_ID, &krate.module, None); + // attach the crate's exported macros to the top-level module: + self.module.macros = krate.exported_macros.iter() + .map(|it| self.visit_macro(&**it)).collect(); self.module.is_crate = true; } @@ -323,15 +334,20 @@ impl<'a> RustdocVisitor<'a> { ast::ItemForeignMod(ref fm) => { om.foreigns.push(fm.clone()); } - ast::ItemMac(ref _m) => { - om.macros.push(Macro { - id: item.id, - attrs: item.attrs.iter().map(|x| *x).collect(), - name: item.ident, - where: item.span, - stab: self.stability(item.id), - }) + ast::ItemMac(_) => { + fail!("rustdoc: macros should be gone, after expansion"); } } } + + // convert each exported_macro into a doc item + fn visit_macro(&self, item: &ast::Item) -> Macro { + Macro { + id: item.id, + attrs: item.attrs.iter().map(|x| *x).collect(), + name: item.ident, + where: item.span, + stab: self.stability(item.id), + } + } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d9f14bfa15661..3b68953c40746 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -256,7 +256,7 @@ pub struct Crate { pub attrs: Vec, pub config: CrateConfig, pub span: Span, - pub exported_macros: Vec + pub exported_macros: Vec> } pub type MetaItem = Spanned; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 49bd3697884c7..5341f0c2d61b2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -104,9 +104,9 @@ pub type IdentMacroExpanderFn = /// just into the compiler's internal macro table, for `make_def`). pub trait MacResult { /// Define a new macro. - // this should go away; the idea that a macro might expand into - // either a macro definition or an expression, depending on what - // the context wants, is kind of silly. + // this particular flavor should go away; the idea that a macro might + // expand into either a macro definition or an expression, depending + // on what the context wants, is kind of silly. fn make_def(&self) -> Option { None } @@ -431,7 +431,7 @@ pub struct ExtCtxt<'a> { pub mod_path: Vec , pub trace_mac: bool, - pub exported_macros: Vec + pub exported_macros: Vec> } impl<'a> ExtCtxt<'a> { @@ -562,9 +562,6 @@ 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 1cbe863e4e4f9..1542bb06b94ab 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -536,7 +536,7 @@ 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") { - fld.cx.push_exported_macro(it.span); + fld.cx.exported_macros.push(it); } SmallVector::zero() } @@ -1031,7 +1031,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, + imported_macros: Vec, user_exts: Vec, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); @@ -1040,7 +1040,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, cx: &mut cx, }; - for ExportedMacros { crate_name, macros } in macros.move_iter() { + for ExportedMacros { crate_name, macros } in imported_macros.move_iter() { let name = format!("<{} macros>", token::get_ident(crate_name)) .into_string(); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5467afab9f515..6406ca378074f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -751,7 +751,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(), + exported_macros: c.exported_macros } }