Skip to content

Commit 6cfc603

Browse files
committed
Auto merge of #55515 - QuietMisdreavus:rustdoc-config, r=GuillaumeGomez
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.
2 parents 56ac2c4 + 560a01c commit 6cfc603

File tree

9 files changed

+729
-554
lines changed

9 files changed

+729
-554
lines changed

Diff for: src/librustdoc/config.rs

+560
Large diffs are not rendered by default.

Diff for: src/librustdoc/core.rs

+36-41
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use rustc_target::spec::TargetTriple;
2828

2929
use syntax::ast::{self, Ident, NodeId};
3030
use syntax::source_map;
31-
use syntax::edition::Edition;
3231
use syntax::feature_gate::UnstableFeatures;
3332
use syntax::json::JsonEmitter;
3433
use syntax::ptr::P;
@@ -43,9 +42,9 @@ use std::mem;
4342
use rustc_data_structures::sync::{self, Lrc};
4443
use std::rc::Rc;
4544
use std::sync::Arc;
46-
use std::path::PathBuf;
4745

4846
use visit_ast::RustdocVisitor;
47+
use config::{Options as RustdocOptions, RenderOptions};
4948
use clean;
5049
use clean::{get_path_for_type, Clean, MAX_DEF_ID, AttributesExt};
5150
use html::render::RenderInfo;
@@ -320,32 +319,33 @@ pub fn new_handler(error_format: ErrorOutputType,
320319
)
321320
}
322321

323-
pub fn run_core(search_paths: SearchPaths,
324-
cfgs: Vec<String>,
325-
externs: config::Externs,
326-
input: Input,
327-
triple: Option<TargetTriple>,
328-
maybe_sysroot: Option<PathBuf>,
329-
allow_warnings: bool,
330-
crate_name: Option<String>,
331-
force_unstable_if_unmarked: bool,
332-
edition: Edition,
333-
cg: CodegenOptions,
334-
error_format: ErrorOutputType,
335-
cmd_lints: Vec<(String, lint::Level)>,
336-
lint_cap: Option<lint::Level>,
337-
describe_lints: bool,
338-
mut manual_passes: Vec<String>,
339-
mut default_passes: passes::DefaultPassOption,
340-
treat_err_as_bug: bool,
341-
ui_testing: bool,
342-
) -> (clean::Crate, RenderInfo, Vec<String>) {
322+
pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions, Vec<String>) {
343323
// Parse, resolve, and typecheck the given crate.
344324

345-
let cpath = match input {
346-
Input::File(ref p) => Some(p.clone()),
347-
_ => None
348-
};
325+
let RustdocOptions {
326+
input,
327+
crate_name,
328+
error_format,
329+
libs,
330+
externs,
331+
cfgs,
332+
codegen_options,
333+
debugging_options,
334+
target,
335+
edition,
336+
maybe_sysroot,
337+
lint_opts,
338+
describe_lints,
339+
lint_cap,
340+
mut default_passes,
341+
mut manual_passes,
342+
display_warnings,
343+
render_options,
344+
..
345+
} = options;
346+
347+
let cpath = Some(input.clone());
348+
let input = Input::File(input);
349349

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

362-
whitelisted_lints.extend(cmd_lints.iter().map(|(lint, _)| lint).cloned());
362+
whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
363363

364364
let lints = lint::builtin::HardwiredLints.get_lints()
365365
.into_iter()
@@ -372,33 +372,28 @@ pub fn run_core(search_paths: SearchPaths,
372372
Some((lint.name_lower(), lint::Allow))
373373
}
374374
})
375-
.chain(cmd_lints.into_iter())
375+
.chain(lint_opts.into_iter())
376376
.collect::<Vec<_>>();
377377

378378
let host_triple = TargetTriple::from_triple(config::host_triple());
379379
// plays with error output here!
380380
let sessopts = config::Options {
381381
maybe_sysroot,
382-
search_paths,
382+
search_paths: libs,
383383
crate_types: vec![config::CrateType::Rlib],
384-
lint_opts: if !allow_warnings {
384+
lint_opts: if !display_warnings {
385385
lints
386386
} else {
387387
vec![]
388388
},
389389
lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
390-
cg,
390+
cg: codegen_options,
391391
externs,
392-
target_triple: triple.unwrap_or(host_triple),
392+
target_triple: target.unwrap_or(host_triple),
393393
// Ensure that rustdoc works even if rustc is feature-staged
394394
unstable_features: UnstableFeatures::Allow,
395395
actually_rustdoc: true,
396-
debugging_opts: config::DebuggingOptions {
397-
force_unstable_if_unmarked,
398-
treat_err_as_bug,
399-
ui_testing,
400-
..config::basic_debugging_options()
401-
},
396+
debugging_opts: debugging_options.clone(),
402397
error_format,
403398
edition,
404399
describe_lints,
@@ -408,8 +403,8 @@ pub fn run_core(search_paths: SearchPaths,
408403
let source_map = Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping()));
409404
let diagnostic_handler = new_handler(error_format,
410405
Some(source_map.clone()),
411-
treat_err_as_bug,
412-
ui_testing);
406+
debugging_options.treat_err_as_bug,
407+
debugging_options.ui_testing);
413408

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

622617
ctxt.sess().abort_if_errors();
623618

624-
(krate, ctxt.renderinfo.into_inner(), passes)
619+
(krate, ctxt.renderinfo.into_inner(), render_options, passes)
625620
}), &sess)
626621
})
627622
}

Diff for: src/librustdoc/externalfiles.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use syntax::feature_gate::UnstableFeatures;
1616
use html::markdown::{IdMap, ErrorCodes, Markdown};
1717
use std::cell::RefCell;
1818

19-
#[derive(Clone)]
19+
#[derive(Clone, Debug)]
2020
pub struct ExternalHtml {
2121
/// Content that will be included inline in the <head> section of a
2222
/// rendered Markdown file or generated documentation

Diff for: src/librustdoc/html/markdown.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
905905
links
906906
}
907907

908-
#[derive(Default)]
908+
#[derive(Clone, Default, Debug)]
909909
pub struct IdMap {
910910
map: FxHashMap<String, usize>,
911911
}

Diff for: src/librustdoc/html/render.rs

+42-47
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ use std::str;
5252
use std::sync::Arc;
5353
use std::rc::Rc;
5454

55-
use externalfiles::ExternalHtml;
56-
5755
use errors;
58-
use getopts;
59-
6056
use serialize::json::{ToJson, Json, as_json};
6157
use syntax::ast;
6258
use syntax::ext::base::MacroKind;
@@ -70,6 +66,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
7066
use rustc_data_structures::flock;
7167

7268
use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
69+
use config::RenderOptions;
7370
use doctree;
7471
use fold::DocFolder;
7572
use html::escape::Escape;
@@ -109,8 +106,6 @@ struct Context {
109106
/// The map used to ensure all generated 'id=' attributes are unique.
110107
id_map: Rc<RefCell<IdMap>>,
111108
pub shared: Arc<SharedContext>,
112-
pub enable_index_page: bool,
113-
pub index_page: Option<PathBuf>,
114109
}
115110

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

496491
/// Generates the documentation for `crate` into the directory `dst`
497492
pub fn run(mut krate: clean::Crate,
498-
extern_urls: BTreeMap<String, String>,
499-
external_html: &ExternalHtml,
500-
playground_url: Option<String>,
501-
dst: PathBuf,
502-
resource_suffix: String,
493+
options: RenderOptions,
503494
passes: FxHashSet<String>,
504-
css_file_extension: Option<PathBuf>,
505495
renderinfo: RenderInfo,
506-
sort_modules_alphabetically: bool,
507-
themes: Vec<PathBuf>,
508-
enable_minification: bool,
509-
id_map: IdMap,
510-
enable_index_page: bool,
511-
index_page: Option<PathBuf>,
512-
matches: &getopts::Matches,
513-
diag: &errors::Handler,
514-
) -> Result<(), Error> {
496+
diag: &errors::Handler) -> Result<(), Error> {
497+
// need to save a copy of the options for rendering the index page
498+
let md_opts = options.clone();
499+
let RenderOptions {
500+
output,
501+
external_html,
502+
id_map,
503+
playground_url,
504+
sort_modules_alphabetically,
505+
themes,
506+
extension_css,
507+
extern_html_root_urls,
508+
resource_suffix,
509+
..
510+
} = options;
511+
515512
let src_root = match krate.src {
516513
FileName::Real(ref p) => match p.parent() {
517514
Some(p) => p.to_path_buf(),
@@ -528,10 +525,10 @@ pub fn run(mut krate: clean::Crate,
528525
layout: layout::Layout {
529526
logo: String::new(),
530527
favicon: String::new(),
531-
external_html: external_html.clone(),
528+
external_html,
532529
krate: krate.name.clone(),
533530
},
534-
css_file_extension,
531+
css_file_extension: extension_css,
535532
created_dirs: Default::default(),
536533
sort_modules_alphabetically,
537534
themes,
@@ -573,6 +570,7 @@ pub fn run(mut krate: clean::Crate,
573570
}
574571
}
575572
}
573+
let dst = output;
576574
try_err!(fs::create_dir_all(&dst), &dst);
577575
krate = render_sources(&dst, &mut scx, krate)?;
578576
let cx = Context {
@@ -582,8 +580,6 @@ pub fn run(mut krate: clean::Crate,
582580
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
583581
id_map: Rc::new(RefCell::new(id_map)),
584582
shared: Arc::new(scx),
585-
enable_index_page,
586-
index_page,
587583
};
588584

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

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

681-
write_shared(&cx, &krate, &*cache, index, enable_minification, matches, diag)?;
677+
write_shared(&cx, &krate, &*cache, index, &md_opts, diag)?;
682678

683679
// And finally render the whole crate's documentation
684680
cx.krate(krate)
@@ -759,8 +755,7 @@ fn write_shared(
759755
krate: &clean::Crate,
760756
cache: &Cache,
761757
search_index: String,
762-
enable_minification: bool,
763-
matches: &getopts::Matches,
758+
options: &RenderOptions,
764759
diag: &errors::Handler,
765760
) -> Result<(), Error> {
766761
// Write out the shared files. Note that these are shared among all rustdoc
@@ -773,10 +768,10 @@ fn write_shared(
773768

774769
write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
775770
include_str!("static/rustdoc.css"),
776-
enable_minification)?;
771+
options.enable_minification)?;
777772
write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
778773
include_str!("static/settings.css"),
779-
enable_minification)?;
774+
options.enable_minification)?;
780775

781776
// To avoid "light.css" to be overwritten, we'll first run over the received themes and only
782777
// then we'll run over the "official" styles.
@@ -800,11 +795,11 @@ fn write_shared(
800795
include_bytes!("static/wheel.svg"))?;
801796
write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
802797
include_str!("static/themes/light.css"),
803-
enable_minification)?;
798+
options.enable_minification)?;
804799
themes.insert("light".to_owned());
805800
write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
806801
include_str!("static/themes/dark.css"),
807-
enable_minification)?;
802+
options.enable_minification)?;
808803
themes.insert("dark".to_owned());
809804

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

861856
write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
862857
include_str!("static/main.js"),
863-
enable_minification)?;
858+
options.enable_minification)?;
864859
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
865860
include_str!("static/settings.js"),
866-
enable_minification)?;
861+
options.enable_minification)?;
867862

868863
{
869864
let mut data = format!("var resourcesSuffix = \"{}\";\n",
870865
cx.shared.resource_suffix);
871866
data.push_str(include_str!("static/storage.js"));
872867
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
873868
&data,
874-
enable_minification)?;
869+
options.enable_minification)?;
875870
}
876871

877872
if let Some(ref css) = cx.shared.css_file_extension {
878873
let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
879-
if !enable_minification {
874+
if !options.enable_minification {
880875
try_err!(fs::copy(css, out), css);
881876
} else {
882877
let mut f = try_err!(File::open(css), css);
883878
let mut buffer = String::with_capacity(1000);
884879

885880
try_err!(f.read_to_string(&mut buffer), css);
886-
write_minify(out, &buffer, enable_minification)?;
881+
write_minify(out, &buffer, options.enable_minification)?;
887882
}
888883
}
889884
write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
890885
include_str!("static/normalize.css"),
891-
enable_minification)?;
886+
options.enable_minification)?;
892887
write(cx.dst.join("FiraSans-Regular.woff"),
893888
include_bytes!("static/FiraSans-Regular.woff"))?;
894889
write(cx.dst.join("FiraSans-Medium.woff"),
@@ -984,19 +979,19 @@ themePicker.onblur = handleThemeButtonsBlur;
984979
let mut w = try_err!(File::create(&dst), &dst);
985980
try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst);
986981
for index in &all_indexes {
987-
try_err!(write_minify_replacer(&mut w, &*index, enable_minification,
982+
try_err!(write_minify_replacer(&mut w, &*index, options.enable_minification,
988983
&[(minifier::js::Keyword::Null, "N")]),
989984
&dst);
990985
}
991986
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
992987

993-
if cx.enable_index_page == true {
994-
if let Some(ref index_page) = cx.index_page {
995-
::markdown::render(index_page,
996-
cx.dst.clone(),
997-
&matches, &(*cx.shared).layout.external_html,
998-
!matches.opt_present("markdown-no-toc"),
999-
diag);
988+
if options.enable_index_page {
989+
if let Some(index_page) = options.index_page.clone() {
990+
let mut md_opts = options.clone();
991+
md_opts.output = cx.dst.clone();
992+
md_opts.external_html = (*cx.shared).layout.external_html.clone();
993+
994+
::markdown::render(index_page, md_opts, diag);
1000995
} else {
1001996
let dst = cx.dst.join("index.html");
1002997
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));

0 commit comments

Comments
 (0)