summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/html/render/write_shared.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/librustdoc/html/render/write_shared.rs64
1 files changed, 42 insertions, 22 deletions
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 94d8a9fec..bc8badad3 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -1,8 +1,9 @@
+use std::cell::RefCell;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::{Component, Path};
-use std::rc::Rc;
+use std::rc::{Rc, Weak};
use itertools::Itertools;
use rustc_data_structures::flock;
@@ -184,23 +185,26 @@ pub(super) fn write_shared(
use std::ffi::OsString;
- #[derive(Debug)]
+ #[derive(Debug, Default)]
struct Hierarchy {
+ parent: Weak<Self>,
elem: OsString,
- children: FxHashMap<OsString, Hierarchy>,
- elems: FxHashSet<OsString>,
+ children: RefCell<FxHashMap<OsString, Rc<Self>>>,
+ elems: RefCell<FxHashSet<OsString>>,
}
impl Hierarchy {
- fn new(elem: OsString) -> Hierarchy {
- Hierarchy { elem, children: FxHashMap::default(), elems: FxHashSet::default() }
+ fn with_parent(elem: OsString, parent: &Rc<Self>) -> Self {
+ Self { elem, parent: Rc::downgrade(parent), ..Self::default() }
}
fn to_json_string(&self) -> String {
- let mut subs: Vec<&Hierarchy> = self.children.values().collect();
+ let borrow = self.children.borrow();
+ let mut subs: Vec<_> = borrow.values().collect();
subs.sort_unstable_by(|a, b| a.elem.cmp(&b.elem));
let mut files = self
.elems
+ .borrow()
.iter()
.map(|s| format!("\"{}\"", s.to_str().expect("invalid osstring conversion")))
.collect::<Vec<_>>();
@@ -220,36 +224,52 @@ pub(super) fn write_shared(
files = files
)
}
- }
- if cx.include_sources {
- let mut hierarchy = Hierarchy::new(OsString::new());
- for source in cx
- .shared
- .local_sources
- .iter()
- .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root).ok())
- {
- let mut h = &mut hierarchy;
- let mut elems = source
+ fn add_path(self: &Rc<Self>, path: &Path) {
+ let mut h = Rc::clone(&self);
+ let mut elems = path
.components()
.filter_map(|s| match s {
Component::Normal(s) => Some(s.to_owned()),
+ Component::ParentDir => Some(OsString::from("..")),
_ => None,
})
.peekable();
loop {
let cur_elem = elems.next().expect("empty file path");
+ if cur_elem == ".." {
+ if let Some(parent) = h.parent.upgrade() {
+ h = parent;
+ }
+ continue;
+ }
if elems.peek().is_none() {
- h.elems.insert(cur_elem);
+ h.elems.borrow_mut().insert(cur_elem);
break;
} else {
- let e = cur_elem.clone();
- h = h.children.entry(cur_elem.clone()).or_insert_with(|| Hierarchy::new(e));
+ let entry = Rc::clone(
+ h.children
+ .borrow_mut()
+ .entry(cur_elem.clone())
+ .or_insert_with(|| Rc::new(Self::with_parent(cur_elem, &h))),
+ );
+ h = entry;
}
}
}
+ }
+ if cx.include_sources {
+ let hierarchy = Rc::new(Hierarchy::default());
+ for source in cx
+ .shared
+ .local_sources
+ .iter()
+ .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root).ok())
+ {
+ hierarchy.add_path(source);
+ }
+ let hierarchy = Rc::try_unwrap(hierarchy).unwrap();
let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix));
let make_sources = || {
let (mut all_sources, _krates) =
@@ -325,7 +345,7 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
};
let content = format!(
- "<h1 class=\"fqn\">List of all crates</h1><ul class=\"all-items\">{}</ul>",
+ "<h1>List of all crates</h1><ul class=\"all-items\">{}</ul>",
krates
.iter()
.map(|s| {