diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7677ccf8bf40c..fa0e5a88f80e0 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -13,16 +13,19 @@ use std::iter::once; use syntax::ast; -use rustc::hir; +use syntax::ext::base::MacroKind; +use syntax_pos::Span; +use rustc::hir; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; +use rustc::middle::cstore::LoadedMacro; use rustc::ty; use rustc::util::nodemap::FxHashSet; use core::{DocContext, DocAccessLevels}; use doctree; -use clean::{self, GetDefId, get_auto_traits_with_def_id}; +use clean::{self, GetDefId, ToSource, get_auto_traits_with_def_id}; use super::Clean; @@ -97,9 +100,12 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa record_extern_fqn(cx, did, clean::TypeKind::Const); clean::ConstantItem(build_const(cx, did)) } - // Macros are eagerly inlined back in visit_ast, don't show their export statements - // FIXME(50647): the eager inline does not take doc(hidden)/doc(no_inline) into account - Def::Macro(..) => return Some(Vec::new()), + // FIXME(misdreavus): if attributes/derives come down here we should probably document them + // separately + Def::Macro(did, MacroKind::Bang) => { + record_extern_fqn(cx, did, clean::TypeKind::Macro); + clean::MacroItem(build_macro(cx, did, name)) + } _ => return None, }; cx.renderinfo.borrow_mut().inlined.insert(did); @@ -460,6 +466,33 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static { } } +fn build_macro(cx: &DocContext, did: DefId, name: ast::Name) -> clean::Macro { + let imported_from = cx.tcx.original_crate_name(did.krate); + let def = match cx.cstore.load_macro_untracked(did, cx.sess()) { + LoadedMacro::MacroDef(macro_def) => macro_def, + // FIXME(jseyfried): document proc macro re-exports + LoadedMacro::ProcMacro(..) => panic!("attempting to document proc-macro re-export"), + }; + + let matchers: hir::HirVec = if let ast::ItemKind::MacroDef(ref def) = def.node { + let tts: Vec<_> = def.stream().into_trees().collect(); + tts.chunks(4).map(|arm| arm[0].span()).collect() + } else { + unreachable!() + }; + + let source = format!("macro_rules! {} {{\n{}}}", + name.clean(cx), + matchers.iter().map(|span| { + format!(" {} => {{ ... }};\n", span.to_src(cx)) + }).collect::()); + + clean::Macro { + source, + imported_from: Some(imported_from).clean(cx), + } +} + /// A trait's generics clause actually contains all of the predicates for all of /// its associated types as well. We specifically move these clauses to the /// associated types instead when displaying, so when we're generating the diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index fdeba93990d1c..2fb69b2cee018 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -21,9 +21,8 @@ use syntax_pos::{self, Span}; use rustc::hir::map as hir_map; use rustc::hir::def::Def; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::middle::cstore::{LoadedMacro, CrateStore}; +use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevel; -use rustc::ty::Visibility; use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::hir; @@ -212,44 +211,6 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { self.visit_item(item, None, &mut om); } self.inside_public_path = orig_inside_public_path; - let def_id = self.cx.tcx.hir.local_def_id(id); - if let Some(exports) = self.cx.tcx.module_exports(def_id) { - for export in exports.iter().filter(|e| e.vis == Visibility::Public) { - if let Def::Macro(def_id, ..) = export.def { - // FIXME(50647): this eager macro inlining does not take - // doc(hidden)/doc(no_inline) into account - if def_id.krate == LOCAL_CRATE { - continue // These are `krate.exported_macros`, handled in `self.visit()`. - } - - let imported_from = self.cx.tcx.original_crate_name(def_id.krate); - let def = match self.cstore.load_macro_untracked(def_id, self.cx.sess()) { - LoadedMacro::MacroDef(macro_def) => macro_def, - // FIXME(jseyfried): document proc macro re-exports - LoadedMacro::ProcMacro(..) => continue, - }; - - let matchers = if let ast::ItemKind::MacroDef(ref def) = def.node { - let tts: Vec<_> = def.stream().into_trees().collect(); - tts.chunks(4).map(|arm| arm[0].span()).collect() - } else { - unreachable!() - }; - - debug!("inlining macro {}", def.ident.name); - om.macros.push(Macro { - def_id, - attrs: def.attrs.clone().into(), - name: def.ident.name, - whence: self.cx.tcx.def_span(def_id), - matchers, - stab: self.cx.tcx.lookup_stability(def_id).cloned(), - depr: self.cx.tcx.lookup_deprecation(def_id), - imported_from: Some(imported_from), - }) - } - } - } om } diff --git a/src/test/rustdoc/cross-crate-links.rs b/src/test/rustdoc/cross-crate-links.rs index 6078352fc0e09..15a774dc9353d 100644 --- a/src/test/rustdoc/cross-crate-links.rs +++ b/src/test/rustdoc/cross-crate-links.rs @@ -66,6 +66,6 @@ pub use all_item_types::FOO_STATIC; #[doc(no_inline)] pub use all_item_types::FOO_CONSTANT; -// @has 'foo/index.html' '//a[@href="../foo/macro.foo_macro.html"]' 'foo_macro' +// @has 'foo/index.html' '//a[@href="../all_item_types/macro.foo_macro.html"]' 'foo_macro' #[doc(no_inline)] pub use all_item_types::foo_macro; diff --git a/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs b/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs new file mode 100644 index 0000000000000..d4a9a9f379b92 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs @@ -0,0 +1,35 @@ +// Copyright 2012-2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "qwop"] + +/// (writen on a spider's web) Some Macro +#[macro_export] +macro_rules! some_macro { + () => { + println!("this is some macro, for sure"); + }; +} + +/// Some other macro, to fill space. +#[macro_export] +macro_rules! other_macro { + () => { + println!("this is some other macro, whatev"); + }; +} + +/// This macro is so cool, it's Super. +#[macro_export] +macro_rules! super_macro { + () => { + println!("is it a bird? a plane? no, it's Super Macro!"); + }; +} diff --git a/src/test/rustdoc/inline_cross/macro-vis.rs b/src/test/rustdoc/inline_cross/macro-vis.rs new file mode 100644 index 0000000000000..6de13338dd376 --- /dev/null +++ b/src/test/rustdoc/inline_cross/macro-vis.rs @@ -0,0 +1,48 @@ +// Copyright 2012-2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:macro-vis.rs +// build-aux-docs +// ignore-cross-compile + +#![feature(use_extern_macros)] + +#[macro_use] extern crate qwop; + +// @has macro_vis/macro.some_macro.html +// @has macro_vis/index.html '//a/@href' 'macro.some_macro.html' +pub use qwop::some_macro; + +// @has macro_vis/macro.renamed_macro.html +// @!has - '//pre' 'some_macro' +// @has macro_vis/index.html '//a/@href' 'macro.renamed_macro.html' +#[doc(inline)] +pub use qwop::some_macro as renamed_macro; + +// @!has macro_vis/macro.other_macro.html +// @!has macro_vis/index.html '//a/@href' 'macro.other_macro.html' +// @!has - '//code' 'pub use qwop::other_macro;' +#[doc(hidden)] +pub use qwop::other_macro; + +// @has macro_vis/index.html '//code' 'pub use qwop::super_macro;' +// @!has macro_vis/macro.super_macro.html +#[doc(no_inline)] +pub use qwop::super_macro; + +// @has macro_vis/macro.this_is_dope.html +// @has macro_vis/index.html '//a/@href' 'macro.this_is_dope.html' +/// What it says on the tin. +#[macro_export] +macro_rules! this_is_dope { + () => { + println!("yo check this out"); + }; +} diff --git a/src/test/rustdoc/pub-use-extern-macros.rs b/src/test/rustdoc/pub-use-extern-macros.rs index a6e707cc2adea..13957fd6a7022 100644 --- a/src/test/rustdoc/pub-use-extern-macros.rs +++ b/src/test/rustdoc/pub-use-extern-macros.rs @@ -23,7 +23,7 @@ pub use macros::bar; #[doc(inline)] pub use macros::baz; -// @has pub_use_extern_macros/macro.quux.html +// @!has pub_use_extern_macros/macro.quux.html // @!has pub_use_extern_macros/index.html '//code' 'pub use macros::quux;' #[doc(hidden)] pub use macros::quux;