]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide/src/syntax_highlighting/tags.rs
lsp-types 0.74
[rust.git] / crates / ra_ide / src / syntax_highlighting / tags.rs
1 //! Defines token tags we use for syntax highlighting.
2 //! A tag is not unlike a CSS class.
3
4 use std::{fmt, ops};
5
6 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
7 pub struct Highlight {
8     pub tag: HighlightTag,
9     pub modifiers: HighlightModifiers,
10 }
11
12 #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
13 pub struct HighlightModifiers(u32);
14
15 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
16 pub enum HighlightTag {
17     Attribute,
18     BuiltinType,
19     ByteLiteral,
20     CharLiteral,
21     Comment,
22     Constant,
23     Enum,
24     EnumVariant,
25     Field,
26     Function,
27     Keyword,
28     Lifetime,
29     Macro,
30     Module,
31     NumericLiteral,
32     SelfType,
33     Static,
34     StringLiteral,
35     Struct,
36     Trait,
37     TypeAlias,
38     TypeParam,
39     Union,
40     Local,
41     UnresolvedReference,
42 }
43
44 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
45 #[repr(u8)]
46 pub enum HighlightModifier {
47     /// Used with keywords like `if` and `break`.
48     ControlFlow = 0,
49     /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
50     /// not.
51     Definition,
52     Mutable,
53     Unsafe,
54 }
55
56 impl HighlightTag {
57     fn as_str(self) -> &'static str {
58         match self {
59             HighlightTag::Attribute => "attribute",
60             HighlightTag::BuiltinType => "builtin_type",
61             HighlightTag::ByteLiteral => "byte_literal",
62             HighlightTag::CharLiteral => "char_literal",
63             HighlightTag::Comment => "comment",
64             HighlightTag::Constant => "constant",
65             HighlightTag::Enum => "enum",
66             HighlightTag::EnumVariant => "enum_variant",
67             HighlightTag::Field => "field",
68             HighlightTag::Function => "function",
69             HighlightTag::Keyword => "keyword",
70             HighlightTag::Lifetime => "lifetime",
71             HighlightTag::Macro => "macro",
72             HighlightTag::Module => "module",
73             HighlightTag::NumericLiteral => "numeric_literal",
74             HighlightTag::SelfType => "self_type",
75             HighlightTag::Static => "static",
76             HighlightTag::StringLiteral => "string_literal",
77             HighlightTag::Struct => "struct",
78             HighlightTag::Trait => "trait",
79             HighlightTag::TypeAlias => "type_alias",
80             HighlightTag::TypeParam => "type_param",
81             HighlightTag::Union => "union",
82             HighlightTag::Local => "variable",
83             HighlightTag::UnresolvedReference => "unresolved_reference",
84         }
85     }
86 }
87
88 impl fmt::Display for HighlightTag {
89     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90         fmt::Display::fmt(self.as_str(), f)
91     }
92 }
93
94 impl HighlightModifier {
95     const ALL: &'static [HighlightModifier] = &[
96         HighlightModifier::ControlFlow,
97         HighlightModifier::Definition,
98         HighlightModifier::Mutable,
99         HighlightModifier::Unsafe,
100     ];
101
102     fn as_str(self) -> &'static str {
103         match self {
104             HighlightModifier::ControlFlow => "control",
105             HighlightModifier::Definition => "declaration",
106             HighlightModifier::Mutable => "mutable",
107             HighlightModifier::Unsafe => "unsafe",
108         }
109     }
110
111     fn mask(self) -> u32 {
112         1 << (self as u32)
113     }
114 }
115
116 impl fmt::Display for HighlightModifier {
117     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118         fmt::Display::fmt(self.as_str(), f)
119     }
120 }
121
122 impl fmt::Display for Highlight {
123     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124         write!(f, "{}", self.tag)?;
125         for modifier in self.modifiers.iter() {
126             write!(f, ".{}", modifier)?
127         }
128         Ok(())
129     }
130 }
131
132 impl From<HighlightTag> for Highlight {
133     fn from(tag: HighlightTag) -> Highlight {
134         Highlight::new(tag)
135     }
136 }
137
138 impl Highlight {
139     pub(crate) fn new(tag: HighlightTag) -> Highlight {
140         Highlight { tag, modifiers: HighlightModifiers::default() }
141     }
142 }
143
144 impl ops::BitOr<HighlightModifier> for HighlightTag {
145     type Output = Highlight;
146
147     fn bitor(self, rhs: HighlightModifier) -> Highlight {
148         Highlight::new(self) | rhs
149     }
150 }
151
152 impl ops::BitOrAssign<HighlightModifier> for HighlightModifiers {
153     fn bitor_assign(&mut self, rhs: HighlightModifier) {
154         self.0 |= rhs.mask();
155     }
156 }
157
158 impl ops::BitOrAssign<HighlightModifier> for Highlight {
159     fn bitor_assign(&mut self, rhs: HighlightModifier) {
160         self.modifiers |= rhs;
161     }
162 }
163
164 impl ops::BitOr<HighlightModifier> for Highlight {
165     type Output = Highlight;
166
167     fn bitor(mut self, rhs: HighlightModifier) -> Highlight {
168         self |= rhs;
169         self
170     }
171 }
172
173 impl HighlightModifiers {
174     pub fn iter(self) -> impl Iterator<Item = HighlightModifier> {
175         HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask())
176     }
177 }