Skip to content

Commit

Permalink
Add impl items for struct, enum, traits
Browse files Browse the repository at this point in the history
  • Loading branch information
HeroicKatora committed Jan 24, 2021
1 parent dc88444 commit 0d13830
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 0 deletions.
27 changes: 27 additions & 0 deletions examples/crate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,33 @@ pub trait ThisIsATrait: Clone {
}
}

pub trait EasyToImpl {
/// A type that must be declared.
type ToDeclare: Clone;
/// A constant attribute that needs to be defined.
const An_ATTRIBTE: usize;
/// A method you do need to impl.
fn method_to_impl(&self);
/// A provided method you do not need to impl.
fn method_not_to_impl(&self) {}
}

impl KindOfReprC {
pub const CONSTANT: usize = 0;

/// An associated method of KindOfReprC
pub fn new() -> Self {
KindOfReprC(0)
}
}

/// Implements the EasyToImpl trait for KindOfReprC.
impl EasyToImpl for KindOfReprC {
type ToDeclare = usize;
const An_ATTRIBTE: usize = 0;
fn method_to_impl(&self) {}
}

/// A normal function.
pub fn function_item(param: usize) -> ReturnType {
ReturnType
Expand Down
134 changes: 134 additions & 0 deletions src/frontend/rustdoc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ impl<'a> Rustdoc<'a> {
Item { inner: ItemEnum::TraitItem(inner), .. } => {
self.appender.trait_(krate, item, inner);
},
Item { inner: ItemEnum::ImplItem(inner), .. } => {
self.appender.impl_(krate, item, inner);
},
Item { kind: types::ItemKind::Primitive, .. }
| Item { kind: types::ItemKind::Keyword, .. } => {},
_ => eprintln!("Unimplemented {:?}", item),
Expand Down Expand Up @@ -428,6 +431,10 @@ impl<'a> RustdocAppender<'a> {

self.buffered.push_back(Event::End(Tag::Paragraph));
}

for impl_ in struct_.impls.iter().rev() {
self.stack.push(Traversal::Item(impl_.clone()));
}
}

fn constant(&mut self, krate: &types::Crate, item: &Item, constant: &types::Constant) {
Expand Down Expand Up @@ -600,6 +607,10 @@ impl<'a> RustdocAppender<'a> {

self.buffered.push_back(Event::End(Tag::Paragraph));
}

for impl_ in enum_.impls.iter().rev() {
self.stack.push(Traversal::Item(impl_.clone()));
}
}

fn trait_(&mut self, krate: &types::Crate, item: &Item, trait_: &types::Trait) {
Expand Down Expand Up @@ -744,6 +755,129 @@ impl<'a> RustdocAppender<'a> {
}
}

fn impl_(&mut self, krate: &types::Crate, item: &Item, impl_: &types::Impl) {
let mut impl_header = String::from("impl");
// FIXME: generics
impl_header.push(' ');
if let Some(trait_) = &impl_.trait_ {
if impl_.negative {
impl_header.push('!');
}
impl_header.push_str(&Self::codify_type(krate, trait_));
impl_header.push_str(" for ");
}
impl_header.push_str(&Self::codify_type(krate, &impl_.for_));

self.buffered.push_back(Event::Start(Tag::Paragraph));
self.buffered.push_back(Event::Start(Tag::InlineCode));
self.buffered.push_back(Event::Text(Cow::Owned(impl_header)));
self.buffered.push_back(Event::End(Tag::InlineCode));
self.buffered.push_back(Event::End(Tag::Paragraph));

if !item.docs.is_empty() {
self.buffered.push_back(Event::Start(Tag::Paragraph));
self.buffered.push_back(Event::Text(item.docs.clone().into()));
self.buffered.push_back(Event::End(Tag::Paragraph));
}

let mut impl_items = vec![];

for item_id in &impl_.items {
match krate.index.get(item_id) {
Some(Item {
inner: ItemEnum::TypedefItem(typedef),
name: Some(name),
visibility,
docs,
..
}) => {
let meta = Self::codify_visibility(visibility);
let mut def = format!("{}type ", meta);
def.push_str(name);
def.push_str(" = ");
def.push_str(&Self::codify_type(krate, &typedef.type_));
def.push_str(";\n");

impl_items.push((name, def, docs));
}
Some(Item {
inner: ItemEnum::ConstantItem(const_),
name: Some(name),
visibility,
docs,
..
}) => {
let meta = Self::codify_visibility(visibility);
let mut def = format!("{}const ", meta);
def.push_str(name);
def.push_str(": ");
def.push_str(&Self::codify_type(krate, &const_.type_));
def.push_str(" = ");
def.push_str(&const_.expr);
def.push_str(";\n");

impl_items.push((name, def, docs));
}
// FIXME(rustdoc): this is only due to an internal bug in rustdoc where associated
// constants ( impl Type { pub const A: usize = 0 ) appear as AssocConstItem
// instead which would be more appropriate for a trait.
Some(Item {
inner: ItemEnum::AssocConstItem { type_, default: Some(const_def) },
name: Some(name),
visibility,
docs,
..
}) => {
let meta = Self::codify_visibility(visibility);
let mut def = format!("{}const ", meta);
def.push_str(name);
def.push_str(": ");
def.push_str(&Self::codify_type(krate, type_));
def.push_str(" = ");
def.push_str(&const_def);
def.push_str(";\n");

impl_items.push((name, def, docs));
}
Some(Item {
inner: ItemEnum::MethodItem(method),
name: Some(name),
visibility,
docs,
..
}) => {
let meta = Self::codify_visibility(visibility);
let mut def = format!("{}{}fn ", meta, &method.header);
def.push_str(name);
// FIXME: generics
def.push_str(&Self::codify_fn_decl(krate, &method.decl));

impl_items.push((name, def, docs));
}
Some(other) => {
self.diagnostics
.warning(format!("Unhandled impl item: {:?}", other))
.emit();
}
None => unreachable!("Trait item does not exist?"),
}
}

for (name, definition, docs) in impl_items {
self.buffered.push_back(Event::Start(Tag::Paragraph));
self.buffered.push_back(Event::Start(Tag::InlineCode));
self.buffered.push_back(Event::Text(Cow::Owned(definition)));
self.buffered.push_back(Event::End(Tag::InlineCode));
self.buffered.push_back(Event::End(Tag::Paragraph));

if !item.docs.is_empty() {
self.buffered.push_back(Event::Start(Tag::Paragraph));
self.buffered.push_back(Event::Text(item.docs.clone().into()));
self.buffered.push_back(Event::End(Tag::Paragraph));
}
}
}

fn label_for_id(&self, path: &types::Id, krate: &types::Crate) -> Option<String> {
match krate.paths.get(path) {
Some(summary) => Some(self.label_for_item_at_path(&summary.path)),
Expand Down

0 comments on commit 0d13830

Please sign in to comment.