Skip to content

Commit 2a3b71a

Browse files
* Rename 'move_span' into 'local_span_to_global_span'
* Add documentation on new arguments/functions
1 parent b5c27b4 commit 2a3b71a

File tree

4 files changed

+85
-17
lines changed

4 files changed

+85
-17
lines changed

src/librustdoc/clean/types.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,14 +1943,18 @@ crate enum Variant {
19431943
crate struct Span(rustc_span::Span);
19441944

19451945
impl Span {
1946+
/// Wraps a [`rustc_span::Span`]. In case this span is the result of a macro expansion, the
1947+
/// span will be updated to point to the macro invocation instead of the macro definition.
1948+
///
1949+
/// (See rust-lang/rust#39726)
19461950
crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
1947-
// Get the macro invocation instead of the definition,
1948-
// in case the span is result of a macro expansion.
1949-
// (See rust-lang/rust#39726)
19501951
Self(sp.source_callsite())
19511952
}
19521953

19531954
/// Unless you know what you're doing, use [`Self::from_rustc_span`] instead!
1955+
///
1956+
/// Contrary to [`Self::from_rustc_span`], this constructor wraps the span as is and don't
1957+
/// perform any operation on it, even if it's from a macro expansion.
19541958
crate fn wrap(sp: rustc_span::Span) -> Span {
19551959
Self(sp)
19561960
}

src/librustdoc/html/format.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,7 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Result<(String, ItemType, Vec<Str
494494
if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
495495
return Err(HrefError::Private);
496496
}
497-
// href_with_depth_inner(did, cache, || {
498-
// let depth = CURRENT_DEPTH.with(|l| l.get());
499-
// "../".repeat(depth)
500-
// })
497+
501498
let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
502499
Some(&(ref fqp, shortty)) => (fqp, shortty, {
503500
let module_fqp = to_module_fqp(shortty, fqp);

src/librustdoc/html/highlight.rs

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,24 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
6363
}
6464
}
6565

66+
/// Convert the given `src` source code into HTML by adding classes for highlighting.
67+
///
68+
/// This code is used to render code blocks (in the documentation) as well as the source code pages.
69+
///
70+
/// Some explanations on the last arguments:
71+
///
72+
/// In case we are rendering a code block and not a source code file, `file_span_lo` value doesn't
73+
/// matter and `context` will be `None`. To put it more simply: if `context` is `None`, the code
74+
/// won't try to generate links to an ident definition.
75+
///
76+
/// More explanations about spans and how we use them here are provided in the
77+
/// [`local_span_to_global_span`] function documentation about how it works.
78+
///
79+
/// As for `root_path`, it's used to know "how far" from the top of the directory we are to link
80+
/// to either documentation pages or other source pages.
81+
///
82+
/// Same as `file_span_lo`: its value doesn't matter in case you are not rendering a source code
83+
/// file.
6684
fn write_code(
6785
out: &mut Buffer,
6886
src: &str,
@@ -135,6 +153,8 @@ impl Class {
135153
}
136154
}
137155

156+
/// In case this is an item which can be converted into a link to a definition, it'll contain
157+
/// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
138158
fn get_span(self) -> Option<(u32, u32)> {
139159
match self {
140160
Self::Ident(sp) | Self::Self_(sp) => Some(sp),
@@ -166,7 +186,7 @@ impl Iterator for TokenIter<'a> {
166186
}
167187
}
168188

169-
/// Returns `None` if this is a `Class::Ident`.
189+
/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
170190
fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool) -> Option<Class> {
171191
let ignore: &[&str] =
172192
if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] };
@@ -181,7 +201,20 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
181201
})
182202
}
183203

184-
fn move_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
204+
/// Before explaining what this function does, some global explanations on rust's `Span`:
205+
///
206+
/// Each source code file is stored in the source map in the compiler and has a
207+
/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
208+
/// string to simplify things). So in this case, this represents the starting byte of the current
209+
/// file. It'll be used later on to retrieve the "definition span" from the
210+
/// `span_correspondance_map` (which is inside `context`).
211+
///
212+
/// This when we transform the "span" we have from reading the input into a "span" which can be
213+
/// used as index to the `span_correspondance_map` to get the definition of this item.
214+
///
215+
/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to make
216+
/// our "span" works in there, we simply add `file_span_lo` to our values.
217+
fn local_span_to_global_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
185218
(start + file_span_lo, end + file_span_lo)
186219
}
187220

@@ -199,6 +232,9 @@ struct Classifier<'a> {
199232
}
200233

201234
impl<'a> Classifier<'a> {
235+
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
236+
/// file "lo" byte which we be used later on by the `span_correspondance_map`. More explanations
237+
/// are provided in the [`local_span_to_global_span`] function documentation about how it works.
202238
fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
203239
let tokens = TokenIter { src }.peekable();
204240
Classifier {
@@ -263,7 +299,10 @@ impl<'a> Classifier<'a> {
263299
}
264300
}
265301

266-
/// Wraps the tokens iteration to ensure that the byte_pos is always correct.
302+
/// Wraps the tokens iteration to ensure that the `byte_pos` is always correct.
303+
///
304+
/// It returns the token's kind, the token as a string and its byte position in the source
305+
/// string.
267306
fn next(&mut self) -> Option<(TokenKind, &'a str, u32)> {
268307
if let Some((kind, text)) = self.tokens.next() {
269308
let before = self.byte_pos;
@@ -306,8 +345,12 @@ impl<'a> Classifier<'a> {
306345
}
307346
}
308347

309-
/// Single step of highlighting. This will classify `token`, but maybe also
310-
/// a couple of following ones as well.
348+
/// Single step of highlighting. This will classify `token`, but maybe also a couple of
349+
/// following ones as well.
350+
///
351+
/// `before` is the position of the given token in the `source` string and is used as "lo" byte
352+
/// in case we want to try to generate a link for this token using the
353+
/// `span_correspondance_map`.
311354
fn advance(
312355
&mut self,
313356
token: TokenKind,
@@ -453,22 +496,24 @@ impl<'a> Classifier<'a> {
453496
self.in_macro_nonterminal = false;
454497
Class::MacroNonTerminal
455498
}
456-
"self" | "Self" => Class::Self_(move_span(
499+
"self" | "Self" => Class::Self_(local_span_to_global_span(
457500
self.file_span_lo,
458501
before,
459502
before + text.len() as u32,
460503
)),
461-
_ => Class::Ident(move_span(
504+
_ => Class::Ident(local_span_to_global_span(
462505
self.file_span_lo,
463506
before,
464507
before + text.len() as u32,
465508
)),
466509
},
467510
Some(c) => c,
468511
},
469-
TokenKind::RawIdent | TokenKind::UnknownPrefix => {
470-
Class::Ident(move_span(self.file_span_lo, before, before + text.len() as u32))
471-
}
512+
TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(local_span_to_global_span(
513+
self.file_span_lo,
514+
before,
515+
before + text.len() as u32,
516+
)),
472517
TokenKind::Lifetime { .. } => Class::Lifetime,
473518
};
474519
// Anything that didn't return above is the simple case where we the
@@ -501,8 +546,13 @@ fn exit_span(out: &mut Buffer) {
501546
/// enter_span(Foo), string("text", None), exit_span()
502547
/// string("text", Foo)
503548
/// ```
549+
///
504550
/// The latter can be thought of as a shorthand for the former, which is more
505551
/// flexible.
552+
///
553+
/// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function
554+
/// will then try to find this `span` in the `span_correspondance_map`. If found, it'll then
555+
/// generate a link for this element (which corresponds to where its definition is located).
506556
fn string<T: Display>(
507557
out: &mut Buffer,
508558
text: T,

src/librustdoc/html/render/span_map.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,29 @@ use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Mod, Node};
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_span::Span;
1111

12+
/// This enum allows us to store two different kinds of information:
13+
///
14+
/// In case the `span` definition comes from the same crate, we can simply get the `span` and use
15+
/// it as is.
16+
///
17+
/// Otherwise, we store the definition `DefId` and will generate a link to the documentation page
18+
/// instead of the source code directly.
1219
#[derive(Debug)]
1320
crate enum LinkFromSrc {
1421
Local(Span),
1522
External(DefId),
1623
}
1724

25+
/// This function will do at most two things:
26+
///
27+
/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
28+
/// 2. Collect the source code files.
29+
///
30+
/// It returns the `krate`, the source code files and the `span` correspondance map.
31+
///
32+
/// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't
33+
/// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
34+
/// only keep the `lo` and `hi`.
1835
crate fn collect_spans_and_sources(
1936
tcx: TyCtxt<'_>,
2037
krate: clean::Crate,

0 commit comments

Comments
 (0)