mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Inline reexports in rustdoc
If a reexport comes from a non-public module, then the documentation for the reexport will be inlined into the module that exports it, but if the reexport is targeted at a public type (like the prelude), then it is not inlined but rather hyperlinked.
This commit is contained in:
parent
4329fc6730
commit
3425901d93
@ -209,6 +209,7 @@ pub fn phase_2_configure_and_expand(sess: Session,
|
||||
pub struct CrateAnalysis {
|
||||
exp_map2: middle::resolve::ExportMap2,
|
||||
exported_items: middle::privacy::ExportedItems,
|
||||
public_items: middle::privacy::PublicItems,
|
||||
ty_cx: ty::ctxt,
|
||||
maps: astencode::Maps,
|
||||
reachable: @RefCell<HashSet<ast::NodeId>>
|
||||
@ -268,9 +269,10 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
method_map, ty_cx));
|
||||
|
||||
let maps = (external_exports, last_private_map);
|
||||
let exported_items = time(time_passes, "privacy checking", maps, |(a, b)|
|
||||
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2,
|
||||
a, b, crate));
|
||||
let (exported_items, public_items) =
|
||||
time(time_passes, "privacy checking", maps, |(a, b)|
|
||||
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2,
|
||||
a, b, crate));
|
||||
|
||||
time(time_passes, "effect checking", (), |_|
|
||||
middle::effect::check_crate(ty_cx, method_map, crate));
|
||||
@ -322,6 +324,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
exp_map2: exp_map2,
|
||||
ty_cx: ty_cx,
|
||||
exported_items: exported_items,
|
||||
public_items: public_items,
|
||||
maps: astencode::Maps {
|
||||
root_map: root_map,
|
||||
method_map: method_map,
|
||||
|
@ -35,6 +35,11 @@ type Context<'a> = (&'a method_map, &'a resolve::ExportMap2);
|
||||
/// A set of AST nodes exported by the crate.
|
||||
pub type ExportedItems = HashSet<ast::NodeId>;
|
||||
|
||||
/// A set of AST nodes that are fully public in the crate. This map is used for
|
||||
/// documentation purposes (reexporting a private struct inlines the doc,
|
||||
/// reexporting a public struct doesn't inline the doc).
|
||||
pub type PublicItems = HashSet<ast::NodeId>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The parent visitor, used to determine what's the parent of what (node-wise)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -165,6 +170,12 @@ struct EmbargoVisitor<'a> {
|
||||
// means that the destination of the reexport is exported, and hence the
|
||||
// destination must also be exported.
|
||||
reexports: HashSet<ast::NodeId>,
|
||||
|
||||
// These two fields are closely related to one another in that they are only
|
||||
// used for generation of the 'PublicItems' set, not for privacy checking at
|
||||
// all
|
||||
public_items: PublicItems,
|
||||
prev_public: bool,
|
||||
}
|
||||
|
||||
impl<'a> EmbargoVisitor<'a> {
|
||||
@ -186,7 +197,13 @@ impl<'a> EmbargoVisitor<'a> {
|
||||
|
||||
impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
||||
fn visit_item(&mut self, item: &ast::item, _: ()) {
|
||||
let orig_all_pub = self.prev_exported;
|
||||
let orig_all_pub = self.prev_public;
|
||||
self.prev_public = orig_all_pub && item.vis == ast::public;
|
||||
if self.prev_public {
|
||||
self.public_items.insert(item.id);
|
||||
}
|
||||
|
||||
let orig_all_exported = self.prev_exported;
|
||||
match item.node {
|
||||
// impls/extern blocks do not break the "public chain" because they
|
||||
// cannot have visibility qualifiers on them anyway
|
||||
@ -202,7 +219,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
||||
// `pub` is explicitly listed.
|
||||
_ => {
|
||||
self.prev_exported =
|
||||
(orig_all_pub && item.vis == ast::public) ||
|
||||
(orig_all_exported && item.vis == ast::public) ||
|
||||
self.reexports.contains(&item.id);
|
||||
}
|
||||
}
|
||||
@ -304,7 +321,8 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
||||
|
||||
visit::walk_item(self, item, ());
|
||||
|
||||
self.prev_exported = orig_all_pub;
|
||||
self.prev_exported = orig_all_exported;
|
||||
self.prev_public = orig_all_pub;
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, a: &ast::foreign_item, _: ()) {
|
||||
@ -1002,7 +1020,7 @@ pub fn check_crate(tcx: ty::ctxt,
|
||||
exp_map2: &resolve::ExportMap2,
|
||||
external_exports: resolve::ExternalExports,
|
||||
last_private_map: resolve::LastPrivateMap,
|
||||
crate: &ast::Crate) -> ExportedItems {
|
||||
crate: &ast::Crate) -> (ExportedItems, PublicItems) {
|
||||
// Figure out who everyone's parent is
|
||||
let mut visitor = ParentVisitor {
|
||||
parents: HashMap::new(),
|
||||
@ -1038,9 +1056,11 @@ pub fn check_crate(tcx: ty::ctxt,
|
||||
let mut visitor = EmbargoVisitor {
|
||||
tcx: tcx,
|
||||
exported_items: HashSet::new(),
|
||||
public_items: HashSet::new(),
|
||||
reexports: HashSet::new(),
|
||||
exp_map2: exp_map2,
|
||||
prev_exported: true,
|
||||
prev_public: true,
|
||||
};
|
||||
loop {
|
||||
let before = visitor.exported_items.len();
|
||||
@ -1050,5 +1070,6 @@ pub fn check_crate(tcx: ty::ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
return visitor.exported_items;
|
||||
let EmbargoVisitor { exported_items, public_items, .. } = visitor;
|
||||
return (exported_items, public_items);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ pub struct Crate {
|
||||
externs: HashMap<ast::CrateNum, ExternalCrate>,
|
||||
}
|
||||
|
||||
impl Clean<Crate> for visit_ast::RustdocVisitor {
|
||||
impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
|
||||
fn clean(&self) -> Crate {
|
||||
use syntax::attr::find_crateid;
|
||||
let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
|
||||
|
@ -34,6 +34,7 @@ pub struct DocContext {
|
||||
|
||||
pub struct CrateAnalysis {
|
||||
exported_items: privacy::ExportedItems,
|
||||
public_items: privacy::PublicItems,
|
||||
}
|
||||
|
||||
/// Parses, resolves, and typechecks the given crate
|
||||
@ -75,12 +76,15 @@ fn get_ast_and_resolve(cpath: &Path,
|
||||
let crate = phase_1_parse_input(sess, cfg.clone(), &input);
|
||||
let (crate, ast_map) = phase_2_configure_and_expand(sess, cfg, crate);
|
||||
let driver::driver::CrateAnalysis {
|
||||
exported_items, ty_cx, ..
|
||||
exported_items, public_items, ty_cx, ..
|
||||
} = phase_3_run_analysis_passes(sess, &crate, ast_map);
|
||||
|
||||
debug!("crate: {:?}", crate);
|
||||
return (DocContext { crate: crate, tycx: Some(ty_cx), sess: sess },
|
||||
CrateAnalysis { exported_items: exported_items });
|
||||
CrateAnalysis {
|
||||
exported_items: exported_items,
|
||||
public_items: public_items,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn run_core (libs: HashSet<Path>, cfgs: ~[~str], path: &Path) -> (clean::Crate, CrateAnalysis) {
|
||||
@ -88,8 +92,11 @@ pub fn run_core (libs: HashSet<Path>, cfgs: ~[~str], path: &Path) -> (clean::Cra
|
||||
let ctxt = @ctxt;
|
||||
local_data::set(super::ctxtkey, ctxt);
|
||||
|
||||
let mut v = RustdocVisitor::new();
|
||||
v.visit(&ctxt.crate);
|
||||
let crate = {
|
||||
let mut v = RustdocVisitor::new(ctxt, Some(&analysis));
|
||||
v.visit(&ctxt.crate);
|
||||
v.clean()
|
||||
};
|
||||
|
||||
(v.clean(), analysis)
|
||||
(crate, analysis)
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
||||
};
|
||||
local_data::set(super::ctxtkey, ctx);
|
||||
|
||||
let mut v = RustdocVisitor::new();
|
||||
let mut v = RustdocVisitor::new(ctx, None);
|
||||
v.visit(&ctx.crate);
|
||||
let crate = v.clean();
|
||||
let (crate, _) = passes::unindent_comments(crate);
|
||||
|
@ -13,169 +13,278 @@
|
||||
|
||||
use syntax::abi::AbiSet;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_map;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use core;
|
||||
use doctree::*;
|
||||
|
||||
pub struct RustdocVisitor {
|
||||
pub struct RustdocVisitor<'a> {
|
||||
module: Module,
|
||||
attrs: ~[ast::Attribute],
|
||||
cx: &'a core::DocContext,
|
||||
analysis: Option<&'a core::CrateAnalysis>,
|
||||
}
|
||||
|
||||
impl RustdocVisitor {
|
||||
pub fn new() -> RustdocVisitor {
|
||||
impl<'a> RustdocVisitor<'a> {
|
||||
pub fn new<'b>(cx: &'b core::DocContext,
|
||||
analysis: Option<&'b core::CrateAnalysis>) -> RustdocVisitor<'b> {
|
||||
RustdocVisitor {
|
||||
module: Module::new(None),
|
||||
attrs: ~[],
|
||||
cx: cx,
|
||||
analysis: analysis,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RustdocVisitor {
|
||||
pub fn visit(&mut self, crate: &ast::Crate) {
|
||||
self.attrs = crate.attrs.clone();
|
||||
fn visit_struct_def(item: &ast::item, sd: @ast::struct_def, generics:
|
||||
&ast::Generics) -> Struct {
|
||||
debug!("Visiting struct");
|
||||
let struct_type = struct_type_from_def(sd);
|
||||
Struct {
|
||||
id: item.id,
|
||||
struct_type: struct_type,
|
||||
name: item.ident,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
generics: generics.clone(),
|
||||
fields: sd.fields.clone(),
|
||||
where: item.span
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_enum_def(it: &ast::item, def: &ast::enum_def, params: &ast::Generics) -> Enum {
|
||||
debug!("Visiting enum");
|
||||
let mut vars: ~[Variant] = ~[];
|
||||
for x in def.variants.iter() {
|
||||
vars.push(Variant {
|
||||
name: x.node.name,
|
||||
attrs: x.node.attrs.clone(),
|
||||
vis: x.node.vis,
|
||||
id: x.node.id,
|
||||
kind: x.node.kind.clone(),
|
||||
where: x.span,
|
||||
});
|
||||
}
|
||||
Enum {
|
||||
name: it.ident,
|
||||
variants: vars,
|
||||
vis: it.vis,
|
||||
generics: params.clone(),
|
||||
attrs: it.attrs.clone(),
|
||||
id: it.id,
|
||||
where: it.span,
|
||||
}
|
||||
}
|
||||
self.module = self.visit_mod_contents(crate.span, crate.attrs.clone(),
|
||||
ast::public, ast::CRATE_NODE_ID,
|
||||
&crate.module, None);
|
||||
}
|
||||
|
||||
fn visit_fn(item: &ast::item, fd: &ast::fn_decl, purity: &ast::purity,
|
||||
_abi: &AbiSet, gen: &ast::Generics) -> Function {
|
||||
debug!("Visiting fn");
|
||||
Function {
|
||||
id: item.id,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
decl: fd.clone(),
|
||||
name: item.ident,
|
||||
where: item.span,
|
||||
generics: gen.clone(),
|
||||
purity: *purity,
|
||||
}
|
||||
}
|
||||
pub fn visit_struct_def(&mut self, item: &ast::item, sd: @ast::struct_def,
|
||||
|
||||
fn visit_mod_contents(span: Span, attrs: ~[ast::Attribute], vis:
|
||||
ast::visibility, id: ast::NodeId, m: &ast::_mod,
|
||||
generics: &ast::Generics) -> Struct {
|
||||
debug!("Visiting struct");
|
||||
let struct_type = struct_type_from_def(sd);
|
||||
Struct {
|
||||
id: item.id,
|
||||
struct_type: struct_type,
|
||||
name: item.ident,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
generics: generics.clone(),
|
||||
fields: sd.fields.clone(),
|
||||
where: item.span
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_enum_def(&mut self, it: &ast::item, def: &ast::enum_def,
|
||||
params: &ast::Generics) -> Enum {
|
||||
debug!("Visiting enum");
|
||||
let mut vars: ~[Variant] = ~[];
|
||||
for x in def.variants.iter() {
|
||||
vars.push(Variant {
|
||||
name: x.node.name,
|
||||
attrs: x.node.attrs.clone(),
|
||||
vis: x.node.vis,
|
||||
id: x.node.id,
|
||||
kind: x.node.kind.clone(),
|
||||
where: x.span,
|
||||
});
|
||||
}
|
||||
Enum {
|
||||
name: it.ident,
|
||||
variants: vars,
|
||||
vis: it.vis,
|
||||
generics: params.clone(),
|
||||
attrs: it.attrs.clone(),
|
||||
id: it.id,
|
||||
where: it.span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_fn(&mut self, item: &ast::item, fd: &ast::fn_decl,
|
||||
purity: &ast::purity, _abi: &AbiSet,
|
||||
gen: &ast::Generics) -> Function {
|
||||
debug!("Visiting fn");
|
||||
Function {
|
||||
id: item.id,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
decl: fd.clone(),
|
||||
name: item.ident,
|
||||
where: item.span,
|
||||
generics: gen.clone(),
|
||||
purity: *purity,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_mod_contents(&mut self, span: Span, attrs: ~[ast::Attribute],
|
||||
vis: ast::visibility, id: ast::NodeId,
|
||||
m: &ast::_mod,
|
||||
name: Option<ast::Ident>) -> Module {
|
||||
let mut om = Module::new(name);
|
||||
om.view_items = m.view_items.clone();
|
||||
om.where = span;
|
||||
om.attrs = attrs;
|
||||
om.vis = vis;
|
||||
om.id = id;
|
||||
for i in m.items.iter() {
|
||||
visit_item(*i, &mut om);
|
||||
}
|
||||
om
|
||||
let mut om = Module::new(name);
|
||||
for item in m.view_items.iter() {
|
||||
self.visit_view_item(item, &mut om);
|
||||
}
|
||||
om.where = span;
|
||||
om.attrs = attrs;
|
||||
om.vis = vis;
|
||||
om.id = id;
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(*i, &mut om);
|
||||
}
|
||||
om
|
||||
}
|
||||
|
||||
fn visit_item(item: &ast::item, om: &mut Module) {
|
||||
debug!("Visiting item {:?}", item);
|
||||
match item.node {
|
||||
ast::item_mod(ref m) => {
|
||||
om.mods.push(visit_mod_contents(item.span, item.attrs.clone(),
|
||||
item.vis, item.id, m,
|
||||
Some(item.ident)));
|
||||
},
|
||||
ast::item_enum(ref ed, ref gen) => om.enums.push(visit_enum_def(item, ed, gen)),
|
||||
ast::item_struct(sd, ref gen) => om.structs.push(visit_struct_def(item, sd, gen)),
|
||||
ast::item_fn(fd, ref pur, ref abi, ref gen, _) =>
|
||||
om.fns.push(visit_fn(item, fd, pur, abi, gen)),
|
||||
ast::item_ty(ty, ref gen) => {
|
||||
let t = Typedef {
|
||||
ty: ty,
|
||||
gen: gen.clone(),
|
||||
name: item.ident,
|
||||
id: item.id,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.typedefs.push(t);
|
||||
},
|
||||
ast::item_static(ty, ref mut_, ref exp) => {
|
||||
let s = Static {
|
||||
type_: ty,
|
||||
mutability: mut_.clone(),
|
||||
expr: exp.clone(),
|
||||
id: item.id,
|
||||
name: item.ident,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.statics.push(s);
|
||||
},
|
||||
ast::item_trait(ref gen, ref tr, ref met) => {
|
||||
let t = Trait {
|
||||
name: item.ident,
|
||||
methods: met.clone(),
|
||||
generics: gen.clone(),
|
||||
parents: tr.clone(),
|
||||
id: item.id,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.traits.push(t);
|
||||
},
|
||||
ast::item_impl(ref gen, ref tr, ty, ref meths) => {
|
||||
let i = Impl {
|
||||
generics: gen.clone(),
|
||||
trait_: tr.clone(),
|
||||
for_: ty,
|
||||
methods: meths.clone(),
|
||||
attrs: item.attrs.clone(),
|
||||
id: item.id,
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.impls.push(i);
|
||||
},
|
||||
ast::item_foreign_mod(ref fm) => {
|
||||
om.foreigns.push(fm.clone());
|
||||
pub fn visit_view_item(&mut self, item: &ast::view_item, om: &mut Module) {
|
||||
if item.vis != ast::public {
|
||||
return om.view_items.push(item.clone());
|
||||
}
|
||||
let item = match item.node {
|
||||
ast::view_item_use(ref paths) => {
|
||||
// rustc no longer supports "use foo, bar;"
|
||||
assert_eq!(paths.len(), 1);
|
||||
match self.visit_view_path(paths[0], om) {
|
||||
None => return,
|
||||
Some(path) => {
|
||||
ast::view_item {
|
||||
node: ast::view_item_use(~[path]),
|
||||
.. item.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
ast::view_item_extern_mod(..) => item.clone()
|
||||
};
|
||||
om.view_items.push(item);
|
||||
}
|
||||
|
||||
fn visit_view_path(&mut self, path: @ast::view_path,
|
||||
om: &mut Module) -> Option<@ast::view_path> {
|
||||
match path.node {
|
||||
ast::view_path_simple(_, _, id) => {
|
||||
if self.resolve_id(id, false, om) { return None }
|
||||
}
|
||||
ast::view_path_list(ref p, ref paths, ref b) => {
|
||||
let mut mine = ~[];
|
||||
for path in paths.iter() {
|
||||
if !self.resolve_id(path.node.id, false, om) {
|
||||
mine.push(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if mine.len() == 0 { return None }
|
||||
return Some(@::syntax::codemap::Spanned {
|
||||
node: ast::view_path_list(p.clone(), mine, b.clone()),
|
||||
span: path.span,
|
||||
})
|
||||
}
|
||||
|
||||
// these are feature gated anyway
|
||||
ast::view_path_glob(_, id) => {
|
||||
if self.resolve_id(id, true, om) { return None }
|
||||
}
|
||||
}
|
||||
return Some(path);
|
||||
}
|
||||
|
||||
self.module = visit_mod_contents(crate.span, crate.attrs.clone(),
|
||||
ast::public, ast::CRATE_NODE_ID,
|
||||
&crate.module, None);
|
||||
fn resolve_id(&mut self, id: ast::NodeId, glob: bool,
|
||||
om: &mut Module) -> bool {
|
||||
let def = {
|
||||
let dm = match self.cx.tycx {
|
||||
Some(tcx) => tcx.def_map.borrow(),
|
||||
None => return false,
|
||||
};
|
||||
ast_util::def_id_of_def(*dm.get().get(&id))
|
||||
};
|
||||
if !ast_util::is_local(def) { return false }
|
||||
let analysis = match self.analysis {
|
||||
Some(analysis) => analysis, None => return false
|
||||
};
|
||||
if analysis.public_items.contains(&def.node) { return false }
|
||||
|
||||
let item = {
|
||||
let items = self.cx.tycx.unwrap().items.borrow();
|
||||
*items.get().get(&def.node)
|
||||
};
|
||||
match item {
|
||||
ast_map::node_item(it, _) => {
|
||||
if glob {
|
||||
match it.node {
|
||||
ast::item_mod(ref m) => {
|
||||
for vi in m.view_items.iter() {
|
||||
self.visit_view_item(vi, om);
|
||||
}
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(*i, om);
|
||||
}
|
||||
}
|
||||
_ => { fail!("glob not mapped to a module"); }
|
||||
}
|
||||
} else {
|
||||
self.visit_item(it, om);
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_item(&mut self, item: &ast::item, om: &mut Module) {
|
||||
debug!("Visiting item {:?}", item);
|
||||
match item.node {
|
||||
ast::item_mod(ref m) => {
|
||||
om.mods.push(self.visit_mod_contents(item.span, item.attrs.clone(),
|
||||
item.vis, item.id, m,
|
||||
Some(item.ident)));
|
||||
},
|
||||
ast::item_enum(ref ed, ref gen) =>
|
||||
om.enums.push(self.visit_enum_def(item, ed, gen)),
|
||||
ast::item_struct(sd, ref gen) =>
|
||||
om.structs.push(self.visit_struct_def(item, sd, gen)),
|
||||
ast::item_fn(fd, ref pur, ref abi, ref gen, _) =>
|
||||
om.fns.push(self.visit_fn(item, fd, pur, abi, gen)),
|
||||
ast::item_ty(ty, ref gen) => {
|
||||
let t = Typedef {
|
||||
ty: ty,
|
||||
gen: gen.clone(),
|
||||
name: item.ident,
|
||||
id: item.id,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.typedefs.push(t);
|
||||
},
|
||||
ast::item_static(ty, ref mut_, ref exp) => {
|
||||
let s = Static {
|
||||
type_: ty,
|
||||
mutability: mut_.clone(),
|
||||
expr: exp.clone(),
|
||||
id: item.id,
|
||||
name: item.ident,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.statics.push(s);
|
||||
},
|
||||
ast::item_trait(ref gen, ref tr, ref met) => {
|
||||
let t = Trait {
|
||||
name: item.ident,
|
||||
methods: met.clone(),
|
||||
generics: gen.clone(),
|
||||
parents: tr.clone(),
|
||||
id: item.id,
|
||||
attrs: item.attrs.clone(),
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.traits.push(t);
|
||||
},
|
||||
ast::item_impl(ref gen, ref tr, ty, ref meths) => {
|
||||
let i = Impl {
|
||||
generics: gen.clone(),
|
||||
trait_: tr.clone(),
|
||||
for_: ty,
|
||||
methods: meths.clone(),
|
||||
attrs: item.attrs.clone(),
|
||||
id: item.id,
|
||||
where: item.span,
|
||||
vis: item.vis,
|
||||
};
|
||||
om.impls.push(i);
|
||||
},
|
||||
ast::item_foreign_mod(ref fm) => {
|
||||
om.foreigns.push(fm.clone());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user