From: QuietMisdreavus Date: Sun, 17 Jun 2018 19:54:28 +0000 (-0500) Subject: rustdoc: import cross-crate macros alongside everything else X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=d4387b3e4f9c6da5009154882051ff7b4862df07;p=rust.git rustdoc: import cross-crate macros alongside everything else --- diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 80eb2d1e214..8bcd1062667 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)) + } _ => return None, }; cx.renderinfo.borrow_mut().inlined.insert(did); @@ -457,6 +463,33 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static { } } +fn build_macro(cx: &DocContext, did: DefId) -> 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{}}}", + def.ident.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 44b41439511..70d0d078308 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -21,9 +21,8 @@ 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; @@ -215,44 +214,6 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec 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/inline_cross/auxiliary/macro-vis.rs b/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs new file mode 100644 index 00000000000..d4a9a9f379b --- /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 00000000000..4dde19f2a0a --- /dev/null +++ b/src/test/rustdoc/inline_cross/macro-vis.rs @@ -0,0 +1,42 @@ +// 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.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"); + }; +}