1 //! Defines token tags we use for syntax highlighting.
2 //! A tag is not unlike a CSS class.
6 use ide_db::SymbolKind;
8 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
14 #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
15 pub struct HlMods(u32);
17 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
36 // For things which don't have a specific highlight.
40 // Don't forget to adjust the feature description in crates/ide/src/syntax_highlighting.rs.
41 // And make sure to use the lsp strings used when converting to the protocol in crates\rust-analyzer\src\semantic_tokens.rs, not the names of the variants here.
42 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
45 /// Used for items in traits and impls.
47 /// Used to differentiate individual elements within attributes.
49 /// Callable item or value.
51 /// Value that is being consumed in a function call
53 /// Used with keywords like `if` and `break`.
55 /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
58 /// Doc-strings like this one.
60 /// Highlighting injection like rust code in doc strings or ra_fixture.
62 /// Used for intra doc links in doc injection.
66 /// Used for associated functions.
68 /// Used for items in traits and trait impls.
70 /// Used with keywords like `async` and `await`.
72 /// Used for items from other crates.
74 /// Used for public items.
77 /// Used for unsafe functions, unsafe traits, mutable statics, union accesses and unsafe operations.
81 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
103 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
104 pub enum HlOperator {
105 /// |, &, !, ^, |=, &=, ^=
107 /// +, -, *, /, +=, -=, *=, /=
111 /// >, <, ==, >=, <=, !=
118 fn as_str(self) -> &'static str {
120 HlTag::Symbol(symbol) => match symbol {
121 SymbolKind::Const => "constant",
122 SymbolKind::Static => "static",
123 SymbolKind::Enum => "enum",
124 SymbolKind::Variant => "enum_variant",
125 SymbolKind::Struct => "struct",
126 SymbolKind::Union => "union",
127 SymbolKind::Field => "field",
128 SymbolKind::Module => "module",
129 SymbolKind::Trait => "trait",
130 SymbolKind::Function => "function",
131 SymbolKind::TypeAlias => "type_alias",
132 SymbolKind::TypeParam => "type_param",
133 SymbolKind::ConstParam => "const_param",
134 SymbolKind::LifetimeParam => "lifetime",
135 SymbolKind::Macro => "macro",
136 SymbolKind::Local => "variable",
137 SymbolKind::Label => "label",
138 SymbolKind::ValueParam => "value_param",
139 SymbolKind::SelfParam => "self_keyword",
140 SymbolKind::Impl => "self_type",
142 HlTag::Attribute => "attribute",
143 HlTag::BoolLiteral => "bool_literal",
144 HlTag::BuiltinType => "builtin_type",
145 HlTag::ByteLiteral => "byte_literal",
146 HlTag::CharLiteral => "char_literal",
147 HlTag::Comment => "comment",
148 HlTag::EscapeSequence => "escape_sequence",
149 HlTag::FormatSpecifier => "format_specifier",
150 HlTag::Keyword => "keyword",
151 HlTag::Punctuation(punct) => match punct {
152 HlPunct::Bracket => "bracket",
153 HlPunct::Brace => "brace",
154 HlPunct::Parenthesis => "parenthesis",
155 HlPunct::Angle => "angle",
156 HlPunct::Comma => "comma",
157 HlPunct::Dot => "dot",
158 HlPunct::Colon => "colon",
159 HlPunct::Semi => "semicolon",
160 HlPunct::Other => "punctuation",
162 HlTag::NumericLiteral => "numeric_literal",
163 HlTag::Operator(op) => match op {
164 HlOperator::Bitwise => "bitwise",
165 HlOperator::Arithmetic => "arithmetic",
166 HlOperator::Logical => "logical",
167 HlOperator::Comparison => "comparison",
168 HlOperator::Other => "operator",
170 HlTag::StringLiteral => "string_literal",
171 HlTag::UnresolvedReference => "unresolved_reference",
172 HlTag::None => "none",
177 impl fmt::Display for HlTag {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 fmt::Display::fmt(self.as_str(), f)
184 const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
191 HlMod::Documentation,
203 fn as_str(self) -> &'static str {
205 HlMod::Associated => "associated",
206 HlMod::Attribute => "attribute",
207 HlMod::Callable => "callable",
208 HlMod::Consuming => "consuming",
209 HlMod::ControlFlow => "control",
210 HlMod::Definition => "declaration",
211 HlMod::Documentation => "documentation",
212 HlMod::Injected => "injected",
213 HlMod::IntraDocLink => "intra_doc_link",
214 HlMod::Mutable => "mutable",
215 HlMod::Static => "static",
216 HlMod::Trait => "trait",
217 HlMod::Async => "async",
218 HlMod::Library => "library",
219 HlMod::Public => "public",
220 HlMod::Unsafe => "unsafe",
224 fn mask(self) -> u32 {
229 impl fmt::Display for HlMod {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 fmt::Display::fmt(self.as_str(), f)
235 impl fmt::Display for Highlight {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 write!(f, "{}", self.tag)?;
238 for modifier in self.mods.iter() {
239 write!(f, ".{}", modifier)?
245 impl From<HlTag> for Highlight {
246 fn from(tag: HlTag) -> Highlight {
251 impl From<HlOperator> for Highlight {
252 fn from(op: HlOperator) -> Highlight {
253 Highlight::new(HlTag::Operator(op))
257 impl From<HlPunct> for Highlight {
258 fn from(punct: HlPunct) -> Highlight {
259 Highlight::new(HlTag::Punctuation(punct))
263 impl From<SymbolKind> for Highlight {
264 fn from(sym: SymbolKind) -> Highlight {
265 Highlight::new(HlTag::Symbol(sym))
270 pub(crate) fn new(tag: HlTag) -> Highlight {
271 Highlight { tag, mods: HlMods::default() }
273 pub fn is_empty(&self) -> bool {
274 self.tag == HlTag::None && self.mods == HlMods::default()
278 impl ops::BitOr<HlMod> for HlTag {
279 type Output = Highlight;
281 fn bitor(self, rhs: HlMod) -> Highlight {
282 Highlight::new(self) | rhs
286 impl ops::BitOrAssign<HlMod> for HlMods {
287 fn bitor_assign(&mut self, rhs: HlMod) {
288 self.0 |= rhs.mask();
292 impl ops::BitOrAssign<HlMod> for Highlight {
293 fn bitor_assign(&mut self, rhs: HlMod) {
298 impl ops::BitOr<HlMod> for Highlight {
299 type Output = Highlight;
301 fn bitor(mut self, rhs: HlMod) -> Highlight {
308 pub fn contains(self, m: HlMod) -> bool {
309 self.0 & m.mask() == m.mask()
312 pub fn iter(self) -> impl Iterator<Item = HlMod> {
313 HlMod::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask())