Skip to content

Commit 72d0be4

Browse files
authored
Rollup merge of rust-lang#99337 - jsha:simplify-highlight, r=GuillaumeGomez
rustdoc: simplify highlight.rs Split render_with_highlighting, which took many optional parameters, into three functions for specific purposes, which each take a smaller number of mostly required parameters. Remove some plumbing to pass through an "edition" parameter, which was used solely to avoid highlighting some 2021 Edition keywords in non-2021 code. I've tested a build of std docs before and after, and this does not change the generated HTML at all. Followup from rust-lang#91264 (comment) r? ``@GuillaumeGomez``
2 parents 23acd82 + 5938fd7 commit 72d0be4

File tree

6 files changed

+75
-79
lines changed

6 files changed

+75
-79
lines changed

src/librustdoc/html/highlight.rs

+55-33
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,80 @@ pub(crate) struct HrefContext<'a, 'b, 'c> {
3333

3434
/// Decorations are represented as a map from CSS class to vector of character ranges.
3535
/// Each range will be wrapped in a span with that class.
36+
#[derive(Default)]
3637
pub(crate) struct DecorationInfo(pub(crate) FxHashMap<&'static str, Vec<(u32, u32)>>);
3738

38-
/// Highlights `src`, returning the HTML output.
39-
pub(crate) fn render_with_highlighting(
39+
#[derive(Eq, PartialEq, Clone, Copy)]
40+
pub(crate) enum Tooltip {
41+
Ignore,
42+
CompileFail,
43+
ShouldPanic,
44+
Edition(Edition),
45+
None,
46+
}
47+
48+
/// Highlights `src` as an inline example, returning the HTML output.
49+
pub(crate) fn render_example_with_highlighting(
4050
src: &str,
4151
out: &mut Buffer,
42-
class: Option<&str>,
52+
tooltip: Tooltip,
4353
playground_button: Option<&str>,
44-
tooltip: Option<(Option<Edition>, &str)>,
45-
edition: Edition,
46-
extra_content: Option<Buffer>,
47-
href_context: Option<HrefContext<'_, '_, '_>>,
48-
decoration_info: Option<DecorationInfo>,
4954
) {
50-
debug!("highlighting: ================\n{}\n==============", src);
51-
if let Some((edition_info, class)) = tooltip {
55+
let class = match tooltip {
56+
Tooltip::Ignore => " ignore",
57+
Tooltip::CompileFail => " compile_fail",
58+
Tooltip::ShouldPanic => " should_panic",
59+
Tooltip::Edition(_) => " edition",
60+
Tooltip::None => "",
61+
};
62+
63+
if tooltip != Tooltip::None {
5264
write!(
5365
out,
54-
"<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>",
66+
"<div class='information'><div class='tooltip{}'{}>ⓘ</div></div>",
5567
class,
56-
if let Some(edition_info) = edition_info {
68+
if let Tooltip::Edition(edition_info) = tooltip {
5769
format!(" data-edition=\"{}\"", edition_info)
5870
} else {
5971
String::new()
6072
},
6173
);
6274
}
6375

64-
write_header(out, class, extra_content);
65-
write_code(out, src, edition, href_context, decoration_info);
76+
write_header(out, &format!("rust-example-rendered{}", class), None);
77+
write_code(out, src, None, None);
6678
write_footer(out, playground_button);
6779
}
6880

69-
fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buffer>) {
81+
/// Highlights `src` as a macro, returning the HTML output.
82+
pub(crate) fn render_macro_with_highlighting(src: &str, out: &mut Buffer) {
83+
write_header(out, "macro", None);
84+
write_code(out, src, None, None);
85+
write_footer(out, None);
86+
}
87+
88+
/// Highlights `src` as a source code page, returning the HTML output.
89+
pub(crate) fn render_source_with_highlighting(
90+
src: &str,
91+
out: &mut Buffer,
92+
line_numbers: Buffer,
93+
href_context: HrefContext<'_, '_, '_>,
94+
decoration_info: DecorationInfo,
95+
) {
96+
write_header(out, "", Some(line_numbers));
97+
write_code(out, src, Some(href_context), Some(decoration_info));
98+
write_footer(out, None);
99+
}
100+
101+
fn write_header(out: &mut Buffer, class: &str, extra_content: Option<Buffer>) {
70102
write!(out, "<div class=\"example-wrap\">");
71103
if let Some(extra) = extra_content {
72104
out.push_buffer(extra);
73105
}
74-
if let Some(class) = class {
75-
write!(out, "<pre class=\"rust {}\">", class);
76-
} else {
106+
if class.is_empty() {
77107
write!(out, "<pre class=\"rust\">");
108+
} else {
109+
write!(out, "<pre class=\"rust {}\">", class);
78110
}
79111
write!(out, "<code>");
80112
}
@@ -93,7 +125,6 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
93125
fn write_code(
94126
out: &mut Buffer,
95127
src: &str,
96-
edition: Edition,
97128
href_context: Option<HrefContext<'_, '_, '_>>,
98129
decoration_info: Option<DecorationInfo>,
99130
) {
@@ -102,7 +133,6 @@ fn write_code(
102133
let mut closing_tags: Vec<&'static str> = Vec::new();
103134
Classifier::new(
104135
&src,
105-
edition,
106136
href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
107137
decoration_info,
108138
)
@@ -220,7 +250,7 @@ impl<'a> Iterator for TokenIter<'a> {
220250
}
221251

222252
/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
223-
fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool) -> Option<Class> {
253+
fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option<Class> {
224254
let ignore: &[&str] =
225255
if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] };
226256
if ignore.iter().any(|k| *k == text) {
@@ -229,7 +259,7 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
229259
Some(match text {
230260
"ref" | "mut" => Class::RefKeyWord,
231261
"false" | "true" => Class::Bool,
232-
_ if Symbol::intern(text).is_reserved(|| edition) => Class::KeyWord,
262+
_ if Symbol::intern(text).is_reserved(|| Edition::Edition2021) => Class::KeyWord,
233263
_ => return None,
234264
})
235265
}
@@ -311,7 +341,6 @@ struct Classifier<'a> {
311341
in_attribute: bool,
312342
in_macro: bool,
313343
in_macro_nonterminal: bool,
314-
edition: Edition,
315344
byte_pos: u32,
316345
file_span: Span,
317346
src: &'a str,
@@ -321,20 +350,14 @@ struct Classifier<'a> {
321350
impl<'a> Classifier<'a> {
322351
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
323352
/// file span which will be used later on by the `span_correspondance_map`.
324-
fn new(
325-
src: &str,
326-
edition: Edition,
327-
file_span: Span,
328-
decoration_info: Option<DecorationInfo>,
329-
) -> Classifier<'_> {
353+
fn new(src: &str, file_span: Span, decoration_info: Option<DecorationInfo>) -> Classifier<'_> {
330354
let tokens = PeekIter::new(TokenIter { src });
331355
let decorations = decoration_info.map(Decorations::new);
332356
Classifier {
333357
tokens,
334358
in_attribute: false,
335359
in_macro: false,
336360
in_macro_nonterminal: false,
337-
edition,
338361
byte_pos: 0,
339362
file_span,
340363
src,
@@ -354,7 +377,6 @@ impl<'a> Classifier<'a> {
354377
let start = self.byte_pos as usize;
355378
let mut pos = start;
356379
let mut has_ident = false;
357-
let edition = self.edition;
358380

359381
loop {
360382
let mut nb = 0;
@@ -376,7 +398,7 @@ impl<'a> Classifier<'a> {
376398

377399
if let Some((None, text)) = self.tokens.peek().map(|(token, text)| {
378400
if *token == TokenKind::Ident {
379-
let class = get_real_ident_class(text, edition, true);
401+
let class = get_real_ident_class(text, true);
380402
(class, text)
381403
} else {
382404
// Doesn't matter which Class we put in here...
@@ -634,7 +656,7 @@ impl<'a> Classifier<'a> {
634656
sink(Highlight::Token { text, class: None });
635657
return;
636658
}
637-
TokenKind::Ident => match get_real_ident_class(text, self.edition, false) {
659+
TokenKind::Ident => match get_real_ident_class(text, false) {
638660
None => match text {
639661
"Option" | "Result" => Class::PreludeTy,
640662
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal,

src/librustdoc/html/highlight/tests.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::html::format::Buffer;
33
use expect_test::expect_file;
44
use rustc_data_structures::fx::FxHashMap;
55
use rustc_span::create_default_session_globals_then;
6-
use rustc_span::edition::Edition;
76

87
const STYLE: &str = r#"
98
<style>
@@ -23,7 +22,7 @@ fn test_html_highlighting() {
2322
let src = include_str!("fixtures/sample.rs");
2423
let html = {
2524
let mut out = Buffer::new();
26-
write_code(&mut out, src, Edition::Edition2018, None, None);
25+
write_code(&mut out, src, None, None);
2726
format!("{}<pre><code>{}</code></pre>\n", STYLE, out.into_inner())
2827
};
2928
expect_file!["fixtures/sample.html"].assert_eq(&html);
@@ -37,7 +36,7 @@ fn test_dos_backline() {
3736
println!(\"foo\");\r\n\
3837
}\r\n";
3938
let mut html = Buffer::new();
40-
write_code(&mut html, src, Edition::Edition2018, None, None);
39+
write_code(&mut html, src, None, None);
4140
expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner());
4241
});
4342
}
@@ -51,7 +50,7 @@ let x = super::b::foo;
5150
let y = Self::whatever;";
5251

5352
let mut html = Buffer::new();
54-
write_code(&mut html, src, Edition::Edition2018, None, None);
53+
write_code(&mut html, src, None, None);
5554
expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner());
5655
});
5756
}
@@ -61,7 +60,7 @@ fn test_union_highlighting() {
6160
create_default_session_globals_then(|| {
6261
let src = include_str!("fixtures/union.rs");
6362
let mut html = Buffer::new();
64-
write_code(&mut html, src, Edition::Edition2018, None, None);
63+
write_code(&mut html, src, None, None);
6564
expect_file!["fixtures/union.html"].assert_eq(&html.into_inner());
6665
});
6766
}
@@ -75,7 +74,7 @@ let y = 2;";
7574
decorations.insert("example", vec![(0, 10)]);
7675

7776
let mut html = Buffer::new();
78-
write_code(&mut html, src, Edition::Edition2018, None, Some(DecorationInfo(decorations)));
77+
write_code(&mut html, src, None, Some(DecorationInfo(decorations)));
7978
expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner());
8079
});
8180
}

src/librustdoc/html/markdown.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -330,34 +330,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
330330
});
331331

332332
let tooltip = if ignore != Ignore::None {
333-
Some((None, "ignore"))
333+
highlight::Tooltip::Ignore
334334
} else if compile_fail {
335-
Some((None, "compile_fail"))
335+
highlight::Tooltip::CompileFail
336336
} else if should_panic {
337-
Some((None, "should_panic"))
337+
highlight::Tooltip::ShouldPanic
338338
} else if explicit_edition {
339-
Some((Some(edition), "edition"))
339+
highlight::Tooltip::Edition(edition)
340340
} else {
341-
None
341+
highlight::Tooltip::None
342342
};
343343

344344
// insert newline to clearly separate it from the
345345
// previous block so we can shorten the html output
346346
let mut s = Buffer::new();
347347
s.push_str("\n");
348-
highlight::render_with_highlighting(
348+
349+
highlight::render_example_with_highlighting(
349350
&text,
350351
&mut s,
351-
Some(&format!(
352-
"rust-example-rendered{}",
353-
if let Some((_, class)) = tooltip { format!(" {}", class) } else { String::new() }
354-
)),
355-
playground_button.as_deref(),
356352
tooltip,
357-
edition,
358-
None,
359-
None,
360-
None,
353+
playground_button.as_deref(),
361354
);
362355
Some(Event::Html(s.into_inner().into()))
363356
}

src/librustdoc/html/render/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2773,11 +2773,10 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
27732773
sources::print_src(
27742774
w,
27752775
contents_subset,
2776-
call_data.edition,
27772776
file_span,
27782777
cx,
27792778
&root_path,
2780-
Some(highlight::DecorationInfo(decoration_info)),
2779+
highlight::DecorationInfo(decoration_info),
27812780
sources::SourceContext::Embedded { offset: line_min },
27822781
);
27832782
write!(w, "</div></div>");

src/librustdoc/html/render/print_item.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1322,17 +1322,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
13221322

13231323
fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
13241324
wrap_into_docblock(w, |w| {
1325-
highlight::render_with_highlighting(
1326-
&t.source,
1327-
w,
1328-
Some("macro"),
1329-
None,
1330-
None,
1331-
it.span(cx.tcx()).inner().edition(),
1332-
None,
1333-
None,
1334-
None,
1335-
);
1325+
highlight::render_macro_with_highlighting(&t.source, w);
13361326
});
13371327
document(w, cx, it, None, HeadingOffset::H2)
13381328
}

src/librustdoc/html/sources.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1111
use rustc_hir::def_id::LOCAL_CRATE;
1212
use rustc_middle::ty::TyCtxt;
1313
use rustc_session::Session;
14-
use rustc_span::edition::Edition;
1514
use rustc_span::source_map::FileName;
1615

1716
use std::ffi::OsStr;
@@ -213,11 +212,10 @@ impl SourceCollector<'_, '_> {
213212
print_src(
214213
buf,
215214
contents,
216-
cx.shared.edition(),
217215
file_span,
218216
cx,
219217
&root_path,
220-
None,
218+
highlight::DecorationInfo::default(),
221219
SourceContext::Standalone,
222220
)
223221
},
@@ -266,11 +264,10 @@ pub(crate) enum SourceContext {
266264
pub(crate) fn print_src(
267265
buf: &mut Buffer,
268266
s: &str,
269-
edition: Edition,
270267
file_span: rustc_span::Span,
271268
context: &Context<'_>,
272269
root_path: &str,
273-
decoration_info: Option<highlight::DecorationInfo>,
270+
decoration_info: highlight::DecorationInfo,
274271
source_context: SourceContext,
275272
) {
276273
let lines = s.lines().count();
@@ -289,15 +286,11 @@ pub(crate) fn print_src(
289286
}
290287
}
291288
line_numbers.write_str("</pre>");
292-
highlight::render_with_highlighting(
289+
highlight::render_source_with_highlighting(
293290
s,
294291
buf,
295-
None,
296-
None,
297-
None,
298-
edition,
299-
Some(line_numbers),
300-
Some(highlight::HrefContext { context, file_span, root_path }),
292+
line_numbers,
293+
highlight::HrefContext { context, file_span, root_path },
301294
decoration_info,
302295
);
303296
}

0 commit comments

Comments
 (0)