about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-05-12 17:29:51 +0200
committerGuillaume Gomez <guillaume.gomez@huawei.com>2021-08-05 23:08:29 +0200
commitb336f2801c1d458990b7122bc4eba126beea37f9 (patch)
tree47d38425b0468dbbbdd9f585ef38addc3b410ad4
parentef0d909f26665c6c9967361c2f5d636d29168976 (diff)
downloadrust-b336f2801c1d458990b7122bc4eba126beea37f9.tar.gz
rust-b336f2801c1d458990b7122bc4eba126beea37f9.zip
Fix invalid generation of HTML in highlight
-rw-r--r--src/librustdoc/html/highlight.rs83
-rw-r--r--src/librustdoc/html/highlight/fixtures/highlight.html4
-rw-r--r--src/librustdoc/html/highlight/tests.rs14
3 files changed, 60 insertions, 41 deletions
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 13c02110514..9adb95fe90e 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -313,6 +313,7 @@ impl<'a> Classifier<'a> {
                 .unwrap_or(false)
             {
                 let tokens = self.get_full_ident_path();
+                // We need this variable because `tokens` is consumed in the loop.
                 let skip = !tokens.is_empty();
                 for (token, start, end) in tokens {
                     let text = &self.src[start..end];
@@ -549,51 +550,51 @@ fn string<T: Display>(
         None => return write!(out, "{}", text),
         Some(klass) => klass,
     };
-    if let Some(def_span) = klass.get_span() {
-        let mut text = text.to_string();
-        if text.contains("::") {
-            text = text.split("::").intersperse("::").fold(String::new(), |mut path, t| {
-                match t {
-                    "self" | "Self" => write!(
-                        &mut path,
-                        "<span class=\"{}\">{}</span>",
-                        Class::Self_(LightSpan::empty()).as_html(),
-                        t
-                    ),
-                    "crate" | "super" => write!(
-                        &mut path,
-                        "<span class=\"{}\">{}</span>",
-                        Class::KeyWord.as_html(),
-                        t
-                    ),
-                    t => write!(&mut path, "{}", t),
-                }
-                .expect("Failed to build source HTML path");
-                path
-            });
+    let def_span = match klass.get_span() {
+        Some(d) => d,
+        None => {
+            write!(out, "<span class=\"{}\">{}</span>", klass.as_html(), text);
+            return;
         }
-        if let Some(context_info) = context_info {
-            if let Some(href) =
-                context_info.context.shared.span_correspondance_map.get(&def_span).and_then(
-                    |href| {
-                        let context = context_info.context;
-                        match href {
-                            LinkFromSrc::Local(span) => context
-                                .href_from_span(*span)
-                                .map(|s| format!("{}{}", context_info.root_path, s)),
-                            LinkFromSrc::External(def_id) => {
-                                format::href(*def_id, context).map(|(url, _, _)| url)
-                            }
-                        }
-                    },
-                )
-            {
-                write!(out, "<a class=\"{}\" href=\"{}\">{}</a>", klass.as_html(), href, text);
-                return;
+    };
+    let mut text_s = text.to_string();
+    if text_s.contains("::") {
+        text_s = text_s.split("::").intersperse("::").fold(String::new(), |mut path, t| {
+            match t {
+                "self" | "Self" => write!(
+                    &mut path,
+                    "<span class=\"{}\">{}</span>",
+                    Class::Self_(LightSpan::empty()).as_html(),
+                    t
+                ),
+                "crate" | "super" => {
+                    write!(&mut path, "<span class=\"{}\">{}</span>", Class::KeyWord.as_html(), t)
+                }
+                t => write!(&mut path, "{}", t),
             }
+            .expect("Failed to build source HTML path");
+            path
+        });
+    }
+    if let Some(context_info) = context_info {
+        if let Some(href) =
+            context_info.context.shared.span_correspondance_map.get(&def_span).and_then(|href| {
+                let context = context_info.context;
+                match href {
+                    LinkFromSrc::Local(span) => context
+                        .href_from_span(*span)
+                        .map(|s| format!("{}{}", context_info.root_path, s)),
+                    LinkFromSrc::External(def_id) => {
+                        format::href(*def_id, context).map(|(url, _, _)| url)
+                    }
+                }
+            })
+        {
+            write!(out, "<a class=\"{}\" href=\"{}\">{}</a>", klass.as_html(), href, text_s);
+            return;
         }
     }
-    write!(out, "<span class=\"{}\">{}</span>", klass.as_html(), text);
+    write!(out, "<span class=\"{}\">{}</span>", klass.as_html(), text_s);
 }
 
 #[cfg(test)]
diff --git a/src/librustdoc/html/highlight/fixtures/highlight.html b/src/librustdoc/html/highlight/fixtures/highlight.html
new file mode 100644
index 00000000000..abc2db1790c
--- /dev/null
+++ b/src/librustdoc/html/highlight/fixtures/highlight.html
@@ -0,0 +1,4 @@
+<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::a::foo</span>;
+<span class="kw">use</span> <span class="ident"><span class="self">self</span>::whatever</span>;
+<span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="ident"><span class="kw">super</span>::b::foo</span>;
+<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="ident"><span class="self">Self</span>::whatever</span>;
\ No newline at end of file
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index 1259a1f3a23..68592ae96c1 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -40,3 +40,17 @@ fn test_dos_backline() {
         expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner());
     });
 }
+
+#[test]
+fn test_keyword_highlight() {
+    create_default_session_globals_then(|| {
+        let src = "use crate::a::foo;
+use self::whatever;
+let x = super::b::foo;
+let y = Self::whatever;";
+
+        let mut html = Buffer::new();
+        write_code(&mut html, src, Edition::Edition2018, None);
+        expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner());
+    });
+}