about summary refs log tree commit diff
path: root/src/librustdoc/html/render
diff options
context:
space:
mode:
authorWill Crichton <wcrichto@cs.stanford.edu>2021-05-09 16:22:22 -0700
committerWill Crichton <wcrichto@cs.stanford.edu>2021-10-06 19:44:47 -0700
commit4b3f82ad0321b8f2e2630b74bbc526ffb8fa5bda (patch)
tree4d10d3906b55b93f95d813d1e859ef92592712a6 /src/librustdoc/html/render
parent0eabf25b90396dead0b2a1aaa275af18a1ae6008 (diff)
downloadrust-4b3f82ad0321b8f2e2630b74bbc526ffb8fa5bda.tar.gz
rust-4b3f82ad0321b8f2e2630b74bbc526ffb8fa5bda.zip
Add updated support for example-analyzer
Move rendering of examples into

Finalize design

Cleanup, rename found -> scraped

Softer yellow

Clean up dead code

Document scrape_examples

More simplification and documentation

Remove extra css

Test
Diffstat (limited to 'src/librustdoc/html/render')
-rw-r--r--src/librustdoc/html/render/context.rs9
-rw-r--r--src/librustdoc/html/render/mod.rs95
2 files changed, 103 insertions, 1 deletions
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index b99d2fe5aa0..49bf760c29c 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -124,6 +124,7 @@ crate struct SharedContext<'tcx> {
     crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
     /// The [`Cache`] used during rendering.
     crate cache: Cache,
+    pub(super) repository_url: Option<String>,
 }
 
 impl SharedContext<'_> {
@@ -140,7 +141,11 @@ impl SharedContext<'_> {
     /// Returns the `collapsed_doc_value` of the given item if this is the main crate, otherwise
     /// returns the `doc_value`.
     crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<String> {
-        if self.collapsed { item.collapsed_doc_value() } else { item.doc_value() }
+        if self.collapsed {
+            item.collapsed_doc_value()
+        } else {
+            item.doc_value()
+        }
     }
 
     crate fn edition(&self) -> Edition {
@@ -389,6 +394,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             generate_redirect_map,
             show_type_layout,
             generate_link_to_definition,
+            repository_url,
             ..
         } = options;
 
@@ -480,6 +486,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             templates,
             span_correspondance_map: matches,
             cache,
+            repository_url,
         };
 
         // Add the default themes to the `Vec` of stylepaths
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 11682afdf89..0fb7723b68b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -39,6 +39,7 @@ crate use span_map::{collect_spans_and_sources, LinkFromSrc};
 use std::collections::VecDeque;
 use std::default::Default;
 use std::fmt;
+use std::fs;
 use std::path::PathBuf;
 use std::str;
 use std::string::ToString;
@@ -68,6 +69,8 @@ use crate::html::format::{
     print_generic_bounds, print_where_clause, Buffer, HrefError, PrintWithSpace,
 };
 use crate::html::markdown::{HeadingOffset, Markdown, MarkdownHtml, MarkdownSummaryLine};
+use crate::html::sources;
+use crate::scrape_examples::FnCallLocations;
 
 /// A pair of name and its optional document.
 crate type NameDoc = (String, Option<String>);
@@ -584,6 +587,13 @@ fn document_full_inner(
             render_markdown(w, cx, &s, item.links(cx), heading_offset);
         }
     }
+
+    match &*item.kind {
+        clean::ItemKind::FunctionItem(f) | clean::ItemKind::MethodItem(f, _) => {
+            render_call_locations(w, cx, &f.call_locations);
+        }
+        _ => {}
+    }
 }
 
 /// Add extra information about an item such as:
@@ -2440,3 +2450,88 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
     }
     out
 }
+
+fn render_call_locations(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    call_locations: &Option<FnCallLocations>,
+) {
+    let call_locations = match call_locations.as_ref() {
+        Some(call_locations) => call_locations,
+        None => {
+            return;
+        }
+    };
+
+    let filtered_locations: Vec<_> = call_locations
+        .iter()
+        .filter_map(|(file, locs)| {
+            // TODO(wcrichto): file I/O should be cached
+            let mut contents = match fs::read_to_string(&file) {
+                Ok(contents) => contents,
+                Err(e) => {
+                    eprintln!("Failed to read file {}", e);
+                    return None;
+                }
+            };
+
+            // Remove the utf-8 BOM if any
+            if contents.starts_with('\u{feff}') {
+                contents.drain(..3);
+            }
+
+            Some((file, contents, locs))
+        })
+        .collect();
+
+    let n_examples = filtered_locations.len();
+    if n_examples == 0 {
+        return;
+    }
+
+    let id = cx.id_map.borrow_mut().derive("scraped-examples");
+    write!(
+        w,
+        r##"<div class="docblock scraped-example-list">
+          <h1 id="scraped-examples" class="small-section-header">
+             <a href="#{}">Uses found in <code>examples/</code></a>
+          </h1>"##,
+        id
+    );
+
+    let write_example = |w: &mut Buffer, (file, contents, locs): (&String, String, _)| {
+        let ex_title = match cx.shared.repository_url.as_ref() {
+            Some(url) => format!(
+                r#"<a href="{url}/{file}" target="_blank">{file}</a>"#,
+                file = file,
+                url = url
+            ),
+            None => file.clone(),
+        };
+        let edition = cx.shared.edition();
+        write!(
+            w,
+            r#"<div class="scraped-example" data-code="{code}" data-locs="{locations}">
+           <strong>{title}</strong>
+           <div class="code-wrapper">"#,
+            code = contents.replace("\"", "&quot;"),
+            locations = serde_json::to_string(&locs).unwrap(),
+            title = ex_title,
+        );
+        write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
+        write!(w, r#"<span class="expand">&varr;</span>"#);
+        sources::print_src(w, &contents, edition);
+        write!(w, "</div></div>");
+    };
+
+    let mut it = filtered_locations.into_iter();
+    write_example(w, it.next().unwrap());
+
+    if n_examples > 1 {
+        write!(w, r#"<div class="more-scraped-examples hidden">"#);
+        it.for_each(|ex| write_example(w, ex));
+        write!(w, "</div>");
+    }
+
+    write!(w, "</div>");
+}