about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-04-20 17:42:06 +0200
committerGuillaume Gomez <guillaume.gomez@huawei.com>2021-08-05 23:08:28 +0200
commit2a3b71ae33e1b5c4f8cecf32492f69a05faa7d93 (patch)
tree0c877ecd9ef2df205d5e4fc3e728c121ada1f513
parentb5c27b49d02d5b6538e40e19e0dd1365cd7632d5 (diff)
downloadrust-2a3b71ae33e1b5c4f8cecf32492f69a05faa7d93.tar.gz
rust-2a3b71ae33e1b5c4f8cecf32492f69a05faa7d93.zip
* Rename 'move_span' into 'local_span_to_global_span'
* Add documentation on new arguments/functions
-rw-r--r--src/librustdoc/clean/types.rs10
-rw-r--r--src/librustdoc/html/format.rs5
-rw-r--r--src/librustdoc/html/highlight.rs70
-rw-r--r--src/librustdoc/html/render/span_map.rs17
4 files changed, 85 insertions, 17 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 85c4731c6bf..d79fcdd5fce 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1943,14 +1943,18 @@ crate enum Variant {
 crate struct Span(rustc_span::Span);
 
 impl Span {
+    /// Wraps a [`rustc_span::Span`]. In case this span is the result of a macro expansion, the
+    /// span will be updated to point to the macro invocation instead of the macro definition.
+    ///
+    /// (See rust-lang/rust#39726)
     crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
-        // Get the macro invocation instead of the definition,
-        // in case the span is result of a macro expansion.
-        // (See rust-lang/rust#39726)
         Self(sp.source_callsite())
     }
 
     /// Unless you know what you're doing, use [`Self::from_rustc_span`] instead!
+    ///
+    /// Contrary to [`Self::from_rustc_span`], this constructor wraps the span as is and don't
+    /// perform any operation on it, even if it's from a macro expansion.
     crate fn wrap(sp: rustc_span::Span) -> Span {
         Self(sp)
     }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 8b5c147b56c..8ab6aa775d2 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -494,10 +494,7 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Result<(String, ItemType, Vec<Str
     if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
         return Err(HrefError::Private);
     }
-    // href_with_depth_inner(did, cache, || {
-    //     let depth = CURRENT_DEPTH.with(|l| l.get());
-    //     "../".repeat(depth)
-    // })
+
     let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
         Some(&(ref fqp, shortty)) => (fqp, shortty, {
             let module_fqp = to_module_fqp(shortty, fqp);
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 579f22052ad..62f8618b8c6 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -63,6 +63,24 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
     }
 }
 
+/// Convert the given `src` source code into HTML by adding classes for highlighting.
+///
+/// This code is used to render code blocks (in the documentation) as well as the source code pages.
+///
+/// Some explanations on the last arguments:
+///
+/// In case we are rendering a code block and not a source code file, `file_span_lo` value doesn't
+/// matter and `context` will be `None`. To put it more simply: if `context` is `None`, the code
+/// 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.
+///
+/// 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.
+///
+/// Same as `file_span_lo`: its value doesn't matter in case you are not rendering a source code
+/// file.
 fn write_code(
     out: &mut Buffer,
     src: &str,
@@ -135,6 +153,8 @@ 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)> {
         match self {
             Self::Ident(sp) | Self::Self_(sp) => Some(sp),
@@ -166,7 +186,7 @@ impl Iterator for TokenIter<'a> {
     }
 }
 
-/// Returns `None` if this is a `Class::Ident`.
+/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
 fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool) -> Option<Class> {
     let ignore: &[&str] =
         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)
     })
 }
 
-fn move_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
+/// 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)
 }
 
@@ -199,6 +232,9 @@ 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.
     fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
         let tokens = TokenIter { src }.peekable();
         Classifier {
@@ -263,7 +299,10 @@ impl<'a> Classifier<'a> {
         }
     }
 
-    /// Wraps the tokens iteration to ensure that the byte_pos is always correct.
+    /// Wraps the tokens iteration to ensure that the `byte_pos` is always correct.
+    ///
+    /// It returns the token's kind, the token as a string and its byte position in the source
+    /// string.
     fn next(&mut self) -> Option<(TokenKind, &'a str, u32)> {
         if let Some((kind, text)) = self.tokens.next() {
             let before = self.byte_pos;
@@ -306,8 +345,12 @@ impl<'a> Classifier<'a> {
         }
     }
 
-    /// Single step of highlighting. This will classify `token`, but maybe also
-    /// a couple of following ones as well.
+    /// Single step of highlighting. This will classify `token`, but maybe also a couple of
+    /// following ones as well.
+    ///
+    /// `before` is the position of the given token in the `source` string and is used as "lo" byte
+    /// in case we want to try to generate a link for this token using the
+    /// `span_correspondance_map`.
     fn advance(
         &mut self,
         token: TokenKind,
@@ -453,12 +496,12 @@ impl<'a> Classifier<'a> {
                         self.in_macro_nonterminal = false;
                         Class::MacroNonTerminal
                     }
-                    "self" | "Self" => Class::Self_(move_span(
+                    "self" | "Self" => Class::Self_(local_span_to_global_span(
                         self.file_span_lo,
                         before,
                         before + text.len() as u32,
                     )),
-                    _ => Class::Ident(move_span(
+                    _ => Class::Ident(local_span_to_global_span(
                         self.file_span_lo,
                         before,
                         before + text.len() as u32,
@@ -466,9 +509,11 @@ impl<'a> Classifier<'a> {
                 },
                 Some(c) => c,
             },
-            TokenKind::RawIdent | TokenKind::UnknownPrefix => {
-                Class::Ident(move_span(self.file_span_lo, before, before + text.len() as u32))
-            }
+            TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(local_span_to_global_span(
+                self.file_span_lo,
+                before,
+                before + text.len() as u32,
+            )),
             TokenKind::Lifetime { .. } => Class::Lifetime,
         };
         // Anything that didn't return above is the simple case where we the
@@ -501,8 +546,13 @@ fn exit_span(out: &mut Buffer) {
 ///     enter_span(Foo), string("text", None), exit_span()
 ///     string("text", Foo)
 /// ```
+///
 /// The latter can be thought of as a shorthand for the former, which is more
 /// flexible.
+///
+/// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function
+/// will then try to find this `span` in the `span_correspondance_map`. If found, it'll then
+/// generate a link for this element (which corresponds to where its definition is located).
 fn string<T: Display>(
     out: &mut Buffer,
     text: T,
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 6100f45e998..9e16c451626 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -9,12 +9,29 @@ use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Mod, Node};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
+/// This enum allows us to store two different kinds of information:
+///
+/// In case the `span` definition comes from the same crate, we can simply get the `span` and use
+/// it as is.
+///
+/// Otherwise, we store the definition `DefId` and will generate a link to the documentation page
+/// instead of the source code directly.
 #[derive(Debug)]
 crate enum LinkFromSrc {
     Local(Span),
     External(DefId),
 }
 
+/// This function will do at most two things:
+///
+/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
+/// 2. Collect the source code files.
+///
+/// It returns the `krate`, the source code files and the `span` correspondance map.
+///
+/// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't
+/// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
+/// only keep the `lo` and `hi`.
 crate fn collect_spans_and_sources(
     tcx: TyCtxt<'_>,
     krate: clean::Crate,