提交 aea1bd0a 编写于 作者: Q QuietMisdreavus

handle proc-macros as macros instead of functions

上级 f49f6e73
...@@ -105,15 +105,14 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa ...@@ -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); record_extern_fqn(cx, did, clean::TypeKind::Const);
clean::ConstantItem(build_const(cx, did)) clean::ConstantItem(build_const(cx, did))
} }
// FIXME(misdreavus): if attributes/derives come down here we should probably document them Def::Macro(did, mac_kind) => {
// separately match mac_kind {
Def::Macro(did, MacroKind::Bang) => { MacroKind::Bang => record_extern_fqn(cx, did, clean::TypeKind::Macro),
record_extern_fqn(cx, did, clean::TypeKind::Macro); MacroKind::Attr => record_extern_fqn(cx, did, clean::TypeKind::Attr),
if let Some(mac) = build_macro(cx, did, name) { MacroKind::Derive => record_extern_fqn(cx, did, clean::TypeKind::Derive),
clean::MacroItem(mac) MacroKind::ProcMacroStub => return None,
} else {
return None;
} }
build_macro(cx, did, name)
} }
_ => return None, _ => return None,
}; };
...@@ -442,31 +441,35 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static { ...@@ -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 imported_from = cx.tcx.original_crate_name(did.krate);
let def = match cx.cstore.load_macro_untracked(did, cx.sess()) { match cx.cstore.load_macro_untracked(did, cx.sess()) {
LoadedMacro::MacroDef(macro_def) => macro_def, LoadedMacro::MacroDef(def) => {
// FIXME(jseyfried): document proc macro re-exports let matchers: hir::HirVec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.node {
LoadedMacro::ProcMacro(..) => return None, let tts: Vec<_> = def.stream().into_trees().collect();
}; tts.chunks(4).map(|arm| arm[0].span()).collect()
} else {
let matchers: hir::HirVec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.node { unreachable!()
let tts: Vec<_> = def.stream().into_trees().collect(); };
tts.chunks(4).map(|arm| arm[0].span()).collect()
} else { let source = format!("macro_rules! {} {{\n{}}}",
unreachable!() name.clean(cx),
}; matchers.iter().map(|span| {
format!(" {} => {{ ... }};\n", span.to_src(cx))
let source = format!("macro_rules! {} {{\n{}}}", }).collect::<String>());
name.clean(cx),
matchers.iter().map(|span| { clean::MacroItem(clean::Macro {
format!(" {} => {{ ... }};\n", span.to_src(cx)) source,
}).collect::<String>()); 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 /// A trait's generics clause actually contains all of the predicates for all of
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use syntax::ast::{self, AttrStyle, Ident}; use syntax::ast::{self, AttrStyle, Ident};
use syntax::attr; use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::source_map::{dummy_spanned, Spanned}; use syntax::source_map::{dummy_spanned, Spanned};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::symbol::keywords::{self, Keyword}; use syntax::symbol::keywords::{self, Keyword};
...@@ -527,6 +528,7 @@ pub enum ItemEnum { ...@@ -527,6 +528,7 @@ pub enum ItemEnum {
/// `type`s from an extern block /// `type`s from an extern block
ForeignTypeItem, ForeignTypeItem,
MacroItem(Macro), MacroItem(Macro),
ProcMacroItem(ProcMacro),
PrimitiveItem(PrimitiveType), PrimitiveItem(PrimitiveType),
AssociatedConstItem(Type, Option<String>), AssociatedConstItem(Type, Option<String>),
AssociatedTypeItem(Vec<GenericBound>, Option<Type>), AssociatedTypeItem(Vec<GenericBound>, Option<Type>),
...@@ -588,6 +590,7 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -588,6 +590,7 @@ fn clean(&self, cx: &DocContext) -> Item {
items.extend(self.traits.iter().map(|x| x.clean(cx))); items.extend(self.traits.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().flat_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.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 // determine if we should display the inner contents or
// the outer `mod` item for the source code. // the outer `mod` item for the source code.
...@@ -2189,6 +2192,8 @@ pub enum TypeKind { ...@@ -2189,6 +2192,8 @@ pub enum TypeKind {
Typedef, Typedef,
Foreign, Foreign,
Macro, Macro,
Attr,
Derive,
} }
pub trait GetDefId { pub trait GetDefId {
...@@ -3725,7 +3730,12 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId { ...@@ -3725,7 +3730,12 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId {
Def::Static(i, _) => (i, TypeKind::Static), Def::Static(i, _) => (i, TypeKind::Static),
Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"), Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"),
TypeKind::Enum), 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(def_id), _) => (def_id, TypeKind::Trait),
Def::SelfTy(_, Some(impl_def_id)) => { Def::SelfTy(_, Some(impl_def_id)) => {
return impl_def_id return impl_def_id
...@@ -3780,6 +3790,28 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -3780,6 +3790,28 @@ fn clean(&self, cx: &DocContext) -> Item {
} }
} }
#[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)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Stability { pub struct Stability {
pub level: stability::StabilityLevel, pub level: stability::StabilityLevel,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
use syntax::ast; use syntax::ast;
use syntax::ast::{Name, NodeId}; use syntax::ast::{Name, NodeId};
use syntax::attr; use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::source_map::Spanned; use syntax::source_map::Spanned;
use syntax_pos::{self, Span}; use syntax_pos::{self, Span};
...@@ -46,6 +47,7 @@ pub struct Module { ...@@ -46,6 +47,7 @@ pub struct Module {
pub impls: Vec<Impl>, pub impls: Vec<Impl>,
pub foreigns: Vec<hir::ForeignMod>, pub foreigns: Vec<hir::ForeignMod>,
pub macros: Vec<Macro>, pub macros: Vec<Macro>,
pub proc_macros: Vec<ProcMacro>,
pub is_crate: bool, pub is_crate: bool,
} }
...@@ -75,6 +77,7 @@ pub fn new(name: Option<Name>) -> Module { ...@@ -75,6 +77,7 @@ pub fn new(name: Option<Name>) -> Module {
impls : Vec::new(), impls : Vec::new(),
foreigns : Vec::new(), foreigns : Vec::new(),
macros : Vec::new(), macros : Vec::new(),
proc_macros: Vec::new(),
is_crate : false, is_crate : false,
} }
} }
...@@ -264,6 +267,16 @@ pub struct Import { ...@@ -264,6 +267,16 @@ pub struct Import {
pub whence: Span, pub whence: Span,
} }
pub struct ProcMacro {
pub name: Name,
pub id: NodeId,
pub kind: MacroKind,
pub attrs: hir::HirVec<ast::Attribute>,
pub whence: Span,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType { pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType {
match *vdata { match *vdata {
hir::VariantData::Struct(..) => Plain, hir::VariantData::Struct(..) => Plain,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
//! Item types. //! Item types.
use std::fmt; use std::fmt;
use syntax::ext::base::MacroKind;
use clean; use clean;
/// Item type. Corresponds to `clean::ItemEnum` variants. /// Item type. Corresponds to `clean::ItemEnum` variants.
...@@ -19,6 +20,11 @@ ...@@ -19,6 +20,11 @@
/// discriminants. JavaScript then is used to decode them into the original value. /// discriminants. JavaScript then is used to decode them into the original value.
/// Consequently, every change to this type should be synchronized to /// Consequently, every change to this type should be synchronized to
/// the `itemTypes` mapping table in `static/main.js`. /// the `itemTypes` mapping table in `static/main.js`.
///
/// In addition, code in `html::render` uses this enum to generate CSS classes, page prefixes, and
/// module headings. If you are adding to this enum and want to ensure that the sidebar also prints
/// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an
/// ordering based on a helper function inside `item_module`, in the same file.
#[derive(Copy, PartialEq, Clone, Debug)] #[derive(Copy, PartialEq, Clone, Debug)]
pub enum ItemType { pub enum ItemType {
Module = 0, Module = 0,
...@@ -44,6 +50,8 @@ pub enum ItemType { ...@@ -44,6 +50,8 @@ pub enum ItemType {
ForeignType = 20, ForeignType = 20,
Keyword = 21, Keyword = 21,
Existential = 22, Existential = 22,
ProcAttribute = 23,
ProcDerive = 24,
} }
...@@ -88,6 +96,12 @@ fn from(item: &'a clean::Item) -> ItemType { ...@@ -88,6 +96,12 @@ fn from(item: &'a clean::Item) -> ItemType {
clean::AssociatedTypeItem(..) => ItemType::AssociatedType, clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
clean::ForeignTypeItem => ItemType::ForeignType, clean::ForeignTypeItem => ItemType::ForeignType,
clean::KeywordItem(..) => ItemType::Keyword, clean::KeywordItem(..) => ItemType::Keyword,
clean::ProcMacroItem(ref mac) => match mac.kind {
MacroKind::Bang => ItemType::Macro,
MacroKind::Attr => ItemType::ProcAttribute,
MacroKind::Derive => ItemType::ProcDerive,
MacroKind::ProcMacroStub => unreachable!(),
}
clean::StrippedItem(..) => unreachable!(), clean::StrippedItem(..) => unreachable!(),
} }
} }
...@@ -107,7 +121,9 @@ fn from(kind: clean::TypeKind) -> ItemType { ...@@ -107,7 +121,9 @@ fn from(kind: clean::TypeKind) -> ItemType {
clean::TypeKind::Variant => ItemType::Variant, clean::TypeKind::Variant => ItemType::Variant,
clean::TypeKind::Typedef => ItemType::Typedef, clean::TypeKind::Typedef => ItemType::Typedef,
clean::TypeKind::Foreign => ItemType::ForeignType, clean::TypeKind::Foreign => ItemType::ForeignType,
clean::TypeKind::Macro => ItemType::Macro, clean::TypeKind::Macro => ItemType::Macro,
clean::TypeKind::Attr => ItemType::ProcAttribute,
clean::TypeKind::Derive => ItemType::ProcDerive,
} }
} }
} }
...@@ -138,6 +154,8 @@ pub fn css_class(&self) -> &'static str { ...@@ -138,6 +154,8 @@ pub fn css_class(&self) -> &'static str {
ItemType::ForeignType => "foreigntype", ItemType::ForeignType => "foreigntype",
ItemType::Keyword => "keyword", ItemType::Keyword => "keyword",
ItemType::Existential => "existential", ItemType::Existential => "existential",
ItemType::ProcAttribute => "attr",
ItemType::ProcDerive => "derive",
} }
} }
...@@ -166,7 +184,9 @@ pub fn name_space(&self) -> NameSpace { ...@@ -166,7 +184,9 @@ pub fn name_space(&self) -> NameSpace {
ItemType::Constant | ItemType::Constant |
ItemType::AssociatedConst => NameSpace::Value, ItemType::AssociatedConst => NameSpace::Value,
ItemType::Macro => NameSpace::Macro, ItemType::Macro |
ItemType::ProcAttribute |
ItemType::ProcDerive => NameSpace::Macro,
ItemType::Keyword => NameSpace::Keyword, ItemType::Keyword => NameSpace::Keyword,
} }
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
use serialize::json::{ToJson, Json, as_json}; use serialize::json::{ToJson, Json, as_json};
use syntax::ast; use syntax::ast;
use syntax::ext::base::MacroKind;
use syntax::source_map::FileName; use syntax::source_map::FileName;
use syntax::feature_gate::UnstableFeatures; use syntax::feature_gate::UnstableFeatures;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
...@@ -2155,6 +2156,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { ...@@ -2155,6 +2156,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
clean::EnumItem(..) => write!(fmt, "Enum ")?, clean::EnumItem(..) => write!(fmt, "Enum ")?,
clean::TypedefItem(..) => write!(fmt, "Type Definition ")?, clean::TypedefItem(..) => write!(fmt, "Type Definition ")?,
clean::MacroItem(..) => write!(fmt, "Macro ")?, clean::MacroItem(..) => write!(fmt, "Macro ")?,
clean::ProcMacroItem(ref mac) => match mac.kind {
MacroKind::Bang => write!(fmt, "Macro ")?,
MacroKind::Attr => write!(fmt, "Attribute Macro ")?,
MacroKind::Derive => write!(fmt, "Derive Macro ")?,
MacroKind::ProcMacroStub => unreachable!(),
}
clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?, clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?, clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
clean::ConstantItem(..) => write!(fmt, "Constant ")?, clean::ConstantItem(..) => write!(fmt, "Constant ")?,
...@@ -2191,6 +2198,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { ...@@ -2191,6 +2198,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e), clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t), clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m), clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
clean::ProcMacroItem(ref m) => item_proc_macro(fmt, self.cx, self.item, m),
clean::PrimitiveItem(ref p) => item_primitive(fmt, self.cx, self.item, p), clean::PrimitiveItem(ref p) => item_primitive(fmt, self.cx, self.item, p),
clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) => clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
item_static(fmt, self.cx, self.item, i), item_static(fmt, self.cx, self.item, i),
...@@ -4523,6 +4531,8 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) { ...@@ -4523,6 +4531,8 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
ItemType::ForeignType => ("foreign-types", "Foreign Types"), ItemType::ForeignType => ("foreign-types", "Foreign Types"),
ItemType::Keyword => ("keywords", "Keywords"), ItemType::Keyword => ("keywords", "Keywords"),
ItemType::Existential => ("existentials", "Existentials"), ItemType::Existential => ("existentials", "Existentials"),
ItemType::ProcAttribute => ("attributes", "Attribute Macros"),
ItemType::ProcDerive => ("derives", "Derive Macros"),
} }
} }
...@@ -4598,6 +4608,17 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, ...@@ -4598,6 +4608,17 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
document(w, cx, it) document(w, cx, it)
} }
fn item_proc_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, m: &clean::ProcMacro)
-> fmt::Result
{
if m.kind == MacroKind::Bang {
write!(w, "<pre class='rust macro'>")?;
write!(w, "{}!() {{ /* proc-macro */ }}", it.name.as_ref().unwrap())?;
write!(w, "</pre>")?;
}
document(w, cx, it)
}
fn item_primitive(w: &mut fmt::Formatter, cx: &Context, fn item_primitive(w: &mut fmt::Formatter, cx: &Context,
it: &clean::Item, it: &clean::Item,
_p: &clean::PrimitiveType) -> fmt::Result { _p: &clean::PrimitiveType) -> fmt::Result {
......
...@@ -39,7 +39,10 @@ ...@@ -39,7 +39,10 @@
"associatedconstant", "associatedconstant",
"union", "union",
"foreigntype", "foreigntype",
"keyword"]; "keyword",
"existential",
"attr",
"derive"];
var search_input = document.getElementsByClassName('search-input')[0]; var search_input = document.getElementsByClassName('search-input')[0];
......
...@@ -124,6 +124,8 @@ pre { ...@@ -124,6 +124,8 @@ pre {
.content .highlighted.tymethod { background-color: #4950ed; } .content .highlighted.tymethod { background-color: #4950ed; }
.content .highlighted.type { background-color: #38902c; } .content .highlighted.type { background-color: #38902c; }
.content .highlighted.foreigntype { background-color: #b200d6; } .content .highlighted.foreigntype { background-color: #b200d6; }
.content .highlighted.attr,
.content .highlighted.derive,
.content .highlighted.macro { background-color: #217d1c; } .content .highlighted.macro { background-color: #217d1c; }
.content .highlighted.constant, .content .highlighted.constant,
.content .highlighted.static { background-color: #0063cc; } .content .highlighted.static { background-color: #0063cc; }
...@@ -134,6 +136,8 @@ pre { ...@@ -134,6 +136,8 @@ pre {
.content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; } .content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; }
.content span.type, .content a.type, .block a.current.type { color: #ff7f00; } .content span.type, .content a.type, .block a.current.type { color: #ff7f00; }
.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #dd7de8; } .content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #dd7de8; }
.content span.attr, .content a.attr, .block a.current.attr,
.content span.derive, .content a.derive, .block a.current.derive,
.content span.macro, .content a.macro, .block a.current.macro { color: #09bd00; } .content span.macro, .content a.macro, .block a.current.macro { color: #09bd00; }
.content span.union, .content a.union, .block a.current.union { color: #a6ae37; } .content span.union, .content a.union, .block a.current.union { color: #a6ae37; }
.content span.constant, .content a.constant, .block a.current.constant, .content span.constant, .content a.constant, .block a.current.constant,
......
...@@ -124,6 +124,8 @@ pre { ...@@ -124,6 +124,8 @@ pre {
.content .highlighted.tymethod { background-color: #c6afb3; } .content .highlighted.tymethod { background-color: #c6afb3; }
.content .highlighted.type { background-color: #ffc891; } .content .highlighted.type { background-color: #ffc891; }
.content .highlighted.foreigntype { background-color: #f5c4ff; } .content .highlighted.foreigntype { background-color: #f5c4ff; }
.content .highlighted.attr,
.content .highlighted.derive,
.content .highlighted.macro { background-color: #8ce488; } .content .highlighted.macro { background-color: #8ce488; }
.content .highlighted.constant, .content .highlighted.constant,
.content .highlighted.static { background-color: #c3e0ff; } .content .highlighted.static { background-color: #c3e0ff; }
...@@ -134,6 +136,8 @@ pre { ...@@ -134,6 +136,8 @@ pre {
.content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; } .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; }
.content span.type, .content a.type, .block a.current.type { color: #ba5d00; } .content span.type, .content a.type, .block a.current.type { color: #ba5d00; }
.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; } .content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #cd00e2; }
.content span.attr, .content a.attr, .block a.current.attr,
.content span.derive, .content a.derive, .block a.current.derive,
.content span.macro, .content a.macro, .block a.current.macro { color: #068000; } .content span.macro, .content a.macro, .block a.current.macro { color: #068000; }
.content span.union, .content a.union, .block a.current.union { color: #767b27; } .content span.union, .content a.union, .block a.current.union { color: #767b27; }
.content span.constant, .content a.constant, .block a.current.constant, .content span.constant, .content a.constant, .block a.current.constant,
......
...@@ -249,6 +249,9 @@ fn fold_item(&mut self, i: Item) -> Option<Item> { ...@@ -249,6 +249,9 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
// tymethods/macros have no control over privacy // tymethods/macros have no control over privacy
clean::MacroItem(..) | clean::TyMethodItem(..) => {} clean::MacroItem(..) | clean::TyMethodItem(..) => {}
// Proc-macros are always public
clean::ProcMacroItem(..) => {}
// Primitives are never stripped // Primitives are never stripped
clean::PrimitiveItem(..) => {} clean::PrimitiveItem(..) => {}
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
use syntax::ast; use syntax::ast;
use syntax::attr; use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::source_map::Spanned; use syntax::source_map::Spanned;
use syntax_pos::{self, Span}; use syntax_pos::{self, Span};
...@@ -168,24 +169,59 @@ pub fn visit_enum_def(&mut self, it: &hir::Item, ...@@ -168,24 +169,59 @@ pub fn visit_enum_def(&mut self, it: &hir::Item,
} }
} }
pub fn visit_fn(&mut self, item: &hir::Item, pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
name: ast::Name, fd: &hir::FnDecl, name: ast::Name, fd: &hir::FnDecl,
header: hir::FnHeader, header: hir::FnHeader,
gen: &hir::Generics, gen: &hir::Generics,
body: hir::BodyId) -> Function { body: hir::BodyId) {
debug!("Visiting fn"); debug!("Visiting fn");
Function { let macro_kind = item.attrs.iter().filter_map(|a| {
id: item.id, if a.check_name("proc_macro") {
vis: item.vis.clone(), Some(MacroKind::Bang)
stab: self.stability(item.id), } else if a.check_name("proc_macro_derive") {
depr: self.deprecation(item.id), Some(MacroKind::Derive)
attrs: item.attrs.clone(), } else if a.check_name("proc_macro_attribute") {
decl: fd.clone(), Some(MacroKind::Attr)
name, } else {
whence: item.span, None
generics: gen.clone(), }
header, }).next();
body, match macro_kind {
Some(kind) => {
let name = if kind == MacroKind::Derive {
item.attrs.lists("proc_macro_derive")
.filter_map(|mi| mi.name())
.next()
.expect("proc-macro derives require a name")
} else {
name
};
om.proc_macros.push(ProcMacro {
name,
id: item.id,
kind,
attrs: item.attrs.clone(),
whence: item.span,
stab: self.stability(item.id),
depr: self.deprecation(item.id),
});
}
None => {
om.fns.push(Function {
id: item.id,
vis: item.vis.clone(),
stab: self.stability(item.id),
depr: self.deprecation(item.id),
attrs: item.attrs.clone(),
decl: fd.clone(),
name,
whence: item.span,
generics: gen.clone(),
header,
body,
});
}
} }
} }
...@@ -425,7 +461,7 @@ pub fn visit_item(&mut self, item: &hir::Item, ...@@ -425,7 +461,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
hir::ItemKind::Union(ref sd, ref gen) => hir::ItemKind::Union(ref sd, ref gen) =>
om.unions.push(self.visit_union_data(item, name, sd, gen)), om.unions.push(self.visit_union_data(item, name, sd, gen)),
hir::ItemKind::Fn(ref fd, header, ref gen, body) => hir::ItemKind::Fn(ref fd, header, ref gen, body) =>
om.fns.push(self.visit_fn(item, name, &**fd, header, gen, body)), self.visit_fn(om, item, name, &**fd, header, gen, body),
hir::ItemKind::Ty(ref ty, ref gen) => { hir::ItemKind::Ty(ref ty, ref gen) => {
let t = Typedef { let t = Typedef {
ty: ty.clone(), ty: ty.clone(),
......
// Copyright 2018 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.
// ignore-stage1
#![crate_type="proc-macro"]
#![crate_name="some_macros"]
extern crate proc_macro;
use proc_macro::TokenStream;
// @has some_macros/index.html
// @has - '//h2' 'Macros'
// @has - '//h2' 'Attribute Macros'
// @has - '//h2' 'Derive Macros'
// @!has - '//h2' 'Functions'
// @has some_macros/index.html '//a/@href' 'macro.some_proc_macro.html'
// @!has - '//a/@href' 'fn.some_proc_macro.html'
// @has some_macros/macro.some_proc_macro.html
// @!has some_macros/fn.some_proc_macro.html
/// a proc-macro that swallows its input and does nothing.
#[proc_macro]
pub fn some_proc_macro(_input: TokenStream) -> TokenStream {
TokenStream::new()
}
// @has some_macros/index.html '//a/@href' 'attr.some_proc_attr.html'
// @!has - '//a/@href' 'fn.some_proc_attr.html'
// @has some_macros/attr.some_proc_attr.html
// @!has some_macros/fn.some_proc_attr.html
/// a proc-macro attribute that passes its item through verbatim.
#[proc_macro_attribute]
pub fn some_proc_attr(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
// @has some_macros/index.html '//a/@href' 'derive.SomeDerive.html'
// @!has - '//a/@href' 'fn.some_derive.html'
// @has some_macros/derive.SomeDerive.html
// @!has some_macros/fn.some_derive.html
/// a derive attribute that adds nothing to its input.
#[proc_macro_derive(SomeDerive)]
pub fn some_derive(_item: TokenStream) -> TokenStream {
TokenStream::new()
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册