diff options
author | Igor Aleksanov <[email protected]> | 2020-08-14 05:34:07 +0100 |
---|---|---|
committer | Igor Aleksanov <[email protected]> | 2020-08-14 05:34:07 +0100 |
commit | c26c911ec1e6c2ad1dcb7d155a6a1d528839ad1a (patch) | |
tree | 7cff36c38234be0afb65273146d8247083a5cfeb /crates/ide/src/syntax_highlighting/tags.rs | |
parent | 3c018bf84de5c693b5ee1c6bec0fed3b201c2060 (diff) | |
parent | f1f73649a686dc6e6449afc35e0fa6fed00e225d (diff) |
Merge branch 'master' into add-disable-diagnostics
Diffstat (limited to 'crates/ide/src/syntax_highlighting/tags.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting/tags.rs | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs new file mode 100644 index 000000000..49ec94bdc --- /dev/null +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -0,0 +1,203 @@ | |||
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 | BoolLiteral, | ||
19 | BuiltinType, | ||
20 | ByteLiteral, | ||
21 | CharLiteral, | ||
22 | Comment, | ||
23 | Constant, | ||
24 | Enum, | ||
25 | EnumVariant, | ||
26 | EscapeSequence, | ||
27 | Field, | ||
28 | Function, | ||
29 | Generic, | ||
30 | Keyword, | ||
31 | Lifetime, | ||
32 | Macro, | ||
33 | Module, | ||
34 | NumericLiteral, | ||
35 | Punctuation, | ||
36 | SelfKeyword, | ||
37 | SelfType, | ||
38 | Static, | ||
39 | StringLiteral, | ||
40 | Struct, | ||
41 | Trait, | ||
42 | TypeAlias, | ||
43 | TypeParam, | ||
44 | Union, | ||
45 | ValueParam, | ||
46 | Local, | ||
47 | UnresolvedReference, | ||
48 | FormatSpecifier, | ||
49 | Operator, | ||
50 | } | ||
51 | |||
52 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
53 | #[repr(u8)] | ||
54 | pub enum HighlightModifier { | ||
55 | /// Used to differentiate individual elements within attributes. | ||
56 | Attribute = 0, | ||
57 | /// Used with keywords like `if` and `break`. | ||
58 | ControlFlow, | ||
59 | /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is | ||
60 | /// not. | ||
61 | Definition, | ||
62 | Documentation, | ||
63 | Injected, | ||
64 | Mutable, | ||
65 | Unsafe, | ||
66 | } | ||
67 | |||
68 | impl HighlightTag { | ||
69 | fn as_str(self) -> &'static str { | ||
70 | match self { | ||
71 | HighlightTag::Attribute => "attribute", | ||
72 | HighlightTag::BoolLiteral => "bool_literal", | ||
73 | HighlightTag::BuiltinType => "builtin_type", | ||
74 | HighlightTag::ByteLiteral => "byte_literal", | ||
75 | HighlightTag::CharLiteral => "char_literal", | ||
76 | HighlightTag::Comment => "comment", | ||
77 | HighlightTag::Constant => "constant", | ||
78 | HighlightTag::Enum => "enum", | ||
79 | HighlightTag::EnumVariant => "enum_variant", | ||
80 | HighlightTag::EscapeSequence => "escape_sequence", | ||
81 | HighlightTag::Field => "field", | ||
82 | HighlightTag::FormatSpecifier => "format_specifier", | ||
83 | HighlightTag::Function => "function", | ||
84 | HighlightTag::Generic => "generic", | ||
85 | HighlightTag::Keyword => "keyword", | ||
86 | HighlightTag::Lifetime => "lifetime", | ||
87 | HighlightTag::Punctuation => "punctuation", | ||
88 | HighlightTag::Macro => "macro", | ||
89 | HighlightTag::Module => "module", | ||
90 | HighlightTag::NumericLiteral => "numeric_literal", | ||
91 | HighlightTag::Operator => "operator", | ||
92 | HighlightTag::SelfKeyword => "self_keyword", | ||
93 | HighlightTag::SelfType => "self_type", | ||
94 | HighlightTag::Static => "static", | ||
95 | HighlightTag::StringLiteral => "string_literal", | ||
96 | HighlightTag::Struct => "struct", | ||
97 | HighlightTag::Trait => "trait", | ||
98 | HighlightTag::TypeAlias => "type_alias", | ||
99 | HighlightTag::TypeParam => "type_param", | ||
100 | HighlightTag::Union => "union", | ||
101 | HighlightTag::ValueParam => "value_param", | ||
102 | HighlightTag::Local => "variable", | ||
103 | HighlightTag::UnresolvedReference => "unresolved_reference", | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
108 | impl fmt::Display for HighlightTag { | ||
109 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
110 | fmt::Display::fmt(self.as_str(), f) | ||
111 | } | ||
112 | } | ||
113 | |||
114 | impl HighlightModifier { | ||
115 | const ALL: &'static [HighlightModifier] = &[ | ||
116 | HighlightModifier::Attribute, | ||
117 | HighlightModifier::ControlFlow, | ||
118 | HighlightModifier::Definition, | ||
119 | HighlightModifier::Documentation, | ||
120 | HighlightModifier::Injected, | ||
121 | HighlightModifier::Mutable, | ||
122 | HighlightModifier::Unsafe, | ||
123 | ]; | ||
124 | |||
125 | fn as_str(self) -> &'static str { | ||
126 | match self { | ||
127 | HighlightModifier::Attribute => "attribute", | ||
128 | HighlightModifier::ControlFlow => "control", | ||
129 | HighlightModifier::Definition => "declaration", | ||
130 | HighlightModifier::Documentation => "documentation", | ||
131 | HighlightModifier::Injected => "injected", | ||
132 | HighlightModifier::Mutable => "mutable", | ||
133 | HighlightModifier::Unsafe => "unsafe", | ||
134 | } | ||
135 | } | ||
136 | |||
137 | fn mask(self) -> u32 { | ||
138 | 1 << (self as u32) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl fmt::Display for HighlightModifier { | ||
143 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
144 | fmt::Display::fmt(self.as_str(), f) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl fmt::Display for Highlight { | ||
149 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
150 | write!(f, "{}", self.tag)?; | ||
151 | for modifier in self.modifiers.iter() { | ||
152 | write!(f, ".{}", modifier)? | ||
153 | } | ||
154 | Ok(()) | ||
155 | } | ||
156 | } | ||
157 | |||
158 | impl From<HighlightTag> for Highlight { | ||
159 | fn from(tag: HighlightTag) -> Highlight { | ||
160 | Highlight::new(tag) | ||
161 | } | ||
162 | } | ||
163 | |||
164 | impl Highlight { | ||
165 | pub(crate) fn new(tag: HighlightTag) -> Highlight { | ||
166 | Highlight { tag, modifiers: HighlightModifiers::default() } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | impl ops::BitOr<HighlightModifier> for HighlightTag { | ||
171 | type Output = Highlight; | ||
172 | |||
173 | fn bitor(self, rhs: HighlightModifier) -> Highlight { | ||
174 | Highlight::new(self) | rhs | ||
175 | } | ||
176 | } | ||
177 | |||
178 | impl ops::BitOrAssign<HighlightModifier> for HighlightModifiers { | ||
179 | fn bitor_assign(&mut self, rhs: HighlightModifier) { | ||
180 | self.0 |= rhs.mask(); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | impl ops::BitOrAssign<HighlightModifier> for Highlight { | ||
185 | fn bitor_assign(&mut self, rhs: HighlightModifier) { | ||
186 | self.modifiers |= rhs; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | impl ops::BitOr<HighlightModifier> for Highlight { | ||
191 | type Output = Highlight; | ||
192 | |||
193 | fn bitor(mut self, rhs: HighlightModifier) -> Highlight { | ||
194 | self |= rhs; | ||
195 | self | ||
196 | } | ||
197 | } | ||
198 | |||
199 | impl HighlightModifiers { | ||
200 | pub fn iter(self) -> impl Iterator<Item = HighlightModifier> { | ||
201 | HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask()) | ||
202 | } | ||
203 | } | ||