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;
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);
}
}
+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
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;
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
}
--- /dev/null
+// 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!");
+ };
+}
--- /dev/null
+// 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");
+ };
+}