1
Fork 0

handle proc-macros as macros instead of functions

This commit is contained in:
QuietMisdreavus 2018-09-25 14:56:43 -05:00
parent f49f6e73a8
commit aea1bd0a59
11 changed files with 241 additions and 48 deletions

View file

@ -105,15 +105,14 @@ 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))
}
// 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);
if let Some(mac) = build_macro(cx, did, name) {
clean::MacroItem(mac)
} else {
return None;
Def::Macro(did, mac_kind) => {
match mac_kind {
MacroKind::Bang => record_extern_fqn(cx, did, clean::TypeKind::Macro),
MacroKind::Attr => record_extern_fqn(cx, did, clean::TypeKind::Attr),
MacroKind::Derive => record_extern_fqn(cx, did, clean::TypeKind::Derive),
MacroKind::ProcMacroStub => return None,
}
build_macro(cx, did, name)
}
_ => return None,
};
@ -442,31 +441,35 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static {
}
}
fn build_macro(cx: &DocContext, did: DefId, name: ast::Name) -> Option<clean::Macro> {
fn build_macro(cx: &DocContext, did: DefId, name: ast::Name) -> clean::ItemEnum {
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(..) => return None,
};
match cx.cstore.load_macro_untracked(did, cx.sess()) {
LoadedMacro::MacroDef(def) => {
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 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{}}}",
name.clean(cx),
matchers.iter().map(|span| {
format!(" {} => {{ ... }};\n", span.to_src(cx))
}).collect::<String>());
let source = format!("macro_rules! {} {{\n{}}}",
name.clean(cx),
matchers.iter().map(|span| {
format!(" {} => {{ ... }};\n", span.to_src(cx))
}).collect::<String>());
clean::MacroItem(clean::Macro {
source,
imported_from: Some(imported_from).clean(cx),
})
}
LoadedMacro::ProcMacro(ext) => {
clean::ProcMacroItem(clean::ProcMacro {
kind: ext.kind(),
})
}
}
Some(clean::Macro {
source,
imported_from: Some(imported_from).clean(cx),
})
}
/// A trait's generics clause actually contains all of the predicates for all of

View file

@ -21,6 +21,7 @@ pub use self::Visibility::{Public, Inherited};
use rustc_target::spec::abi::Abi;
use syntax::ast::{self, AttrStyle, Ident};
use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::source_map::{dummy_spanned, Spanned};
use syntax::ptr::P;
use syntax::symbol::keywords::{self, Keyword};
@ -527,6 +528,7 @@ pub enum ItemEnum {
/// `type`s from an extern block
ForeignTypeItem,
MacroItem(Macro),
ProcMacroItem(ProcMacro),
PrimitiveItem(PrimitiveType),
AssociatedConstItem(Type, Option<String>),
AssociatedTypeItem(Vec<GenericBound>, Option<Type>),
@ -588,6 +590,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.traits.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
items.extend(self.macros.iter().map(|x| x.clean(cx)));
items.extend(self.proc_macros.iter().map(|x| x.clean(cx)));
// determine if we should display the inner contents or
// the outer `mod` item for the source code.
@ -2189,6 +2192,8 @@ pub enum TypeKind {
Typedef,
Foreign,
Macro,
Attr,
Derive,
}
pub trait GetDefId {
@ -3725,7 +3730,12 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId {
Def::Static(i, _) => (i, TypeKind::Static),
Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"),
TypeKind::Enum),
Def::Macro(i, _) => (i, TypeKind::Macro),
Def::Macro(i, mac_kind) => match mac_kind {
MacroKind::Bang => (i, TypeKind::Macro),
MacroKind::Attr => (i, TypeKind::Attr),
MacroKind::Derive => (i, TypeKind::Derive),
MacroKind::ProcMacroStub => unreachable!(),
},
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
Def::SelfTy(_, Some(impl_def_id)) => {
return impl_def_id
@ -3780,6 +3790,28 @@ impl Clean<Item> for doctree::Macro {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct ProcMacro {
pub kind: MacroKind,
}
impl Clean<Item> for doctree::ProcMacro {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
visibility: Some(Public),
stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx),
def_id: cx.tcx.hir.local_def_id(self.id),
inner: ProcMacroItem(ProcMacro {
kind: self.kind,
}),
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Stability {
pub level: stability::StabilityLevel,