Skip to content

Commit

Permalink
Add updated support for example-analyzer
Browse files Browse the repository at this point in the history
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
  • Loading branch information
willcrichton committed Oct 7, 2021
1 parent 0eabf25 commit 4b3f82a
Show file tree
Hide file tree
Showing 12 changed files with 609 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi
decl,
generics,
header: hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness },
call_locations: None,
}
}

Expand Down
41 changes: 25 additions & 16 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,10 @@ impl<'a> Clean<Function> for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::Bo
fn clean(&self, cx: &mut DocContext<'_>) -> Function {
let (generics, decl) =
enter_impl_trait(cx, |cx| (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
Function { decl, generics, header: self.0.header }
let mut function = Function { decl, generics, header: self.0.header, call_locations: None };
let def_id = self.2.hir_id.owner.to_def_id();
function.load_call_locations(def_id, cx);
function
}
}

Expand Down Expand Up @@ -933,12 +936,14 @@ impl Clean<Item> for hir::TraitItem<'_> {
let (generics, decl) = enter_impl_trait(cx, |cx| {
(self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
});
let mut t = Function { header: sig.header, decl, generics };
let mut t =
Function { header: sig.header, decl, generics, call_locations: None };
if t.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
t.header.constness = hir::Constness::NotConst;
}
t.load_call_locations(self.def_id.to_def_id(), cx);
TyMethodItem(t)
}
hir::TraitItemKind::Type(ref bounds, ref default) => {
Expand Down Expand Up @@ -1057,21 +1062,21 @@ impl Clean<Item> for ty::AssocItem {
ty::ImplContainer(_) => Some(self.defaultness),
ty::TraitContainer(_) => None,
};
MethodItem(
Function {
generics,
decl,
header: hir::FnHeader {
unsafety: sig.unsafety(),
abi: sig.abi(),
constness,
asyncness,
},
let mut function = Function {
generics,
decl,
header: hir::FnHeader {
unsafety: sig.unsafety(),
abi: sig.abi(),
constness,
asyncness,
},
defaultness,
)
call_locations: None,
};
function.load_call_locations(self.def_id, cx);
MethodItem(function, defaultness)
} else {
TyMethodItem(Function {
let mut function = Function {
generics,
decl,
header: hir::FnHeader {
Expand All @@ -1080,7 +1085,10 @@ impl Clean<Item> for ty::AssocItem {
constness: hir::Constness::NotConst,
asyncness: hir::IsAsync::NotAsync,
},
})
call_locations: None,
};
function.load_call_locations(self.def_id, cx);
TyMethodItem(function)
}
}
ty::AssocKind::Type => {
Expand Down Expand Up @@ -2098,6 +2106,7 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
constness: hir::Constness::NotConst,
asyncness: hir::IsAsync::NotAsync,
},
call_locations: None,
})
}
hir::ForeignItemKind::Static(ref ty, mutability) => {
Expand Down
12 changes: 12 additions & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::render::cache::ExternalLocation;
use crate::html::render::Context;
use crate::scrape_examples::FnCallLocations;

use self::FnRetTy::*;
use self::ItemKind::*;
Expand Down Expand Up @@ -1254,6 +1255,17 @@ crate struct Function {
crate decl: FnDecl,
crate generics: Generics,
crate header: hir::FnHeader,
crate call_locations: Option<FnCallLocations>,
}

impl Function {
crate fn load_call_locations(&mut self, def_id: hir::def_id::DefId, cx: &DocContext<'_>) {
if let Some(call_locations) = cx.render_options.call_locations.as_ref() {
let key = cx.tcx.def_path(def_id).to_string_no_crate_verbose();
self.call_locations = call_locations.get(&key).cloned();
debug!("call_locations: {} -- {:?}", key, self.call_locations);
}
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
11 changes: 11 additions & 0 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::html::render::StylePath;
use crate::html::static_files;
use crate::opts;
use crate::passes::{self, Condition, DefaultPassOption};
use crate::scrape_examples::AllCallLocations;
use crate::theme;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -158,6 +159,8 @@ crate struct Options {
crate json_unused_externs: bool,
/// Whether to skip capturing stdout and stderr of tests.
crate nocapture: bool,

crate scrape_examples: Vec<String>,
}

impl fmt::Debug for Options {
Expand Down Expand Up @@ -280,6 +283,8 @@ crate struct RenderOptions {
crate emit: Vec<EmitType>,
/// If `true`, HTML source pages will generate links for items to their definition.
crate generate_link_to_definition: bool,
crate call_locations: Option<AllCallLocations>,
crate repository_url: Option<String>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -671,6 +676,9 @@ impl Options {
return Err(1);
}

let repository_url = matches.opt_str("repository-url");
let scrape_examples = matches.opt_strs("scrape-examples");

let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);

Ok(Options {
Expand Down Expand Up @@ -737,10 +745,13 @@ impl Options {
),
emit,
generate_link_to_definition,
call_locations: None,
repository_url,
},
crate_name,
output_format,
json_unused_externs,
scrape_examples,
})
}

Expand Down
9 changes: 8 additions & 1 deletion src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<'_> {
Expand All @@ -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 {
Expand Down Expand Up @@ -389,6 +394,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
generate_redirect_map,
show_type_layout,
generate_link_to_definition,
repository_url,
..
} = options;

Expand Down Expand Up @@ -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
Expand Down
95 changes: 95 additions & 0 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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>");
}
2 changes: 1 addition & 1 deletion src/librustdoc/html/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ where

/// Wrapper struct to render the source code of a file. This will do things like
/// adding line numbers to the left-hand side.
fn print_src(
crate fn print_src(
buf: &mut Buffer,
s: &str,
edition: Edition,
Expand Down
Loading

0 comments on commit 4b3f82a

Please sign in to comment.