Skip to content

Commit 0582085

Browse files
committed
rustdoc: Refactor keyword highlighting and make metavars take precedence
1 parent a5f0713 commit 0582085

File tree

1 file changed

+37
-46
lines changed

1 file changed

+37
-46
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -754,22 +754,6 @@ impl<'a> Iterator for TokenIter<'a> {
754754
}
755755
}
756756

757-
/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
758-
fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option<Class> {
759-
let ignore: &[&str] =
760-
if allow_path_keywords { &["self", "Self", "super", "crate"] } else { &["self", "Self"] };
761-
if ignore.contains(&text) {
762-
return None;
763-
}
764-
Some(match text {
765-
"ref" | "mut" => Class::RefKeyWord,
766-
"false" | "true" => Class::Bool,
767-
// FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument.
768-
_ if Symbol::intern(text).is_reserved(|| Edition::Edition2024) => Class::KeyWord,
769-
_ => return None,
770-
})
771-
}
772-
773757
/// This iterator comes from the same idea than "Peekable" except that it allows to "peek" more than
774758
/// just the next item by using `peek_next`. The `peek` method always returns the next item after
775759
/// the current one whereas `peek_next` will return the next item after the last one peeked.
@@ -787,16 +771,16 @@ impl<'a> PeekIter<'a> {
787771
Self { stored: VecDeque::new(), peek_pos: 0, iter }
788772
}
789773
/// Returns the next item after the current one. It doesn't interfere with `peek_next` output.
790-
fn peek(&mut self) -> Option<&(TokenKind, &'a str)> {
774+
fn peek(&mut self) -> Option<(TokenKind, &'a str)> {
791775
if self.stored.is_empty()
792776
&& let Some(next) = self.iter.next()
793777
{
794778
self.stored.push_back(next);
795779
}
796-
self.stored.front()
780+
self.stored.front().copied()
797781
}
798782
/// Returns the next item after the last one peeked. It doesn't interfere with `peek` output.
799-
fn peek_next(&mut self) -> Option<&(TokenKind, &'a str)> {
783+
fn peek_next(&mut self) -> Option<(TokenKind, &'a str)> {
800784
self.peek_pos += 1;
801785
if self.peek_pos - 1 < self.stored.len() {
802786
self.stored.get(self.peek_pos - 1)
@@ -806,6 +790,7 @@ impl<'a> PeekIter<'a> {
806790
} else {
807791
None
808792
}
793+
.copied()
809794
}
810795

811796
fn stop_peeking(&mut self) {
@@ -956,15 +941,10 @@ impl<'src> Classifier<'src> {
956941
}
957942
}
958943

959-
if let Some((None, text)) = self.tokens.peek().map(|(token, text)| {
960-
if *token == TokenKind::Ident {
961-
let class = get_real_ident_class(text, true);
962-
(class, text)
963-
} else {
964-
// Doesn't matter which Class we put in here...
965-
(Some(Class::Comment), text)
966-
}
967-
}) {
944+
if let Some((TokenKind::Ident, text)) = self.tokens.peek()
945+
&& let symbol = Symbol::intern(text)
946+
&& (symbol.is_path_segment_keyword() || !is_keyword(symbol))
947+
{
968948
// We only "add" the colon if there is an ident behind.
969949
pos += text.len() + nb;
970950
has_ident = true;
@@ -1210,22 +1190,7 @@ impl<'src> Classifier<'src> {
12101190
sink(span, Highlight::Token { text, class: None });
12111191
return;
12121192
}
1213-
TokenKind::Ident => match get_real_ident_class(text, false) {
1214-
None => match text {
1215-
"Option" | "Result" => Class::PreludeTy(new_span(before, text, file_span)),
1216-
"Some" | "None" | "Ok" | "Err" => {
1217-
Class::PreludeVal(new_span(before, text, file_span))
1218-
}
1219-
_ if self.is_weak_keyword(text) => Class::KeyWord,
1220-
_ if self.in_macro_nonterminal => {
1221-
self.in_macro_nonterminal = false;
1222-
Class::MacroNonTerminal
1223-
}
1224-
"self" | "Self" => Class::Self_(new_span(before, text, file_span)),
1225-
_ => Class::Ident(new_span(before, text, file_span)),
1226-
},
1227-
Some(c) => c,
1228-
},
1193+
TokenKind::Ident => self.classify_ident(before, text),
12291194
TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => {
12301195
Class::Ident(new_span(before, text, file_span))
12311196
}
@@ -1246,6 +1211,27 @@ impl<'src> Classifier<'src> {
12461211
}
12471212
}
12481213

1214+
fn classify_ident(&mut self, before: u32, text: &'src str) -> Class {
1215+
// Macro non-terminals (meta vars) take precedence.
1216+
if self.in_macro_nonterminal {
1217+
self.in_macro_nonterminal = false;
1218+
return Class::MacroNonTerminal;
1219+
}
1220+
1221+
let file_span = self.file_span;
1222+
let span = || new_span(before, text, file_span);
1223+
1224+
match text {
1225+
"ref" | "mut" => Class::RefKeyWord,
1226+
"false" | "true" => Class::Bool,
1227+
"self" | "Self" => Class::Self_(span()),
1228+
"Option" | "Result" => Class::PreludeTy(span()),
1229+
"Some" | "None" | "Ok" | "Err" => Class::PreludeVal(span()),
1230+
_ if self.is_weak_keyword(text) || is_keyword(Symbol::intern(text)) => Class::KeyWord,
1231+
_ => Class::Ident(span()),
1232+
}
1233+
}
1234+
12491235
fn is_weak_keyword(&mut self, text: &str) -> bool {
12501236
// NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization),
12511237
// `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are
@@ -1263,11 +1249,11 @@ impl<'src> Classifier<'src> {
12631249
}
12641250

12651251
fn peek(&mut self) -> Option<TokenKind> {
1266-
self.tokens.peek().map(|&(kind, _)| kind)
1252+
self.tokens.peek().map(|(kind, _)| kind)
12671253
}
12681254

12691255
fn peek_non_trivia(&mut self) -> Option<(TokenKind, &str)> {
1270-
while let Some(&token @ (kind, _)) = self.tokens.peek_next() {
1256+
while let Some(token @ (kind, _)) = self.tokens.peek_next() {
12711257
if let TokenKind::Whitespace
12721258
| TokenKind::LineComment { doc_style: None }
12731259
| TokenKind::BlockComment { doc_style: None, .. } = kind
@@ -1282,6 +1268,11 @@ impl<'src> Classifier<'src> {
12821268
}
12831269
}
12841270

1271+
fn is_keyword(symbol: Symbol) -> bool {
1272+
// FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument.
1273+
symbol.is_reserved(|| Edition::Edition2024)
1274+
}
1275+
12851276
fn generate_link_to_def(
12861277
out: &mut impl Write,
12871278
text_s: &str,

0 commit comments

Comments
 (0)