merge early and late passes into single struct

This commit is contained in:
Andy Russell 2019-02-23 15:10:56 -05:00
parent 906ec8acce
commit 1536852b42
No known key found for this signature in database
GPG key ID: BE2221033EDBC374
14 changed files with 68 additions and 138 deletions

View file

@ -214,7 +214,7 @@ impl Options {
if matches.opt_strs("passes") == ["list"] { if matches.opt_strs("passes") == ["list"] {
println!("Available passes for running rustdoc:"); println!("Available passes for running rustdoc:");
for pass in passes::PASSES { for pass in passes::PASSES {
println!("{:>20} - {}", pass.name(), pass.description()); println!("{:>20} - {}", pass.name, pass.description);
} }
println!("\nDefault passes for rustdoc:"); println!("\nDefault passes for rustdoc:");
for &name in passes::DEFAULT_PASSES { for &name in passes::DEFAULT_PASSES {

View file

@ -606,10 +606,12 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
passes::defaults(default_passes).iter().map(|p| p.to_string()).collect(); passes::defaults(default_passes).iter().map(|p| p.to_string()).collect();
passes.extend(manual_passes); passes.extend(manual_passes);
info!("Executing passes");
for pass in &passes { for pass in &passes {
// the "unknown pass" error will be reported when late passes are run match passes::find_pass(pass).map(|p| p.pass) {
if let Some(pass) = passes::find_pass(pass).and_then(|p| p.early_fn()) { Some(pass) => krate = pass(krate, &ctxt),
krate = pass(krate, &ctxt); None => error!("unknown pass {}, skipping", *pass),
} }
} }

View file

@ -441,28 +441,6 @@ where R: 'static + Send,
krate.version = crate_version; krate.version = crate_version;
info!("Executing passes");
for pass in &passes {
// determine if we know about this pass
let pass = match passes::find_pass(pass) {
Some(pass) => if let Some(pass) = pass.late_fn() {
pass
} else {
// not a late pass, but still valid so don't report the error
continue
}
None => {
error!("unknown pass {}, skipping", *pass);
continue
},
};
// run it
krate = pass(krate);
}
tx.send(f(Output { tx.send(f(Output {
krate: krate, krate: krate,
renderinfo: renderinfo, renderinfo: renderinfo,

View file

@ -10,9 +10,11 @@ use crate::fold::DocFolder;
use crate::html::markdown::{self, RustCodeBlock}; use crate::html::markdown::{self, RustCodeBlock};
use crate::passes::Pass; use crate::passes::Pass;
pub const CHECK_CODE_BLOCK_SYNTAX: Pass = pub const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
Pass::early("check-code-block-syntax", check_code_block_syntax, name: "check-code-block-syntax",
"validates syntax inside Rust code blocks"); pass: check_code_block_syntax,
description: "validates syntax inside Rust code blocks",
};
pub fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_, '_, '_>) -> clean::Crate { pub fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_, '_, '_>) -> clean::Crate {
SyntaxChecker { cx }.fold_crate(krate) SyntaxChecker { cx }.fold_crate(krate)

View file

@ -6,9 +6,11 @@ use crate::passes::Pass;
use std::mem::replace; use std::mem::replace;
pub const COLLAPSE_DOCS: Pass = pub const COLLAPSE_DOCS: Pass = Pass {
Pass::early("collapse-docs", collapse_docs, name: "collapse-docs",
"concatenates all document attributes into one document attribute"); pass: collapse_docs,
description: "concatenates all document attributes into one document attribute",
};
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum DocFragmentKind { enum DocFragmentKind {

View file

@ -18,9 +18,11 @@ use crate::passes::{look_for_tests, Pass};
use super::span_of_attrs; use super::span_of_attrs;
pub const COLLECT_INTRA_DOC_LINKS: Pass = pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
Pass::early("collect-intra-doc-links", collect_intra_doc_links, name: "collect-intra-doc-links",
"reads a crate's documentation to resolve intra-doc-links"); pass: collect_intra_doc_links,
description: "reads a crate's documentation to resolve intra-doc-links",
};
pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate { pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate {
if !UnstableFeatures::from_environment().is_nightly_build() { if !UnstableFeatures::from_environment().is_nightly_build() {

View file

@ -6,9 +6,11 @@ use super::Pass;
use rustc::util::nodemap::FxHashSet; use rustc::util::nodemap::FxHashSet;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
pub const COLLECT_TRAIT_IMPLS: Pass = pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
Pass::early("collect-trait-impls", collect_trait_impls, name: "collect-trait-impls",
"retrieves trait impls for items in the crate"); pass: collect_trait_impls,
description: "retrieves trait impls for items in the crate",
};
pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate { pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate {
let mut synth = SyntheticImplCollector::new(cx); let mut synth = SyntheticImplCollector::new(cx);

View file

@ -6,7 +6,6 @@ use rustc::lint as lint;
use rustc::middle::privacy::AccessLevels; use rustc::middle::privacy::AccessLevels;
use rustc::util::nodemap::DefIdSet; use rustc::util::nodemap::DefIdSet;
use std::mem; use std::mem;
use std::fmt;
use syntax::ast::NodeId; use syntax::ast::NodeId;
use syntax_pos::{DUMMY_SP, Span}; use syntax_pos::{DUMMY_SP, Span};
use std::ops::Range; use std::ops::Range;
@ -46,84 +45,14 @@ pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
mod check_code_block_syntax; mod check_code_block_syntax;
pub use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX; pub use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
/// Represents a single pass. /// A single pass over the cleaned documentation.
///
/// Runs in the compiler context, so it has access to types and traits and the like.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Pass { pub struct Pass {
/// An "early pass" is run in the compiler context, and can gather information about types and pub name: &'static str,
/// traits and the like. pub pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate,
EarlyPass { pub description: &'static str,
name: &'static str,
pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate,
description: &'static str,
},
/// A "late pass" is run between crate cleaning and page generation.
LatePass {
name: &'static str,
pass: fn(clean::Crate) -> clean::Crate,
description: &'static str,
},
}
impl fmt::Debug for Pass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg = match *self {
Pass::EarlyPass { .. } => f.debug_struct("EarlyPass"),
Pass::LatePass { .. } => f.debug_struct("LatePass"),
};
dbg.field("name", &self.name())
.field("pass", &"...")
.field("description", &self.description())
.finish()
}
}
impl Pass {
/// Constructs a new early pass.
pub const fn early(name: &'static str,
pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate,
description: &'static str) -> Pass {
Pass::EarlyPass { name, pass, description }
}
/// Constructs a new late pass.
pub const fn late(name: &'static str,
pass: fn(clean::Crate) -> clean::Crate,
description: &'static str) -> Pass {
Pass::LatePass { name, pass, description }
}
/// Returns the name of this pass.
pub fn name(self) -> &'static str {
match self {
Pass::EarlyPass { name, .. } |
Pass::LatePass { name, .. } => name,
}
}
/// Returns the description of this pass.
pub fn description(self) -> &'static str {
match self {
Pass::EarlyPass { description, .. } |
Pass::LatePass { description, .. } => description,
}
}
/// If this pass is an early pass, returns the pointer to its function.
pub fn early_fn(self) -> Option<fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate> {
match self {
Pass::EarlyPass { pass, .. } => Some(pass),
_ => None,
}
}
/// If this pass is a late pass, returns the pointer to its function.
pub fn late_fn(self) -> Option<fn(clean::Crate) -> clean::Crate> {
match self {
Pass::LatePass { pass, .. } => Some(pass),
_ => None,
}
}
} }
/// The full list of passes. /// The full list of passes.
@ -184,8 +113,8 @@ pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] {
} }
/// If the given name matches a known pass, returns its information. /// If the given name matches a known pass, returns its information.
pub fn find_pass(pass_name: &str) -> Option<Pass> { pub fn find_pass(pass_name: &str) -> Option<&'static Pass> {
PASSES.iter().find(|p| p.name() == pass_name).cloned() PASSES.iter().find(|p| p.name == pass_name)
} }
struct Stripper<'a> { struct Stripper<'a> {

View file

@ -3,10 +3,11 @@ use crate::core::DocContext;
use crate::fold::DocFolder; use crate::fold::DocFolder;
use crate::passes::{look_for_tests, Pass}; use crate::passes::{look_for_tests, Pass};
pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = name: "check-private-items-doc-tests",
Pass::early("check-private-items-doc-tests", check_private_items_doc_tests, pass: check_private_items_doc_tests,
"check private items doc tests"); description: "check private items doc tests",
};
struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a> { struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a> {
cx: &'a DocContext<'a, 'tcx, 'rcx>, cx: &'a DocContext<'a, 'tcx, 'rcx>,

View file

@ -2,14 +2,17 @@ use std::sync::Arc;
use crate::clean::{Crate, Item}; use crate::clean::{Crate, Item};
use crate::clean::cfg::Cfg; use crate::clean::cfg::Cfg;
use crate::core::DocContext;
use crate::fold::DocFolder; use crate::fold::DocFolder;
use crate::passes::Pass; use crate::passes::Pass;
pub const PROPAGATE_DOC_CFG: Pass = pub const PROPAGATE_DOC_CFG: Pass = Pass {
Pass::late("propagate-doc-cfg", propagate_doc_cfg, name: "propagate-doc-cfg",
"propagates `#[doc(cfg(...))]` to child items"); pass: propagate_doc_cfg,
description: "propagates `#[doc(cfg(...))]` to child items",
};
pub fn propagate_doc_cfg(cr: Crate) -> Crate { pub fn propagate_doc_cfg(cr: Crate, _: &DocContext<'_, '_, '_>) -> Crate {
CfgPropagator { parent_cfg: None }.fold_crate(cr) CfgPropagator { parent_cfg: None }.fold_crate(cr)
} }

View file

@ -7,9 +7,11 @@ use crate::core::DocContext;
use crate::fold::{DocFolder, StripItem}; use crate::fold::{DocFolder, StripItem};
use crate::passes::{ImplStripper, Pass}; use crate::passes::{ImplStripper, Pass};
pub const STRIP_HIDDEN: Pass = pub const STRIP_HIDDEN: Pass = Pass {
Pass::early("strip-hidden", strip_hidden, name: "strip-hidden",
"strips all doc(hidden) items from the output"); pass: strip_hidden,
description: "strips all doc(hidden) items from the output",
};
/// Strip items marked `#[doc(hidden)]` /// Strip items marked `#[doc(hidden)]`
pub fn strip_hidden(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { pub fn strip_hidden(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {

View file

@ -3,8 +3,11 @@ use crate::fold::{DocFolder};
use crate::core::DocContext; use crate::core::DocContext;
use crate::passes::{ImportStripper, Pass}; use crate::passes::{ImportStripper, Pass};
pub const STRIP_PRIV_IMPORTS: Pass = Pass::early("strip-priv-imports", strip_priv_imports, pub const STRIP_PRIV_IMPORTS: Pass = Pass {
"strips all private import statements (`use`, `extern crate`) from a crate"); name: "strip-priv-imports",
pass: strip_priv_imports,
description: "strips all private import statements (`use`, `extern crate`) from a crate",
};
pub fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { pub fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
ImportStripper.fold_crate(krate) ImportStripper.fold_crate(krate)

View file

@ -5,10 +5,12 @@ use crate::fold::{DocFolder};
use crate::core::DocContext; use crate::core::DocContext;
use crate::passes::{ImplStripper, ImportStripper, Stripper, Pass}; use crate::passes::{ImplStripper, ImportStripper, Stripper, Pass};
pub const STRIP_PRIVATE: Pass = pub const STRIP_PRIVATE: Pass = Pass {
Pass::early("strip-private", strip_private, name: "strip-private",
"strips all private items from a crate which cannot be seen externally, \ pass: strip_private,
implies strip-priv-imports"); description: "strips all private items from a crate which cannot be seen externally, \
implies strip-priv-imports",
};
/// Strip private items from the point of view of a crate or externally from a /// Strip private items from the point of view of a crate or externally from a
/// crate, specified by the `xcrate` flag. /// crate, specified by the `xcrate` flag.

View file

@ -7,9 +7,11 @@ use crate::core::DocContext;
use crate::fold::{self, DocFolder}; use crate::fold::{self, DocFolder};
use crate::passes::Pass; use crate::passes::Pass;
pub const UNINDENT_COMMENTS: Pass = pub const UNINDENT_COMMENTS: Pass = Pass {
Pass::early("unindent-comments", unindent_comments, name: "unindent-comments",
"removes excess indentation on comments in order for markdown to like it"); pass: unindent_comments,
description: "removes excess indentation on comments in order for markdown to like it",
};
pub fn unindent_comments(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate { pub fn unindent_comments(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
CommentCleaner.fold_crate(krate) CommentCleaner.fold_crate(krate)