Skip to content

Commit

Permalink
Auto merge of #55515 - QuietMisdreavus:rustdoc-config, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
rustdoc: refactor: centralize all command-line argument parsing

This is something i've wanted to do for a while, since we keep having to add new arguments to places like `rust_input` or `core::run_core` whenever we add a new CLI flag or the like. Those functions have inflated up to 11-19, and in some cases hiding away the locations where some CLI flags were being parsed, obscuring their use. Now, we have a central place where all command-line configuration occurs, including argument validation.

One note about the design: i grouped together all the arguments that `html::render::run` needed, so that i could pass them on from compilation in one lump instead of trying to thread through individual items or clone the entire blob ahead of time.

One other thing this adds is that rustdoc also now recognizes all the `-Z` options that rustc does, since we were manually grabbing a few previously. Now we parse a full `DebuggingOptions` struct and hand it directly to rustc when scraping docs.
  • Loading branch information
bors committed Nov 5, 2018
2 parents 56ac2c4 + 560a01c commit 6cfc603
Show file tree
Hide file tree
Showing 9 changed files with 729 additions and 554 deletions.
560 changes: 560 additions & 0 deletions src/librustdoc/config.rs

Large diffs are not rendered by default.

77 changes: 36 additions & 41 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use rustc_target::spec::TargetTriple;

use syntax::ast::{self, Ident, NodeId};
use syntax::source_map;
use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
use syntax::json::JsonEmitter;
use syntax::ptr::P;
Expand All @@ -43,9 +42,9 @@ use std::mem;
use rustc_data_structures::sync::{self, Lrc};
use std::rc::Rc;
use std::sync::Arc;
use std::path::PathBuf;

use visit_ast::RustdocVisitor;
use config::{Options as RustdocOptions, RenderOptions};
use clean;
use clean::{get_path_for_type, Clean, MAX_DEF_ID, AttributesExt};
use html::render::RenderInfo;
Expand Down Expand Up @@ -320,32 +319,33 @@ pub fn new_handler(error_format: ErrorOutputType,
)
}

pub fn run_core(search_paths: SearchPaths,
cfgs: Vec<String>,
externs: config::Externs,
input: Input,
triple: Option<TargetTriple>,
maybe_sysroot: Option<PathBuf>,
allow_warnings: bool,
crate_name: Option<String>,
force_unstable_if_unmarked: bool,
edition: Edition,
cg: CodegenOptions,
error_format: ErrorOutputType,
cmd_lints: Vec<(String, lint::Level)>,
lint_cap: Option<lint::Level>,
describe_lints: bool,
mut manual_passes: Vec<String>,
mut default_passes: passes::DefaultPassOption,
treat_err_as_bug: bool,
ui_testing: bool,
) -> (clean::Crate, RenderInfo, Vec<String>) {
pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions, Vec<String>) {
// Parse, resolve, and typecheck the given crate.

let cpath = match input {
Input::File(ref p) => Some(p.clone()),
_ => None
};
let RustdocOptions {
input,
crate_name,
error_format,
libs,
externs,
cfgs,
codegen_options,
debugging_options,
target,
edition,
maybe_sysroot,
lint_opts,
describe_lints,
lint_cap,
mut default_passes,
mut manual_passes,
display_warnings,
render_options,
..
} = options;

let cpath = Some(input.clone());
let input = Input::File(input);

let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
let warnings_lint_name = lint::builtin::WARNINGS.name;
Expand All @@ -359,7 +359,7 @@ pub fn run_core(search_paths: SearchPaths,
missing_docs.to_owned(),
missing_doc_example.to_owned()];

whitelisted_lints.extend(cmd_lints.iter().map(|(lint, _)| lint).cloned());
whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());

let lints = lint::builtin::HardwiredLints.get_lints()
.into_iter()
Expand All @@ -372,33 +372,28 @@ pub fn run_core(search_paths: SearchPaths,
Some((lint.name_lower(), lint::Allow))
}
})
.chain(cmd_lints.into_iter())
.chain(lint_opts.into_iter())
.collect::<Vec<_>>();

let host_triple = TargetTriple::from_triple(config::host_triple());
// plays with error output here!
let sessopts = config::Options {
maybe_sysroot,
search_paths,
search_paths: libs,
crate_types: vec![config::CrateType::Rlib],
lint_opts: if !allow_warnings {
lint_opts: if !display_warnings {
lints
} else {
vec![]
},
lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
cg,
cg: codegen_options,
externs,
target_triple: triple.unwrap_or(host_triple),
target_triple: target.unwrap_or(host_triple),
// Ensure that rustdoc works even if rustc is feature-staged
unstable_features: UnstableFeatures::Allow,
actually_rustdoc: true,
debugging_opts: config::DebuggingOptions {
force_unstable_if_unmarked,
treat_err_as_bug,
ui_testing,
..config::basic_debugging_options()
},
debugging_opts: debugging_options.clone(),
error_format,
edition,
describe_lints,
Expand All @@ -408,8 +403,8 @@ pub fn run_core(search_paths: SearchPaths,
let source_map = Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping()));
let diagnostic_handler = new_handler(error_format,
Some(source_map.clone()),
treat_err_as_bug,
ui_testing);
debugging_options.treat_err_as_bug,
debugging_options.ui_testing);

let mut sess = session::build_session_(
sessopts, cpath, diagnostic_handler, source_map,
Expand Down Expand Up @@ -621,7 +616,7 @@ pub fn run_core(search_paths: SearchPaths,

ctxt.sess().abort_if_errors();

(krate, ctxt.renderinfo.into_inner(), passes)
(krate, ctxt.renderinfo.into_inner(), render_options, passes)
}), &sess)
})
}
2 changes: 1 addition & 1 deletion src/librustdoc/externalfiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use syntax::feature_gate::UnstableFeatures;
use html::markdown::{IdMap, ErrorCodes, Markdown};
use std::cell::RefCell;

#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct ExternalHtml {
/// Content that will be included inline in the <head> section of a
/// rendered Markdown file or generated documentation
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
links
}

#[derive(Default)]
#[derive(Clone, Default, Debug)]
pub struct IdMap {
map: FxHashMap<String, usize>,
}
Expand Down
89 changes: 42 additions & 47 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ use std::str;
use std::sync::Arc;
use std::rc::Rc;

use externalfiles::ExternalHtml;

use errors;
use getopts;

use serialize::json::{ToJson, Json, as_json};
use syntax::ast;
use syntax::ext::base::MacroKind;
Expand All @@ -70,6 +66,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::flock;

use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
use config::RenderOptions;
use doctree;
use fold::DocFolder;
use html::escape::Escape;
Expand Down Expand Up @@ -109,8 +106,6 @@ struct Context {
/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
pub shared: Arc<SharedContext>,
pub enable_index_page: bool,
pub index_page: Option<PathBuf>,
}

struct SharedContext {
Expand Down Expand Up @@ -495,23 +490,25 @@ pub fn initial_ids() -> Vec<String> {

/// Generates the documentation for `crate` into the directory `dst`
pub fn run(mut krate: clean::Crate,
extern_urls: BTreeMap<String, String>,
external_html: &ExternalHtml,
playground_url: Option<String>,
dst: PathBuf,
resource_suffix: String,
options: RenderOptions,
passes: FxHashSet<String>,
css_file_extension: Option<PathBuf>,
renderinfo: RenderInfo,
sort_modules_alphabetically: bool,
themes: Vec<PathBuf>,
enable_minification: bool,
id_map: IdMap,
enable_index_page: bool,
index_page: Option<PathBuf>,
matches: &getopts::Matches,
diag: &errors::Handler,
) -> Result<(), Error> {
diag: &errors::Handler) -> Result<(), Error> {
// need to save a copy of the options for rendering the index page
let md_opts = options.clone();
let RenderOptions {
output,
external_html,
id_map,
playground_url,
sort_modules_alphabetically,
themes,
extension_css,
extern_html_root_urls,
resource_suffix,
..
} = options;

let src_root = match krate.src {
FileName::Real(ref p) => match p.parent() {
Some(p) => p.to_path_buf(),
Expand All @@ -528,10 +525,10 @@ pub fn run(mut krate: clean::Crate,
layout: layout::Layout {
logo: String::new(),
favicon: String::new(),
external_html: external_html.clone(),
external_html,
krate: krate.name.clone(),
},
css_file_extension,
css_file_extension: extension_css,
created_dirs: Default::default(),
sort_modules_alphabetically,
themes,
Expand Down Expand Up @@ -573,6 +570,7 @@ pub fn run(mut krate: clean::Crate,
}
}
}
let dst = output;
try_err!(fs::create_dir_all(&dst), &dst);
krate = render_sources(&dst, &mut scx, krate)?;
let cx = Context {
Expand All @@ -582,8 +580,6 @@ pub fn run(mut krate: clean::Crate,
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
id_map: Rc::new(RefCell::new(id_map)),
shared: Arc::new(scx),
enable_index_page,
index_page,
};

// Crawl the crate to build various caches used for the output
Expand Down Expand Up @@ -637,7 +633,7 @@ pub fn run(mut krate: clean::Crate,
},
_ => PathBuf::new(),
};
let extern_url = extern_urls.get(&e.name).map(|u| &**u);
let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u);
cache.extern_locations.insert(n, (e.name.clone(), src_root,
extern_location(e, extern_url, &cx.dst)));

Expand Down Expand Up @@ -678,7 +674,7 @@ pub fn run(mut krate: clean::Crate,
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());

write_shared(&cx, &krate, &*cache, index, enable_minification, matches, diag)?;
write_shared(&cx, &krate, &*cache, index, &md_opts, diag)?;

// And finally render the whole crate's documentation
cx.krate(krate)
Expand Down Expand Up @@ -759,8 +755,7 @@ fn write_shared(
krate: &clean::Crate,
cache: &Cache,
search_index: String,
enable_minification: bool,
matches: &getopts::Matches,
options: &RenderOptions,
diag: &errors::Handler,
) -> Result<(), Error> {
// Write out the shared files. Note that these are shared among all rustdoc
Expand All @@ -773,10 +768,10 @@ fn write_shared(

write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
include_str!("static/rustdoc.css"),
enable_minification)?;
options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
include_str!("static/settings.css"),
enable_minification)?;
options.enable_minification)?;

// To avoid "light.css" to be overwritten, we'll first run over the received themes and only
// then we'll run over the "official" styles.
Expand All @@ -800,11 +795,11 @@ fn write_shared(
include_bytes!("static/wheel.svg"))?;
write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/light.css"),
enable_minification)?;
options.enable_minification)?;
themes.insert("light".to_owned());
write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/dark.css"),
enable_minification)?;
options.enable_minification)?;
themes.insert("dark".to_owned());

let mut themes: Vec<&String> = themes.iter().collect();
Expand Down Expand Up @@ -860,35 +855,35 @@ themePicker.onblur = handleThemeButtonsBlur;

write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
include_str!("static/main.js"),
enable_minification)?;
options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
include_str!("static/settings.js"),
enable_minification)?;
options.enable_minification)?;

{
let mut data = format!("var resourcesSuffix = \"{}\";\n",
cx.shared.resource_suffix);
data.push_str(include_str!("static/storage.js"));
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
&data,
enable_minification)?;
options.enable_minification)?;
}

if let Some(ref css) = cx.shared.css_file_extension {
let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
if !enable_minification {
if !options.enable_minification {
try_err!(fs::copy(css, out), css);
} else {
let mut f = try_err!(File::open(css), css);
let mut buffer = String::with_capacity(1000);

try_err!(f.read_to_string(&mut buffer), css);
write_minify(out, &buffer, enable_minification)?;
write_minify(out, &buffer, options.enable_minification)?;
}
}
write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
include_str!("static/normalize.css"),
enable_minification)?;
options.enable_minification)?;
write(cx.dst.join("FiraSans-Regular.woff"),
include_bytes!("static/FiraSans-Regular.woff"))?;
write(cx.dst.join("FiraSans-Medium.woff"),
Expand Down Expand Up @@ -984,19 +979,19 @@ themePicker.onblur = handleThemeButtonsBlur;
let mut w = try_err!(File::create(&dst), &dst);
try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst);
for index in &all_indexes {
try_err!(write_minify_replacer(&mut w, &*index, enable_minification,
try_err!(write_minify_replacer(&mut w, &*index, options.enable_minification,
&[(minifier::js::Keyword::Null, "N")]),
&dst);
}
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);

if cx.enable_index_page == true {
if let Some(ref index_page) = cx.index_page {
::markdown::render(index_page,
cx.dst.clone(),
&matches, &(*cx.shared).layout.external_html,
!matches.opt_present("markdown-no-toc"),
diag);
if options.enable_index_page {
if let Some(index_page) = options.index_page.clone() {
let mut md_opts = options.clone();
md_opts.output = cx.dst.clone();
md_opts.external_html = (*cx.shared).layout.external_html.clone();

::markdown::render(index_page, md_opts, diag);
} else {
let dst = cx.dst.join("index.html");
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
Expand Down
Loading

0 comments on commit 6cfc603

Please sign in to comment.