rustdoc: Split the pruning of undocumented branches into two passes
prune_undoc_details_pass strips arguments and return values that are undocumented. prune_undoc_items_pass prunes entire items.
This commit is contained in:
parent
e204aa281d
commit
f6f3d518e6
4 changed files with 187 additions and 104 deletions
162
src/rustdoc/prune_undoc_details_pass.rs
Normal file
162
src/rustdoc/prune_undoc_details_pass.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
#[doc = "Prunes args, retvals of the document tree that \
|
||||
contain no documentation"];
|
||||
|
||||
export mk_pass;
|
||||
|
||||
fn mk_pass() -> pass {
|
||||
run
|
||||
}
|
||||
|
||||
fn run(
|
||||
_srv: astsrv::srv,
|
||||
doc: doc::cratedoc
|
||||
) -> doc::cratedoc {
|
||||
let fold = fold::fold({
|
||||
fold_fn: fold_fn,
|
||||
fold_res: fold_res,
|
||||
fold_iface: fold_iface,
|
||||
fold_impl: fold_impl
|
||||
with *fold::default_seq_fold(())
|
||||
});
|
||||
fold.fold_crate(fold, doc)
|
||||
}
|
||||
|
||||
fn fold_fn(
|
||||
fold: fold::fold<()>,
|
||||
doc: doc::fndoc
|
||||
) -> doc::fndoc {
|
||||
let doc = fold::default_seq_fold_fn(fold, doc);
|
||||
|
||||
{
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
fn prune_args(docs: [doc::argdoc]) -> [doc::argdoc] {
|
||||
vec::filter_map(docs) {|doc|
|
||||
if option::is_some(doc.desc) {
|
||||
some(doc)
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prune_return(doc: doc::retdoc) -> doc::retdoc {
|
||||
{
|
||||
ty: if option::is_some(doc.desc) {
|
||||
doc.ty
|
||||
} else {
|
||||
none
|
||||
}
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_arguments() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] fn a(b: int) { }");
|
||||
assert vec::is_empty(doc.topmod.fns()[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_return_values() {
|
||||
let source = "#[doc = \"fonz\"] fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = tystr_pass::mk_pass()(srv, doc);
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
assert doc.topmod.fns()[0].return.ty == none;
|
||||
}
|
||||
|
||||
fn fold_res(
|
||||
fold: fold::fold<()>,
|
||||
doc: doc::resdoc
|
||||
) -> doc::resdoc {
|
||||
let doc = fold::default_seq_fold_res(fold, doc);
|
||||
|
||||
{
|
||||
args: prune_args(doc.args)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_resource_args() {
|
||||
let doc = test::mk_doc("#[doc = \"drunk\"]\
|
||||
resource r(a: bool) { }");
|
||||
assert vec::is_empty(doc.topmod.resources()[0].args);
|
||||
}
|
||||
|
||||
fn fold_iface(
|
||||
fold: fold::fold<()>,
|
||||
doc: doc::ifacedoc
|
||||
) -> doc::ifacedoc {
|
||||
let doc = fold::default_seq_fold_iface(fold, doc);
|
||||
|
||||
{
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
fn prune_methods(docs: [doc::methoddoc]) -> [doc::methoddoc] {
|
||||
vec::map(docs) {|doc|
|
||||
{
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_iface_method_args() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a(); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_iface_method_return_values() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
fn fold_impl(
|
||||
fold: fold::fold<()>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
let doc = fold::default_seq_fold_impl(fold, doc);
|
||||
|
||||
{
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_args() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a(b: bool) { } }");
|
||||
assert vec::is_empty(doc.topmod.impls()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_return_values() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a() -> int { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
run(srv, doc)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Prunes branches of the document tree that contain no documentation"];
|
||||
#[doc = "Prunes items of the document tree that contain no documentation"];
|
||||
|
||||
export mk_pass;
|
||||
|
||||
|
@ -109,46 +109,27 @@ fn fold_fn(
|
|||
fold: fold::fold<ctxt>,
|
||||
doc: doc::fndoc
|
||||
) -> doc::fndoc {
|
||||
let doc = {
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
};
|
||||
let doc = fold::default_seq_fold_fn(fold, doc);
|
||||
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| vec::is_not_empty(doc.args)
|
||||
|| args_have_docs(doc.args)
|
||||
|| doc.return.desc != none
|
||||
|| doc.failure != none;
|
||||
ret doc;
|
||||
}
|
||||
|
||||
fn prune_args(docs: [doc::argdoc]) -> [doc::argdoc] {
|
||||
vec::filter_map(docs) {|doc|
|
||||
if option::is_some(doc.desc) {
|
||||
some(doc)
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prune_return(doc: doc::retdoc) -> doc::retdoc {
|
||||
{
|
||||
ty: if option::is_some(doc.desc) {
|
||||
doc.ty
|
||||
} else {
|
||||
none
|
||||
}
|
||||
with doc
|
||||
fn args_have_docs(docs: [doc::argdoc]) -> bool {
|
||||
vec::foldl(false, docs) {|accum, doc|
|
||||
accum || doc.desc != none
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_arguments() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] fn a(b: int) { }");
|
||||
assert vec::is_empty(doc.topmod.fns()[0].args);
|
||||
fn should_elide_fns_with_undocumented_arguments() {
|
||||
let doc = test::mk_doc("fn a(a: int) { }");
|
||||
assert vec::is_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -157,17 +138,6 @@ fn should_not_elide_fns_with_documented_arguments() {
|
|||
assert vec::is_not_empty(doc.topmod.fns());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_return_values() {
|
||||
let source = "#[doc = \"fonz\"] fn a() -> int { }";
|
||||
let srv = astsrv::mk_srv_from_str(source);
|
||||
let doc = extract::from_srv(srv, "");
|
||||
let doc = tystr_pass::mk_pass()(srv, doc);
|
||||
let doc = attr_pass::mk_pass()(srv, doc);
|
||||
let doc = run(srv, doc);
|
||||
assert doc.topmod.fns()[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_fns_with_documented_failure_conditions() {
|
||||
let doc = test::mk_doc("#[doc(failure = \"yup\")] fn a() { }");
|
||||
|
@ -252,20 +222,12 @@ fn should_not_elide_enums_with_documented_variants() {
|
|||
}
|
||||
|
||||
fn fold_res(fold: fold::fold<ctxt>, doc: doc::resdoc) -> doc::resdoc {
|
||||
let doc = {
|
||||
args: vec::filter_map(doc.args) {|arg|
|
||||
if arg.desc != none {
|
||||
some(arg)
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
with fold::default_seq_fold_res(fold, doc)
|
||||
};
|
||||
let doc = fold::default_seq_fold_res(fold, doc);
|
||||
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| vec::is_not_empty(doc.args);
|
||||
|| args_have_docs(doc.args);
|
||||
ret doc;
|
||||
}
|
||||
|
||||
|
@ -275,13 +237,6 @@ fn should_elide_undocumented_resources() {
|
|||
assert vec::is_empty(doc.topmod.resources());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_resource_args() {
|
||||
let doc = test::mk_doc("#[doc = \"drunk\"]\
|
||||
resource r(a: bool) { }");
|
||||
assert vec::is_empty(doc.topmod.resources()[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_resources_with_documented_args() {
|
||||
let doc = test::mk_doc("#[doc(args(a = \"drunk\"))]\
|
||||
|
@ -294,10 +249,7 @@ fn fold_iface(
|
|||
doc: doc::ifacedoc
|
||||
) -> doc::ifacedoc {
|
||||
let doc = fold::default_seq_fold_iface(fold, doc);
|
||||
let doc = {
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
};
|
||||
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|
@ -305,22 +257,12 @@ fn fold_iface(
|
|||
ret doc;
|
||||
}
|
||||
|
||||
fn prune_methods(docs: [doc::methoddoc]) -> [doc::methoddoc] {
|
||||
vec::map(docs) {|doc|
|
||||
{
|
||||
args: prune_args(doc.args),
|
||||
return: prune_return(doc.return)
|
||||
with doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn methods_have_docs(docs: [doc::methoddoc]) -> bool {
|
||||
vec::foldl(false, docs) {|accum, doc|
|
||||
accum
|
||||
|| doc.brief != none
|
||||
|| doc.desc != none
|
||||
|| vec::is_not_empty(doc.args)
|
||||
|| args_have_docs(doc.args)
|
||||
|| doc.return.desc != none
|
||||
|| doc.failure != none
|
||||
}
|
||||
|
@ -338,6 +280,12 @@ fn should_not_elide_documented_ifaces() {
|
|||
assert vec::is_not_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_ifaces_with_undocumented_args() {
|
||||
let doc = test::mk_doc("iface i { fn a(b: bool); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_elide_ifaces_with_documented_methods() {
|
||||
let doc = test::mk_doc("iface i { #[doc = \"hey\"] fn a(); }");
|
||||
|
@ -350,27 +298,12 @@ fn should_not_elide_undocumented_iface_methods() {
|
|||
assert vec::is_not_empty(doc.topmod.ifaces()[0].methods);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_iface_method_args() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a(); }");
|
||||
assert vec::is_empty(doc.topmod.ifaces()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_iface_method_return_values() {
|
||||
let doc = test::mk_doc("#[doc = \"hey\"] iface i { fn a() -> int; }");
|
||||
assert doc.topmod.ifaces()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
fn fold_impl(
|
||||
fold: fold::fold<ctxt>,
|
||||
doc: doc::impldoc
|
||||
) -> doc::impldoc {
|
||||
let doc = fold::default_seq_fold_impl(fold, doc);
|
||||
let doc = {
|
||||
methods: prune_methods(doc.methods)
|
||||
with doc
|
||||
};
|
||||
|
||||
fold.ctxt.have_docs =
|
||||
doc.brief != none
|
||||
|| doc.desc != none
|
||||
|
@ -402,20 +335,6 @@ fn should_not_elide_undocumented_impl_methods() {
|
|||
assert vec::is_not_empty(doc.topmod.impls()[0].methods);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_args() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a(b: bool) { } }");
|
||||
assert vec::is_empty(doc.topmod.impls()[0].methods[0].args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_elide_undocumented_impl_method_return_values() {
|
||||
let doc = test::mk_doc(
|
||||
"#[doc = \"hey\"] impl i for int { fn a() -> int { } }");
|
||||
assert doc.topmod.impls()[0].methods[0].return.ty == none;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
fn mk_doc(source: str) -> doc::cratedoc {
|
|
@ -21,7 +21,8 @@ mod fold;
|
|||
mod path_pass;
|
||||
mod attr_pass;
|
||||
mod tystr_pass;
|
||||
mod prune_undoc_pass;
|
||||
mod prune_undoc_details_pass;
|
||||
mod prune_undoc_items_pass;
|
||||
mod prune_unexported_pass;
|
||||
mod desc_to_brief_pass;
|
||||
mod desc_pass;
|
||||
|
|
|
@ -100,8 +100,9 @@ fn run(source_file: str) {
|
|||
tystr_pass::mk_pass(),
|
||||
path_pass::mk_pass(),
|
||||
attr_pass::mk_pass(),
|
||||
prune_undoc_details_pass::mk_pass(),
|
||||
// FIXME: This pass should be optional
|
||||
prune_undoc_pass::mk_pass(),
|
||||
// prune_undoc_items_pass::mk_pass(),
|
||||
desc_to_brief_pass::mk_pass(),
|
||||
trim_pass::mk_pass(),
|
||||
unindent_pass::mk_pass(),
|
||||
|
|
Loading…
Reference in a new issue