diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-05-12 17:29:51 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume.gomez@huawei.com> | 2021-08-05 23:08:29 +0200 |
| commit | b336f2801c1d458990b7122bc4eba126beea37f9 (patch) | |
| tree | 47d38425b0468dbbbdd9f585ef38addc3b410ad4 | |
| parent | ef0d909f26665c6c9967361c2f5d636d29168976 (diff) | |
| download | rust-b336f2801c1d458990b7122bc4eba126beea37f9.tar.gz rust-b336f2801c1d458990b7122bc4eba126beea37f9.zip | |
Fix invalid generation of HTML in highlight
| -rw-r--r-- | src/librustdoc/html/highlight.rs | 83 | ||||
| -rw-r--r-- | src/librustdoc/html/highlight/fixtures/highlight.html | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/highlight/tests.rs | 14 |
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()); + }); +} |
