about summary refs log tree commit diff
path: root/src/librustdoc/html
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-01-20 20:56:47 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2021-02-23 11:13:35 +0100
commit3a92f771b22a2ac487838767f552c4dae0a52ddc (patch)
treef3219cf1d137df2da44e046316be6c90c3889f85 /src/librustdoc/html
parent15598a83db88ec7a32ea18a44dd6309f32edc07e (diff)
downloadrust-3a92f771b22a2ac487838767f552c4dae0a52ddc.tar.gz
rust-3a92f771b22a2ac487838767f552c4dae0a52ddc.zip
Add --generate-redirect-map option to replace HTML redirection file with a unique JSON map
Diffstat (limited to 'src/librustdoc/html')
-rw-r--r--src/librustdoc/html/render/mod.rs61
1 files changed, 49 insertions, 12 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 7f122bb8cb5..cd115eef314 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -111,6 +111,10 @@ crate struct Context<'tcx> {
     /// real location of an item. This is used to allow external links to
     /// publicly reused items to redirect to the right location.
     crate render_redirect_pages: bool,
+    /// `None` by default, depends on the `generate-redirect-map` option flag. If this field is set
+    /// to `Some(...)`, it'll store redirections and then generate a JSON file at the top level of
+    /// the crate.
+    crate redirections: Option<Rc<RefCell<FxHashMap<String, String>>>>,
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
     /// Tracks section IDs for `Deref` targets so they match in both the main
@@ -405,6 +409,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             static_root_path,
             generate_search_filter,
             unstable_features,
+            generate_redirect_map,
             ..
         } = options;
 
@@ -510,6 +515,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             all: Rc::new(RefCell::new(AllTypes::new())),
             errors: Rc::new(receiver),
             cache: Rc::new(cache),
+            redirections: if generate_redirect_map {
+                Some(Rc::new(RefCell::new(FxHashMap::default())))
+            } else {
+                None
+            },
         };
 
         CURRENT_DEPTH.with(|s| s.set(0));
@@ -588,6 +598,15 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             &style_files,
         );
         self.shared.fs.write(&settings_file, v.as_bytes())?;
+        if let Some(redirections) = self.redirections.take() {
+            if !redirections.borrow().is_empty() {
+                let redirect_map_path =
+                    self.dst.join(&*krate.name.as_str()).join("redirect-map.json");
+                let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
+                self.shared.ensure_dir(&self.dst.join(&*krate.name.as_str()))?;
+                self.shared.fs.write(&redirect_map_path, paths.as_bytes())?;
+            }
+        }
 
         // Flush pending errors.
         Arc::get_mut(&mut self.shared).unwrap().fs.close();
@@ -664,9 +683,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         if !buf.is_empty() {
             let name = item.name.as_ref().unwrap();
             let item_type = item.type_();
-            let file_name = &item_path(item_type, &name.as_str());
+            let file_name = item_path(item_type, &name.as_str());
             self.shared.ensure_dir(&self.dst)?;
-            let joint_dst = self.dst.join(file_name);
+            let joint_dst = self.dst.join(&file_name);
             self.shared.fs.write(&joint_dst, buf.as_bytes())?;
 
             if !self.render_redirect_pages {
@@ -676,9 +695,17 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             // to the new one (without).
             if item_type == ItemType::Macro {
                 let redir_name = format!("{}.{}!.html", item_type, name);
-                let redir_dst = self.dst.join(redir_name);
-                let v = layout::redirect(file_name);
-                self.shared.fs.write(&redir_dst, v.as_bytes())?;
+                if let Some(ref redirections) = self.redirections {
+                    let crate_name = &self.shared.layout.krate;
+                    redirections.borrow_mut().insert(
+                        format!("{}/{}", crate_name, redir_name),
+                        format!("{}/{}", crate_name, file_name),
+                    );
+                } else {
+                    let v = layout::redirect(&file_name);
+                    let redir_dst = self.dst.join(redir_name);
+                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
+                }
             }
         }
         Ok(())
@@ -1588,17 +1615,27 @@ impl Context<'_> {
                 &self.shared.style_files,
             )
         } else {
-            let mut url = self.root_path();
             if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id) {
+                let mut path = String::new();
                 for name in &names[..names.len() - 1] {
-                    url.push_str(name);
-                    url.push('/');
+                    path.push_str(name);
+                    path.push('/');
+                }
+                path.push_str(&item_path(ty, names.last().unwrap()));
+                match self.redirections {
+                    Some(ref redirections) => {
+                        let mut current_path = String::new();
+                        for name in &self.current {
+                            current_path.push_str(name);
+                            current_path.push('/');
+                        }
+                        current_path.push_str(&item_path(ty, names.last().unwrap()));
+                        redirections.borrow_mut().insert(current_path, path);
+                    }
+                    None => return layout::redirect(&format!("{}{}", self.root_path(), path)),
                 }
-                url.push_str(&item_path(ty, names.last().unwrap()));
-                layout::redirect(&url)
-            } else {
-                String::new()
             }
+            String::new()
         }
     }