Wrap the span_map tuple index into a type called "LightSpan"
This commit is contained in:
parent
c5c927dfda
commit
e8869cb7a7
4 changed files with 68 additions and 44 deletions
|
@ -17,7 +17,7 @@ use rustc_span::edition::Edition;
|
|||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use super::format::{self, Buffer};
|
||||
use super::render::LinkFromSrc;
|
||||
use super::render::{LightSpan, LinkFromSrc};
|
||||
|
||||
/// Highlights `src`, returning the HTML output.
|
||||
crate fn render_with_highlighting(
|
||||
|
@ -74,7 +74,7 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
|
|||
/// won't try to generate links to an ident definition.
|
||||
///
|
||||
/// More explanations about spans and how we use them here are provided in the
|
||||
/// [`local_span_to_global_span`] function documentation about how it works.
|
||||
/// [`LightSpan::new_in_file`] function documentation about how it works.
|
||||
///
|
||||
/// As for `root_path`, it's used to know "how far" from the top of the directory we are to link
|
||||
/// to either documentation pages or other source pages.
|
||||
|
@ -115,14 +115,14 @@ enum Class {
|
|||
KeyWord,
|
||||
// Keywords that do pointer/reference stuff.
|
||||
RefKeyWord,
|
||||
Self_((u32, u32)),
|
||||
Self_(LightSpan),
|
||||
Op,
|
||||
Macro,
|
||||
MacroNonTerminal,
|
||||
String,
|
||||
Number,
|
||||
Bool,
|
||||
Ident((u32, u32)),
|
||||
Ident(LightSpan),
|
||||
Lifetime,
|
||||
PreludeTy,
|
||||
PreludeVal,
|
||||
|
@ -155,7 +155,7 @@ impl Class {
|
|||
|
||||
/// In case this is an item which can be converted into a link to a definition, it'll contain
|
||||
/// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
|
||||
fn get_span(self) -> Option<(u32, u32)> {
|
||||
fn get_span(self) -> Option<LightSpan> {
|
||||
match self {
|
||||
Self::Ident(sp) | Self::Self_(sp) => Some(sp),
|
||||
_ => None,
|
||||
|
@ -201,23 +201,6 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
|
|||
})
|
||||
}
|
||||
|
||||
/// Before explaining what this function does, some global explanations on rust's `Span`:
|
||||
///
|
||||
/// Each source code file is stored in the source map in the compiler and has a
|
||||
/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
|
||||
/// string to simplify things). So in this case, this represents the starting byte of the current
|
||||
/// file. It'll be used later on to retrieve the "definition span" from the
|
||||
/// `span_correspondance_map` (which is inside `context`).
|
||||
///
|
||||
/// This when we transform the "span" we have from reading the input into a "span" which can be
|
||||
/// used as index to the `span_correspondance_map` to get the definition of this item.
|
||||
///
|
||||
/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to make
|
||||
/// our "span" works in there, we simply add `file_span_lo` to our values.
|
||||
fn local_span_to_global_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
|
||||
(start + file_span_lo, end + file_span_lo)
|
||||
}
|
||||
|
||||
/// Processes program tokens, classifying strings of text by highlighting
|
||||
/// category (`Class`).
|
||||
struct Classifier<'a> {
|
||||
|
@ -234,7 +217,7 @@ struct Classifier<'a> {
|
|||
impl<'a> Classifier<'a> {
|
||||
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
|
||||
/// file "lo" byte which we be used later on by the `span_correspondance_map`. More explanations
|
||||
/// are provided in the [`local_span_to_global_span`] function documentation about how it works.
|
||||
/// are provided in the [`LightSpan::new_in_file`] function documentation about how it works.
|
||||
fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
|
||||
let tokens = TokenIter { src }.peekable();
|
||||
Classifier {
|
||||
|
@ -496,12 +479,12 @@ impl<'a> Classifier<'a> {
|
|||
self.in_macro_nonterminal = false;
|
||||
Class::MacroNonTerminal
|
||||
}
|
||||
"self" | "Self" => Class::Self_(local_span_to_global_span(
|
||||
"self" | "Self" => Class::Self_(LightSpan::new_in_file(
|
||||
self.file_span_lo,
|
||||
before,
|
||||
before + text.len() as u32,
|
||||
)),
|
||||
_ => Class::Ident(local_span_to_global_span(
|
||||
_ => Class::Ident(LightSpan::new_in_file(
|
||||
self.file_span_lo,
|
||||
before,
|
||||
before + text.len() as u32,
|
||||
|
@ -509,7 +492,7 @@ impl<'a> Classifier<'a> {
|
|||
},
|
||||
Some(c) => c,
|
||||
},
|
||||
TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(local_span_to_global_span(
|
||||
TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(LightSpan::new_in_file(
|
||||
self.file_span_lo,
|
||||
before,
|
||||
before + text.len() as u32,
|
||||
|
@ -572,7 +555,7 @@ fn string<T: Display>(
|
|||
"self" | "Self" => write!(
|
||||
&mut path,
|
||||
"<span class=\"{}\">{}</span>",
|
||||
Class::Self_((0, 0)).as_html(),
|
||||
Class::Self_(LightSpan::empty()).as_html(),
|
||||
t
|
||||
),
|
||||
"crate" | "super" => write!(
|
||||
|
|
|
@ -18,8 +18,8 @@ use super::cache::{build_index, ExternalLocation};
|
|||
use super::print_item::{full_path, item_path, print_item};
|
||||
use super::write_shared::write_shared;
|
||||
use super::{
|
||||
collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
|
||||
BASIC_KEYWORDS,
|
||||
collect_spans_and_sources, print_sidebar, settings, AllTypes, LightSpan, LinkFromSrc, NameDoc,
|
||||
StylePath, BASIC_KEYWORDS,
|
||||
};
|
||||
|
||||
use crate::clean;
|
||||
|
@ -131,7 +131,7 @@ crate struct SharedContext<'tcx> {
|
|||
|
||||
/// Correspondance map used to link types used in the source code pages to allow to click on
|
||||
/// links to jump to the type's definition.
|
||||
crate span_correspondance_map: FxHashMap<(u32, u32), LinkFromSrc>,
|
||||
crate span_correspondance_map: FxHashMap<LightSpan, LinkFromSrc>,
|
||||
}
|
||||
|
||||
impl SharedContext<'_> {
|
||||
|
|
|
@ -34,7 +34,7 @@ mod span_map;
|
|||
mod write_shared;
|
||||
|
||||
crate use context::*;
|
||||
crate use span_map::{collect_spans_and_sources, LinkFromSrc};
|
||||
crate use span_map::{collect_spans_and_sources, LightSpan, LinkFromSrc};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::default::Default;
|
||||
|
|
|
@ -24,6 +24,43 @@ crate enum LinkFromSrc {
|
|||
External(DefId),
|
||||
}
|
||||
|
||||
/// This struct is used only as index in the `span_map`, not as [`Span`]! `Span`s contain
|
||||
/// some extra information (the syntax context) we don't need. **Do not convert this type back to
|
||||
/// `Span`!!!**
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
|
||||
crate struct LightSpan {
|
||||
crate lo: u32,
|
||||
crate hi: u32,
|
||||
}
|
||||
|
||||
impl LightSpan {
|
||||
/// Before explaining what this method does, some global explanations on rust's `Span`:
|
||||
///
|
||||
/// Each source code file is stored in the source map in the compiler and has a
|
||||
/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
|
||||
/// string to simplify things). So in this case, this represents the starting byte of the
|
||||
/// current file. It'll be used later on to retrieve the "definition span" from the
|
||||
/// `span_correspondance_map` (which is inside `context`).
|
||||
///
|
||||
/// This when we transform the "span" we have from reading the input into a "span" which can be
|
||||
/// used as index to the `span_correspondance_map` to get the definition of this item.
|
||||
///
|
||||
/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to
|
||||
/// make our "span" works in there, we simply add `file_span_lo` to our values.
|
||||
crate fn new_in_file(file_span_lo: u32, lo: u32, hi: u32) -> Self {
|
||||
Self { lo: lo + file_span_lo, hi: hi + file_span_lo }
|
||||
}
|
||||
|
||||
crate fn empty() -> Self {
|
||||
Self { lo: 0, hi: 0 }
|
||||
}
|
||||
|
||||
/// Extra the `lo` and `hi` from the [`Span`] and discard the unused syntax context.
|
||||
fn new_from_span(sp: Span) -> Self {
|
||||
Self { lo: sp.lo().0, hi: sp.hi().0 }
|
||||
}
|
||||
}
|
||||
|
||||
/// This function will do at most two things:
|
||||
///
|
||||
/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
|
||||
|
@ -40,7 +77,7 @@ crate fn collect_spans_and_sources(
|
|||
src_root: &Path,
|
||||
include_sources: bool,
|
||||
generate_link_to_definition: bool,
|
||||
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<(u32, u32), LinkFromSrc>) {
|
||||
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<LightSpan, LinkFromSrc>) {
|
||||
let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
|
||||
|
||||
if include_sources {
|
||||
|
@ -54,13 +91,9 @@ crate fn collect_spans_and_sources(
|
|||
}
|
||||
}
|
||||
|
||||
fn span_to_tuple(span: Span) -> (u32, u32) {
|
||||
(span.lo().0, span.hi().0)
|
||||
}
|
||||
|
||||
struct SpanMapVisitor<'tcx> {
|
||||
crate tcx: TyCtxt<'tcx>,
|
||||
crate matches: FxHashMap<(u32, u32), LinkFromSrc>,
|
||||
crate matches: FxHashMap<LightSpan, LinkFromSrc>,
|
||||
}
|
||||
|
||||
impl<'tcx> SpanMapVisitor<'tcx> {
|
||||
|
@ -77,12 +110,16 @@ impl<'tcx> SpanMapVisitor<'tcx> {
|
|||
};
|
||||
if let Some(span) = self.tcx.hir().res_span(path.res) {
|
||||
self.matches.insert(
|
||||
path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
|
||||
path_span
|
||||
.map(LightSpan::new_from_span)
|
||||
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
|
||||
LinkFromSrc::Local(span),
|
||||
);
|
||||
} else if let Some(def_id) = info {
|
||||
self.matches.insert(
|
||||
path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
|
||||
path_span
|
||||
.map(LightSpan::new_from_span)
|
||||
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
|
||||
LinkFromSrc::External(def_id),
|
||||
);
|
||||
}
|
||||
|
@ -122,8 +159,10 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
|
|||
if let Some(node) = self.tcx.hir().find(id) {
|
||||
match node {
|
||||
Node::Item(item) => {
|
||||
self.matches
|
||||
.insert(span_to_tuple(item.ident.span), LinkFromSrc::Local(m.inner));
|
||||
self.matches.insert(
|
||||
LightSpan::new_from_span(item.ident.span),
|
||||
LinkFromSrc::Local(m.inner),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -146,12 +185,14 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
|
|||
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
|
||||
match hir.span_if_local(def_id) {
|
||||
Some(span) => {
|
||||
self.matches
|
||||
.insert(span_to_tuple(method_span), LinkFromSrc::Local(span));
|
||||
self.matches.insert(
|
||||
LightSpan::new_from_span(method_span),
|
||||
LinkFromSrc::Local(span),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
self.matches.insert(
|
||||
span_to_tuple(method_span),
|
||||
LightSpan::new_from_span(method_span),
|
||||
LinkFromSrc::External(def_id),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue