Skip to content

Commit 210fda6

Browse files
committed
consolidate json info into crate-info.json
1 parent 1629a8b commit 210fda6

File tree

4 files changed

+68
-62
lines changed

4 files changed

+68
-62
lines changed

src/librustdoc/config.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use rustc_target::spec::TargetTriple;
2525

2626
use crate::core::new_dcx;
2727
use crate::externalfiles::ExternalHtml;
28-
use crate::html::render::NamedPart;
2928
use crate::html;
3029
use crate::html::markdown::IdMap;
3130
use crate::html::render::StylePath;
@@ -923,7 +922,7 @@ fn parse_extern_html_roots(
923922
Ok(externs)
924923
}
925924

926-
/// Identifies a crate. Absolute path to cci root, including doc.parts, but not the crate name
925+
/// Absolute path to cci root, including doc.parts, but not the crate name
927926
///
928927
/// For example, `/home/user/project/target/doc.parts/`.
929928
#[derive(Clone, Debug)]
@@ -936,8 +935,8 @@ impl PathToParts {
936935
}
937936

938937
/// Gets the final path at which to place the cci part
939-
pub(crate) fn cci_path<T: NamedPart>(&self, crate_name: &str) -> PathBuf {
940-
PathBuf::from_iter([&self.0, Path::new(crate_name), Path::new(T::NAME)])
938+
pub(crate) fn crate_info_path(&self, crate_name: &str) -> PathBuf {
939+
PathBuf::from_iter([&self.0, Path::new(crate_name), Path::new("crate-info.json")])
941940
}
942941
}
943942

src/librustdoc/html/render/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ use crate::scrape_examples::{CallData, CallLocation};
8585
use crate::try_none;
8686
use crate::DOC_RUST_LANG_ORG_CHANNEL;
8787

88-
pub(crate) use write_shared::NamedPart;
89-
9088
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
9189
crate::html::format::display_fn(move |f| {
9290
if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }

src/librustdoc/html/render/offset_template.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::str::FromStr;
55

66
use serde::{Serialize, Deserialize};
77

8-
/// Append-only templates for sorted lists of items.
8+
/// Append-only templates for sorted, deduplicated lists of items.
99
///
1010
/// Last line of the rendered output is a comment encoding the next insertion point.
1111
#[derive(Debug, Clone)]
@@ -45,7 +45,7 @@ impl<F> OffsetTemplate<F> {
4545
}
4646

4747
impl<F: FileFormat> OffsetTemplate<F> {
48-
/// Puts the text `insert` at the template's insertion point
48+
/// Adds this text to the next insert point
4949
pub(crate) fn append(&mut self, insert: String) {
5050
self.contents.insert(insert);
5151
}

src/librustdoc/html/render/write_shared.rs

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::ffi::OsString;
2525
use std::collections::hash_map::Entry;
2626
use std::iter::once;
2727
use std::str::FromStr;
28+
use std::any::Any;
2829

2930
use indexmap::IndexMap;
3031
use itertools::Itertools;
@@ -42,7 +43,7 @@ use super::{collect_paths_for_type, ensure_trailing_slash, Context, RenderMode};
4243
use crate::html::render::search_index::build_index;
4344
use crate::html::render::sorted_json::SortedJson;
4445
use crate::html::render::offset_template::{self, OffsetTemplate};
45-
use crate::clean::{Crate, Item, ItemId, ItemKind, types::ExternalCrate};
46+
use crate::clean::{Crate, Item, ItemId, ItemKind};
4647
use crate::config::{EmitType, RenderOptions, PathToParts};
4748
use crate::docfs::PathError;
4849
use crate::error::Error;
@@ -63,6 +64,40 @@ use crate::{try_err, try_none};
6364
// string faster loading tetchnique
6465
// run rest of the tests and fix things up
6566

67+
#[derive(Serialize, Deserialize, Clone, Debug)]
68+
struct CrateInfo {
69+
src_files_js: PartsAndLocations<SourcesPart>,
70+
search_index_js: PartsAndLocations<SearchIndexPart>,
71+
all_crates: PartsAndLocations<AllCratesPart>,
72+
crates_index: PartsAndLocations<CratesIndexPart>,
73+
trait_impl: PartsAndLocations<TraitAliasPart>,
74+
type_impl: PartsAndLocations<TypeAliasPart>,
75+
}
76+
77+
impl CrateInfo {
78+
fn get<T: 'static>(&self) -> Option<&PartsAndLocations<T>> {
79+
(&self.src_files_js as &dyn Any).downcast_ref()
80+
.or_else(|| (&self.search_index_js as &dyn Any).downcast_ref())
81+
.or_else(|| (&self.all_crates as &dyn Any).downcast_ref())
82+
.or_else(|| (&self.crates_index as &dyn Any).downcast_ref())
83+
.or_else(|| (&self.trait_impl as &dyn Any).downcast_ref())
84+
.or_else(|| (&self.type_impl as &dyn Any).downcast_ref())
85+
}
86+
87+
fn read(parts_paths: &FxHashMap<String, PathToParts>) -> Result<Vec<Self>, Error> {
88+
parts_paths.iter()
89+
.map(|(crate_name, parts_path)| {
90+
let path = parts_path.crate_info_path(crate_name);
91+
let parts = try_err!(fs::read(&path), &path);
92+
let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path);
93+
Ok::<_, Error>(parts)
94+
})
95+
.collect::<Result<Vec<CrateInfo>, Error>>()
96+
}
97+
98+
}
99+
100+
66101
pub(crate) fn write_shared(
67102
cx: &mut Context<'_>,
68103
krate: &Crate,
@@ -78,37 +113,37 @@ pub(crate) fn write_shared(
78113
let crate_name = krate.name(cx.tcx());
79114
let crate_name = crate_name.as_str(); // rand
80115
let crate_name_json = SortedJson::serialize(crate_name); // "rand"
81-
82-
let sources = PartsAndLocations::<SourcesPart>::get(cx, &crate_name_json)?;
83116
let SerializedSearchIndex { index, desc } = build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx);
84-
let search_index = PartsAndLocations::<SearchIndexPart>::get(cx, index)?;
85-
let all_crates = PartsAndLocations::<AllCratesPart>::get(crate_name_json.clone())?;
86117
let external_crates = hack_get_external_crate_names(cx)?;
87-
let crates_index = PartsAndLocations::<CratesIndexPart>::get(&crate_name, &external_crates)?;
88-
let trait_aliases = PartsAndLocations::<TraitAliasPart>::get(cx, &crate_name_json)?;
89-
let type_aliases = PartsAndLocations::<TypeAliasPart>::get(cx, krate, &crate_name_json)?;
118+
let info = CrateInfo {
119+
src_files_js: PartsAndLocations::<SourcesPart>::get(cx, &crate_name_json)?,
120+
search_index_js: PartsAndLocations::<SearchIndexPart>::get(cx, index)?,
121+
all_crates: PartsAndLocations::<AllCratesPart>::get(crate_name_json.clone())?,
122+
crates_index: PartsAndLocations::<CratesIndexPart>::get(&crate_name, &external_crates)?,
123+
trait_impl: PartsAndLocations::<TraitAliasPart>::get(cx, &crate_name_json)?,
124+
type_impl: PartsAndLocations::<TypeAliasPart>::get(cx, krate, &crate_name_json)?,
125+
};
90126

91127
if let Some(parts_out_dir) = &opt.parts_out_dir {
92-
sources.write(cx, parts_out_dir)?;
93-
search_index.write(cx, parts_out_dir)?;
94-
all_crates.write(cx, parts_out_dir)?;
95-
crates_index.write(cx, parts_out_dir)?;
96-
trait_aliases.write(cx, parts_out_dir)?;
97-
type_aliases.write(cx, parts_out_dir)?;
128+
let path = parts_out_dir.crate_info_path(&crate_name);
129+
write_create_parents(cx, path, serde_json::to_string(&info).unwrap())?;
98130
}
99131

132+
let mut crates_info = CrateInfo::read(&opt.parts_paths)?;
133+
crates_info.push(info);
134+
100135
if opt.write_rendered_cci {
101136
write_static_files(cx, &opt)?;
102137
write_search_desc(cx, &krate, &desc)?;
103138
if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
104139
if cx.include_sources {
105-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &sources)?;
140+
write_rendered_cci::<SourcesPart>(cx, opt.read_rendered_cci, &crates_info)?;
106141
}
107-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &search_index)?;
108-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &all_crates)?;
142+
write_rendered_cci::<SearchIndexPart>(cx, opt.read_rendered_cci, &crates_info)?;
143+
write_rendered_cci::<AllCratesPart>(cx, opt.read_rendered_cci, &crates_info)?;
109144
}
110-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &trait_aliases)?;
111-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &type_aliases)?;
145+
write_rendered_cci::<TraitAliasPart>(cx, opt.read_rendered_cci, &crates_info)?;
146+
write_rendered_cci::<TypeAliasPart>(cx, opt.read_rendered_cci, &crates_info)?;
112147
match &opt.index_page {
113148
Some(index_page) if opt.enable_index_page => {
114149
let mut md_opts = opt.clone();
@@ -117,7 +152,7 @@ pub(crate) fn write_shared(
117152
try_err!(crate::markdown::render(&index_page, md_opts, cx.shared.edition()), &index_page);
118153
}
119154
None if opt.enable_index_page => {
120-
write_rendered_cci(cx, opt.read_rendered_cci, &opt.parts_paths, &crates_index)?;
155+
write_rendered_cci::<CratesIndexPart>(cx, opt.read_rendered_cci, &crates_info)?;
121156
}
122157
_ => {}, // they don't want an index page
123158
}
@@ -206,6 +241,7 @@ struct Part<T, U> {
206241
}
207242

208243
impl<T, U: fmt::Display> fmt::Display for Part<T, U> {
244+
/// Writes serialized JSON
209245
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210246
write!(f, "{}", self.item)
211247
}
@@ -215,12 +251,11 @@ pub(crate) trait NamedPart: Sized {
215251
/// Identifies the kind of cross crate information.
216252
///
217253
/// The cci type name in `doc.parts/<cci type>`
218-
const NAME: &'static str;
219254
type FileFormat: offset_template::FileFormat;
220255
fn blank_template(cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat>;
221256
}
222257

223-
/// Paths (relative to `doc/`) and their pre-merge contents
258+
/// Paths (relative to the doc root) and their pre-merge contents
224259
#[derive(Serialize, Deserialize, Debug, Clone)]
225260
#[serde(transparent)]
226261
struct PartsAndLocations<P> {
@@ -245,22 +280,10 @@ impl<T, U> PartsAndLocations<Part<T, U>> {
245280
}
246281
}
247282

248-
impl<T, U: Serialize> PartsAndLocations<Part<T, U>>
249-
where Part<T, U>: NamedPart,
250-
{
251-
fn write(&self, cx: &mut Context<'_>, parts_path: &PathToParts) -> Result<(), Error> {
252-
let name = ExternalCrate::LOCAL.name(cx.tcx());
253-
let path = parts_path.cci_path::<Part<T, U>>(name.as_str());
254-
write_create_parents(cx, path, serde_json::to_string(self).unwrap())?;
255-
Ok(())
256-
}
257-
}
258-
259283
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
260284
struct SearchIndex;
261285
type SearchIndexPart = Part<SearchIndex, SortedJson>;
262286
impl NamedPart for SearchIndexPart {
263-
const NAME: &'static str = "search-index-js";
264287
type FileFormat = offset_template::Js;
265288
fn blank_template(_cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
266289
OffsetTemplate::before_after(r"var searchIndex = new Map([", r"]);
@@ -279,7 +302,6 @@ impl PartsAndLocations<SearchIndexPart> {
279302
struct AllCrates;
280303
type AllCratesPart = Part<AllCrates, SortedJson>;
281304
impl NamedPart for AllCratesPart {
282-
const NAME: &'static str = "crates-js";
283305
type FileFormat = offset_template::Js;
284306
fn blank_template(_cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
285307
OffsetTemplate::before_after("window.ALL_CRATES = [", "];")
@@ -314,7 +336,6 @@ fn hack_get_external_crate_names(cx: &Context<'_>) -> Result<Vec<String>, Error>
314336
struct CratesIndex;
315337
type CratesIndexPart = Part<CratesIndex, String>;
316338
impl NamedPart for CratesIndexPart {
317-
const NAME: &'static str = "index-html";
318339
type FileFormat = offset_template::Html;
319340
fn blank_template(cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
320341
let mut magic = String::from("\u{FFFC}");
@@ -360,7 +381,6 @@ impl PartsAndLocations<CratesIndexPart> {
360381
struct Sources;
361382
type SourcesPart = Part<Sources, SortedJson>;
362383
impl NamedPart for SourcesPart {
363-
const NAME: &'static str = "src-files-js";
364384
type FileFormat = offset_template::Js;
365385
fn blank_template(_cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
366386
// This needs to be `var`, not `const`.
@@ -454,7 +474,6 @@ impl Hierarchy {
454474
struct TypeAlias;
455475
type TypeAliasPart = Part<TypeAlias, SortedJson>;
456476
impl NamedPart for TypeAliasPart {
457-
const NAME: &'static str = "type-impl";
458477
type FileFormat = offset_template::Js;
459478
fn blank_template(_cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
460479
OffsetTemplate::before_after(r"(function() {
@@ -570,7 +589,6 @@ impl PartsAndLocations<TypeAliasPart> {
570589
struct TraitAlias;
571590
type TraitAliasPart = Part<TraitAlias, SortedJson>;
572591
impl NamedPart for TraitAliasPart {
573-
const NAME: &'static str = "trait-impl";
574592
type FileFormat = offset_template::Js;
575593
fn blank_template(_cx: &Context<'_>) -> OffsetTemplate<Self::FileFormat> {
576594
OffsetTemplate::before_after(r"(function() {
@@ -830,25 +848,16 @@ fn write_create_parents(cx: &mut Context<'_>, path: PathBuf, content: String) ->
830848
Ok(())
831849
}
832850

833-
fn write_rendered_cci<T: NamedPart + DeserializeOwned + fmt::Display + fmt::Debug>(
851+
/// info from this crate and the --include-info-json'd crates
852+
fn write_rendered_cci<T: NamedPart + DeserializeOwned + fmt::Display + fmt::Debug + Any>(
834853
cx: &mut Context<'_>,
835854
read_rendered_cci: bool,
836-
parts_paths: &FxHashMap<String, PathToParts>,
837-
our_parts_and_locations: &PartsAndLocations<T>,
855+
crates_info: &[CrateInfo],
838856
) -> Result<(), Error> where <T as NamedPart>::FileFormat: std::fmt::Debug {
839857
// read parts from disk
840-
let path_parts = parts_paths.iter()
841-
.map(|(crate_name, parts_path)| {
842-
let path = parts_path.cci_path::<T>(crate_name);
843-
let parts = try_err!(fs::read(&path), &path);
844-
let parts: PartsAndLocations::<T> = try_err!(serde_json::from_slice(&parts), &path);
845-
Ok::<_, Error>(parts)
846-
})
847-
.collect::<Result<Vec<PartsAndLocations<T>>, Error>>()?;
848-
let path_parts = path_parts.iter()
849-
.map(|parts_and_locations| parts_and_locations.parts.iter())
850-
.flatten()
851-
.chain(our_parts_and_locations.parts.iter());
858+
let path_parts = crates_info.iter()
859+
.map(|crate_info| crate_info.get::<T>().unwrap().parts.iter())
860+
.flatten();
852861
// read previous rendered cci from storage, append to them
853862
let mut templates: FxHashMap<PathBuf, OffsetTemplate<T::FileFormat>> = Default::default();
854863
for (path, part) in path_parts {

0 commit comments

Comments
 (0)