Skip to content

Commit

Permalink
rustdoc: import cross-crate macros alongside everything else
Browse files Browse the repository at this point in the history
  • Loading branch information
QuietMisdreavus committed Jun 17, 2018
1 parent 499583a commit d4387b3
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 45 deletions.
43 changes: 38 additions & 5 deletions src/librustdoc/clean/inline.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<Span> = 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::<String>());

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
Expand Down
41 changes: 1 addition & 40 deletions src/librustdoc/visit_ast.rs
Expand Up @@ -21,9 +21,8 @@ use syntax_pos::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;
Expand Down Expand Up @@ -215,44 +214,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
}

Expand Down
35 changes: 35 additions & 0 deletions 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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!");
};
}
42 changes: 42 additions & 0 deletions 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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");
};
}

0 comments on commit d4387b3

Please sign in to comment.