Skip to content

Commit

Permalink
Rollup merge of rust-lang#58627 - euclio:rustdoc-pass-order, r=QuietM…
Browse files Browse the repository at this point in the history
…isdreavus

rustdoc: move collapse and unindent docs passes earlier

Moves these passes as early as possible so later passes will see the same markdown that is passed to the test collector.

Fixes rust-lang#58473, and a similar issue with the private-doc-tests lint.

r? @QuietMisdreavus
  • Loading branch information
Centril committed Feb 27, 2019
2 parents 5418e2a + 1536852 commit bcc7ec1
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 152 deletions.
2 changes: 1 addition & 1 deletion src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ impl Options {
if matches.opt_strs("passes") == ["list"] {
println!("Available passes for running rustdoc:");
for pass in passes::PASSES {
println!("{:>20} - {}", pass.name(), pass.description());
println!("{:>20} - {}", pass.name, pass.description);
}
println!("\nDefault passes for rustdoc:");
for &name in passes::DEFAULT_PASSES {
Expand Down
8 changes: 5 additions & 3 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,10 +603,12 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
passes::defaults(default_passes).iter().map(|p| p.to_string()).collect();
passes.extend(manual_passes);

info!("Executing passes");

for pass in &passes {
// the "unknown pass" error will be reported when late passes are run
if let Some(pass) = passes::find_pass(pass).and_then(|p| p.early_fn()) {
krate = pass(krate, &ctxt);
match passes::find_pass(pass).map(|p| p.pass) {
Some(pass) => krate = pass(krate, &ctxt),
None => error!("unknown pass {}, skipping", *pass),
}
}

Expand Down
22 changes: 0 additions & 22 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,28 +441,6 @@ where R: 'static + Send,

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 {
krate: krate,
renderinfo: renderinfo,
Expand Down
8 changes: 5 additions & 3 deletions src/librustdoc/passes/check_code_block_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ use crate::fold::DocFolder;
use crate::html::markdown::{self, RustCodeBlock};
use crate::passes::Pass;

pub const CHECK_CODE_BLOCK_SYNTAX: Pass =
Pass::early("check-code-block-syntax", check_code_block_syntax,
"validates syntax inside Rust code blocks");
pub const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
name: "check-code-block-syntax",
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 {
SyntaxChecker { cx }.fold_crate(krate)
Expand Down
11 changes: 7 additions & 4 deletions src/librustdoc/passes/collapse_docs.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::clean::{self, DocFragment, Item};
use crate::core::DocContext;
use crate::fold;
use crate::fold::{DocFolder};
use crate::passes::Pass;

use std::mem::replace;

pub const COLLAPSE_DOCS: Pass =
Pass::late("collapse-docs", collapse_docs,
"concatenates all document attributes into one document attribute");
pub const COLLAPSE_DOCS: Pass = Pass {
name: "collapse-docs",
pass: collapse_docs,
description: "concatenates all document attributes into one document attribute",
};

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum DocFragmentKind {
Expand All @@ -26,7 +29,7 @@ impl DocFragment {
}
}

pub fn collapse_docs(krate: clean::Crate) -> clean::Crate {
pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
Collapser.fold_crate(krate)
}

Expand Down
8 changes: 5 additions & 3 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ use crate::passes::{look_for_tests, Pass};

use super::span_of_attrs;

pub const COLLECT_INTRA_DOC_LINKS: Pass =
Pass::early("collect-intra-doc-links", collect_intra_doc_links,
"reads a crate's documentation to resolve intra-doc-links");
pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
name: "collect-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 {
if !UnstableFeatures::from_environment().is_nightly_build() {
Expand Down
8 changes: 5 additions & 3 deletions src/librustdoc/passes/collect_trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ use super::Pass;
use rustc::util::nodemap::FxHashSet;
use rustc::hir::def_id::DefId;

pub const COLLECT_TRAIT_IMPLS: Pass =
Pass::early("collect-trait-impls", collect_trait_impls,
"retrieves trait impls for items in the crate");
pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
name: "collect-trait-impls",
pass: collect_trait_impls,
description: "retrieves trait impls for items in the crate",
};

pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_, '_, '_>) -> Crate {
let mut synth = SyntheticImplCollector::new(cx);
Expand Down
109 changes: 19 additions & 90 deletions src/librustdoc/passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use rustc::lint as lint;
use rustc::middle::privacy::AccessLevels;
use rustc::util::nodemap::DefIdSet;
use std::mem;
use std::fmt;
use syntax::ast::NodeId;
use syntax_pos::{DUMMY_SP, Span};
use std::ops::Range;
Expand Down Expand Up @@ -46,84 +45,14 @@ pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
mod 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)]
pub enum Pass {
/// An "early pass" is run in the compiler context, and can gather information about types and
/// traits and the like.
EarlyPass {
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,
}
}
pub struct Pass {
pub name: &'static str,
pub pass: fn(clean::Crate, &DocContext<'_, '_, '_>) -> clean::Crate,
pub description: &'static str,
}

/// The full list of passes.
Expand All @@ -141,27 +70,27 @@ pub const PASSES: &'static [Pass] = &[
];

/// The list of passes run by default.
pub const DEFAULT_PASSES: &'static [&'static str] = &[
pub const DEFAULT_PASSES: &[&str] = &[
"collect-trait-impls",
"collapse-docs",
"unindent-comments",
"check-private-items-doc-tests",
"strip-hidden",
"strip-private",
"collect-intra-doc-links",
"check-code-block-syntax",
"collapse-docs",
"unindent-comments",
"propagate-doc-cfg",
];

/// The list of default passes run with `--document-private-items` is passed to rustdoc.
pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[
pub const DEFAULT_PRIVATE_PASSES: &[&str] = &[
"collect-trait-impls",
"collapse-docs",
"unindent-comments",
"check-private-items-doc-tests",
"strip-priv-imports",
"collect-intra-doc-links",
"check-code-block-syntax",
"collapse-docs",
"unindent-comments",
"propagate-doc-cfg",
];

Expand All @@ -184,8 +113,8 @@ pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] {
}

/// If the given name matches a known pass, returns its information.
pub fn find_pass(pass_name: &str) -> Option<Pass> {
PASSES.iter().find(|p| p.name() == pass_name).cloned()
pub fn find_pass(pass_name: &str) -> Option<&'static Pass> {
PASSES.iter().find(|p| p.name == pass_name)
}

struct Stripper<'a> {
Expand Down Expand Up @@ -438,11 +367,11 @@ crate fn source_span_for_markdown_range(
.span_to_snippet(span_of_attrs(attrs))
.ok()?;

let starting_line = markdown[..md_range.start].lines().count() - 1;
let ending_line = markdown[..md_range.end].lines().count() - 1;
let starting_line = markdown[..md_range.start].matches('\n').count();
let ending_line = starting_line + markdown[md_range.start..md_range.end].matches('\n').count();

// We use `split_terminator('\n')` instead of `lines()` when counting bytes so that we only
// we can treat CRLF and LF line endings the same way.
// We use `split_terminator('\n')` instead of `lines()` when counting bytes so that we treat
// CRLF and LF line endings the same way.
let mut src_lines = snippet.split_terminator('\n');
let md_lines = markdown.split_terminator('\n');

Expand Down
9 changes: 5 additions & 4 deletions src/librustdoc/passes/private_items_doc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use crate::core::DocContext;
use crate::fold::DocFolder;
use crate::passes::{look_for_tests, Pass};


pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass =
Pass::early("check-private-items-doc-tests", check_private_items_doc_tests,
"check private items doc tests");
pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
name: "check-private-items-doc-tests",
pass: check_private_items_doc_tests,
description: "check private items doc tests",
};

struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a> {
cx: &'a DocContext<'a, 'tcx, 'rcx>,
Expand Down
11 changes: 7 additions & 4 deletions src/librustdoc/passes/propagate_doc_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ use std::sync::Arc;

use crate::clean::{Crate, Item};
use crate::clean::cfg::Cfg;
use crate::core::DocContext;
use crate::fold::DocFolder;
use crate::passes::Pass;

pub const PROPAGATE_DOC_CFG: Pass =
Pass::late("propagate-doc-cfg", propagate_doc_cfg,
"propagates `#[doc(cfg(...))]` to child items");
pub const PROPAGATE_DOC_CFG: Pass = Pass {
name: "propagate-doc-cfg",
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)
}

Expand Down
8 changes: 5 additions & 3 deletions src/librustdoc/passes/strip_hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use crate::core::DocContext;
use crate::fold::{DocFolder, StripItem};
use crate::passes::{ImplStripper, Pass};

pub const STRIP_HIDDEN: Pass =
Pass::early("strip-hidden", strip_hidden,
"strips all doc(hidden) items from the output");
pub const STRIP_HIDDEN: Pass = Pass {
name: "strip-hidden",
pass: strip_hidden,
description: "strips all doc(hidden) items from the output",
};

/// Strip items marked `#[doc(hidden)]`
pub fn strip_hidden(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
Expand Down
7 changes: 5 additions & 2 deletions src/librustdoc/passes/strip_priv_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ use crate::fold::{DocFolder};
use crate::core::DocContext;
use crate::passes::{ImportStripper, Pass};

pub const STRIP_PRIV_IMPORTS: Pass = Pass::early("strip-priv-imports", strip_priv_imports,
"strips all private import statements (`use`, `extern crate`) from a crate");
pub const STRIP_PRIV_IMPORTS: Pass = Pass {
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 {
ImportStripper.fold_crate(krate)
Expand Down
10 changes: 6 additions & 4 deletions src/librustdoc/passes/strip_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use crate::fold::{DocFolder};
use crate::core::DocContext;
use crate::passes::{ImplStripper, ImportStripper, Stripper, Pass};

pub const STRIP_PRIVATE: Pass =
Pass::early("strip-private", strip_private,
"strips all private items from a crate which cannot be seen externally, \
implies strip-priv-imports");
pub const STRIP_PRIVATE: Pass = Pass {
name: "strip-private",
pass: strip_private,
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
/// crate, specified by the `xcrate` flag.
Expand Down
11 changes: 7 additions & 4 deletions src/librustdoc/passes/unindent_comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ use std::string::String;
use std::usize;

use crate::clean::{self, DocFragment, Item};
use crate::core::DocContext;
use crate::fold::{self, DocFolder};
use crate::passes::Pass;

pub const UNINDENT_COMMENTS: Pass =
Pass::late("unindent-comments", unindent_comments,
"removes excess indentation on comments in order for markdown to like it");
pub const UNINDENT_COMMENTS: Pass = Pass {
name: "unindent-comments",
pass: unindent_comments,
description: "removes excess indentation on comments in order for markdown to like it",
};

pub fn unindent_comments(krate: clean::Crate) -> clean::Crate {
pub fn unindent_comments(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
CommentCleaner.fold_crate(krate)
}

Expand Down
Loading

0 comments on commit bcc7ec1

Please sign in to comment.