aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs176
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs18
2 files changed, 92 insertions, 102 deletions
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 62213dc47..8731699dc 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -1,6 +1,6 @@
1//! Computes color for a single element. 1//! Computes color for a single element.
2 2
3use hir::{AsAssocItem, AssocItemContainer, Semantics, VariantDef}; 3use hir::{AsAssocItem, Semantics};
4use ide_db::{ 4use ide_db::{
5 defs::{Definition, NameClass, NameRefClass}, 5 defs::{Definition, NameClass, NameRefClass},
6 RootDatabase, SymbolKind, 6 RootDatabase, SymbolKind,
@@ -45,28 +45,26 @@ pub(super) fn element(
45 }; 45 };
46 46
47 match name_kind { 47 match name_kind {
48 Some(NameClass::ExternCrate(_)) => HlTag::Symbol(SymbolKind::Module).into(), 48 Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(),
49 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, 49 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition,
50 Some(NameClass::ConstReference(def)) => highlight_def(db, def), 50 Some(NameClass::ConstReference(def)) => highlight_def(db, def),
51 Some(NameClass::PatFieldShorthand { field_ref, .. }) => { 51 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
52 let mut h = HlTag::Symbol(SymbolKind::Field).into(); 52 let mut h = HlTag::Symbol(SymbolKind::Field).into();
53 if let Definition::Field(field) = field_ref { 53 if let Definition::Field(field) = field_ref {
54 if let VariantDef::Union(_) = field.parent_def(db) { 54 if let hir::VariantDef::Union(_) = field.parent_def(db) {
55 h |= HlMod::Unsafe; 55 h |= HlMod::Unsafe;
56 } 56 }
57 } 57 }
58
59 h 58 h
60 } 59 }
61 None => highlight_name_by_syntax(name) | HlMod::Definition, 60 None => highlight_name_by_syntax(name) | HlMod::Definition,
62 } 61 }
63 } 62 }
64
65 // Highlight references like the definitions they resolve to 63 // Highlight references like the definitions they resolve to
66 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { 64 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => {
67 // even though we track whether we are in an attribute or not we still need this special case 65 // even though we track whether we are in an attribute or not we still need this special case
68 // as otherwise we would emit unresolved references for name refs inside attributes 66 // as otherwise we would emit unresolved references for name refs inside attributes
69 Highlight::from(HlTag::Symbol(SymbolKind::Function)) 67 SymbolKind::Function.into()
70 } 68 }
71 NAME_REF => { 69 NAME_REF => {
72 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 70 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
@@ -74,7 +72,7 @@ pub(super) fn element(
74 let is_self = name_ref.self_token().is_some(); 72 let is_self = name_ref.self_token().is_some();
75 let h = match NameRefClass::classify(sema, &name_ref) { 73 let h = match NameRefClass::classify(sema, &name_ref) {
76 Some(name_kind) => match name_kind { 74 Some(name_kind) => match name_kind {
77 NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), 75 NameRefClass::ExternCrate(_) => SymbolKind::Module.into(),
78 NameRefClass::Definition(def) => { 76 NameRefClass::Definition(def) => {
79 if let Definition::Local(local) = &def { 77 if let Definition::Local(local) = &def {
80 if let Some(name) = local.name(db) { 78 if let Some(name) = local.name(db) {
@@ -95,7 +93,7 @@ pub(super) fn element(
95 if let Some(parent) = name_ref.syntax().parent() { 93 if let Some(parent) = name_ref.syntax().parent() {
96 if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { 94 if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
97 if let Definition::Field(field) = def { 95 if let Definition::Field(field) = def {
98 if let VariantDef::Union(_) = field.parent_def(db) { 96 if let hir::VariantDef::Union(_) = field.parent_def(db) {
99 h |= HlMod::Unsafe; 97 h |= HlMod::Unsafe;
100 } 98 }
101 } 99 }
@@ -104,9 +102,7 @@ pub(super) fn element(
104 102
105 h 103 h
106 } 104 }
107 NameRefClass::FieldShorthand { .. } => { 105 NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
108 HlTag::Symbol(SymbolKind::Field).into()
109 }
110 }, 106 },
111 None if syntactic_name_ref_highlighting => { 107 None if syntactic_name_ref_highlighting => {
112 highlight_name_ref_by_syntax(name_ref, sema) 108 highlight_name_ref_by_syntax(name_ref, sema)
@@ -114,7 +110,7 @@ pub(super) fn element(
114 None => HlTag::UnresolvedReference.into(), 110 None => HlTag::UnresolvedReference.into(),
115 }; 111 };
116 if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self { 112 if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self {
117 HlTag::Symbol(SymbolKind::SelfParam).into() 113 SymbolKind::SelfParam.into()
118 } else { 114 } else {
119 h 115 h
120 } 116 }
@@ -135,7 +131,7 @@ pub(super) fn element(
135 INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), 131 INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(),
136 BYTE => HlTag::ByteLiteral.into(), 132 BYTE => HlTag::ByteLiteral.into(),
137 CHAR => HlTag::CharLiteral.into(), 133 CHAR => HlTag::CharLiteral.into(),
138 QUESTION => Highlight::new(HlTag::Operator(HlOperator::Other)) | HlMod::ControlFlow, 134 QUESTION => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow,
139 LIFETIME => { 135 LIFETIME => {
140 let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); 136 let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap();
141 137
@@ -143,44 +139,31 @@ pub(super) fn element(
143 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, 139 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition,
144 None => match NameRefClass::classify_lifetime(sema, &lifetime) { 140 None => match NameRefClass::classify_lifetime(sema, &lifetime) {
145 Some(NameRefClass::Definition(def)) => highlight_def(db, def), 141 Some(NameRefClass::Definition(def)) => highlight_def(db, def),
146 _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)), 142 _ => SymbolKind::LifetimeParam.into(),
147 }, 143 },
148 _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) | HlMod::Definition, 144 _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition,
149 } 145 }
150 } 146 }
151 p if p.is_punct() => match p { 147 p if p.is_punct() => match p {
152 T![&] if element.parent().and_then(ast::BinExpr::cast).is_some() => { 148 T![&] if parent_matches::<ast::BinExpr>(&element) => HlOperator::Bitwise.into(),
153 HlTag::Operator(HlOperator::Bitwise).into()
154 }
155 T![&] => { 149 T![&] => {
156 let h = HlTag::Operator(HlOperator::Other).into(); 150 let h = HlTag::Operator(HlOperator::Other).into();
157 let is_unsafe = element 151 let is_unsafe = element
158 .parent() 152 .parent()
159 .and_then(ast::RefExpr::cast) 153 .and_then(ast::RefExpr::cast)
160 .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr)) 154 .map_or(false, |ref_expr| sema.is_unsafe_ref_expr(&ref_expr));
161 .unwrap_or(false);
162 if is_unsafe { 155 if is_unsafe {
163 h | HlMod::Unsafe 156 h | HlMod::Unsafe
164 } else { 157 } else {
165 h 158 h
166 } 159 }
167 } 160 }
168 T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => { 161 T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlOperator::Other.into(),
169 HlTag::Operator(HlOperator::Other).into() 162 T![!] if parent_matches::<ast::MacroCall>(&element) => SymbolKind::Macro.into(),
170 } 163 T![!] if parent_matches::<ast::NeverType>(&element) => HlTag::BuiltinType.into(),
171 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 164 T![!] if parent_matches::<ast::PrefixExpr>(&element) => HlOperator::Logical.into(),
172 HlTag::Symbol(SymbolKind::Macro).into() 165 T![*] if parent_matches::<ast::PtrType>(&element) => HlTag::Keyword.into(),
173 } 166 T![*] if parent_matches::<ast::PrefixExpr>(&element) => {
174 T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => {
175 HlTag::BuiltinType.into()
176 }
177 T![!] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
178 HlTag::Operator(HlOperator::Logical).into()
179 }
180 T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => {
181 HlTag::Keyword.into()
182 }
183 T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
184 let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; 167 let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?;
185 168
186 let expr = prefix_expr.expr()?; 169 let expr = prefix_expr.expr()?;
@@ -188,12 +171,12 @@ pub(super) fn element(
188 if ty.is_raw_ptr() { 171 if ty.is_raw_ptr() {
189 HlTag::Operator(HlOperator::Other) | HlMod::Unsafe 172 HlTag::Operator(HlOperator::Other) | HlMod::Unsafe
190 } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { 173 } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() {
191 HlTag::Operator(HlOperator::Other).into() 174 HlOperator::Other.into()
192 } else { 175 } else {
193 HlTag::Punctuation(HlPunct::Other).into() 176 HlPunct::Other.into()
194 } 177 }
195 } 178 }
196 T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { 179 T![-] if parent_matches::<ast::PrefixExpr>(&element) => {
197 let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; 180 let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?;
198 181
199 let expr = prefix_expr.expr()?; 182 let expr = prefix_expr.expr()?;
@@ -203,41 +186,31 @@ pub(super) fn element(
203 } 186 }
204 .into() 187 .into()
205 } 188 }
206 _ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { 189 _ if parent_matches::<ast::PrefixExpr>(&element) => HlOperator::Other.into(),
207 HlTag::Operator(HlOperator::Other).into()
208 }
209 T![+] | T![-] | T![*] | T![/] | T![+=] | T![-=] | T![*=] | T![/=] 190 T![+] | T![-] | T![*] | T![/] | T![+=] | T![-=] | T![*=] | T![/=]
210 if element.parent().and_then(ast::BinExpr::cast).is_some() => 191 if parent_matches::<ast::BinExpr>(&element) =>
211 { 192 {
212 HlTag::Operator(HlOperator::Arithmetic).into() 193 HlOperator::Arithmetic.into()
213 } 194 }
214 T![|] | T![&] | T![!] | T![^] | T![|=] | T![&=] | T![^=] 195 T![|] | T![&] | T![!] | T![^] | T![|=] | T![&=] | T![^=]
215 if element.parent().and_then(ast::BinExpr::cast).is_some() => 196 if parent_matches::<ast::BinExpr>(&element) =>
216 { 197 {
217 HlTag::Operator(HlOperator::Bitwise).into() 198 HlOperator::Bitwise.into()
218 } 199 }
219 T![&&] | T![||] if element.parent().and_then(ast::BinExpr::cast).is_some() => { 200 T![&&] | T![||] if parent_matches::<ast::BinExpr>(&element) => {
220 HlTag::Operator(HlOperator::Logical).into() 201 HlOperator::Logical.into()
221 } 202 }
222 T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=] 203 T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=]
223 if element.parent().and_then(ast::BinExpr::cast).is_some() => 204 if parent_matches::<ast::BinExpr>(&element) =>
224 { 205 {
225 HlTag::Operator(HlOperator::Comparison).into() 206 HlOperator::Comparison.into()
226 }
227 _ if element.parent().and_then(ast::BinExpr::cast).is_some() => {
228 HlTag::Operator(HlOperator::Other).into()
229 } 207 }
230 _ if element.parent().and_then(ast::RangeExpr::cast).is_some() => { 208 _ if parent_matches::<ast::BinExpr>(&element) => HlOperator::Other.into(),
231 HlTag::Operator(HlOperator::Other).into() 209 _ if parent_matches::<ast::RangeExpr>(&element) => HlOperator::Other.into(),
232 } 210 _ if parent_matches::<ast::RangePat>(&element) => HlOperator::Other.into(),
233 _ if element.parent().and_then(ast::RangePat::cast).is_some() => { 211 _ if parent_matches::<ast::RestPat>(&element) => HlOperator::Other.into(),
234 HlTag::Operator(HlOperator::Other).into() 212 _ if parent_matches::<ast::Attr>(&element) => HlTag::Attribute.into(),
235 } 213 kind => match kind {
236 _ if element.parent().and_then(ast::RestPat::cast).is_some() => {
237 HlTag::Operator(HlOperator::Other).into()
238 }
239 _ if element.parent().and_then(ast::Attr::cast).is_some() => HlTag::Attribute.into(),
240 kind => HlTag::Punctuation(match kind {
241 T!['['] | T![']'] => HlPunct::Bracket, 214 T!['['] | T![']'] => HlPunct::Bracket,
242 T!['{'] | T!['}'] => HlPunct::Brace, 215 T!['{'] | T!['}'] => HlPunct::Brace,
243 T!['('] | T![')'] => HlPunct::Parenthesis, 216 T!['('] | T![')'] => HlPunct::Parenthesis,
@@ -247,7 +220,7 @@ pub(super) fn element(
247 T![;] => HlPunct::Semi, 220 T![;] => HlPunct::Semi,
248 T![.] => HlPunct::Dot, 221 T![.] => HlPunct::Dot,
249 _ => HlPunct::Other, 222 _ => HlPunct::Other,
250 }) 223 }
251 .into(), 224 .into(),
252 }, 225 },
253 226
@@ -303,7 +276,6 @@ pub(super) fn element(
303 hash((name, shadow_count)) 276 hash((name, shadow_count))
304 } 277 }
305} 278}
306
307fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { 279fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
308 match def { 280 match def {
309 Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), 281 Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro),
@@ -319,12 +291,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
319 } 291 }
320 292
321 match item.container(db) { 293 match item.container(db) {
322 AssocItemContainer::Impl(i) => { 294 hir::AssocItemContainer::Impl(i) => {
323 if i.trait_(db).is_some() { 295 if i.trait_(db).is_some() {
324 h |= HlMod::Trait; 296 h |= HlMod::Trait;
325 } 297 }
326 } 298 }
327 AssocItemContainer::Trait(_t) => { 299 hir::AssocItemContainer::Trait(_t) => {
328 h |= HlMod::Trait; 300 h |= HlMod::Trait;
329 } 301 }
330 } 302 }
@@ -344,12 +316,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
344 if let Some(item) = konst.as_assoc_item(db) { 316 if let Some(item) = konst.as_assoc_item(db) {
345 h |= HlMod::Associated; 317 h |= HlMod::Associated;
346 match item.container(db) { 318 match item.container(db) {
347 AssocItemContainer::Impl(i) => { 319 hir::AssocItemContainer::Impl(i) => {
348 if i.trait_(db).is_some() { 320 if i.trait_(db).is_some() {
349 h |= HlMod::Trait; 321 h |= HlMod::Trait;
350 } 322 }
351 } 323 }
352 AssocItemContainer::Trait(_t) => { 324 hir::AssocItemContainer::Trait(_t) => {
353 h |= HlMod::Trait; 325 h |= HlMod::Trait;
354 } 326 }
355 } 327 }
@@ -363,12 +335,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
363 if let Some(item) = type_.as_assoc_item(db) { 335 if let Some(item) = type_.as_assoc_item(db) {
364 h |= HlMod::Associated; 336 h |= HlMod::Associated;
365 match item.container(db) { 337 match item.container(db) {
366 AssocItemContainer::Impl(i) => { 338 hir::AssocItemContainer::Impl(i) => {
367 if i.trait_(db).is_some() { 339 if i.trait_(db).is_some() {
368 h |= HlMod::Trait; 340 h |= HlMod::Trait;
369 } 341 }
370 } 342 }
371 AssocItemContainer::Trait(_t) => { 343 hir::AssocItemContainer::Trait(_t) => {
372 h |= HlMod::Trait; 344 h |= HlMod::Trait;
373 } 345 }
374 } 346 }
@@ -427,7 +399,7 @@ fn highlight_method_call(
427 method_call: &ast::MethodCallExpr, 399 method_call: &ast::MethodCallExpr,
428) -> Option<Highlight> { 400) -> Option<Highlight> {
429 let func = sema.resolve_method_call(&method_call)?; 401 let func = sema.resolve_method_call(&method_call)?;
430 let mut h = HlTag::Symbol(SymbolKind::Function).into(); 402 let mut h = SymbolKind::Function.into();
431 h |= HlMod::Associated; 403 h |= HlMod::Associated;
432 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { 404 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) {
433 h |= HlMod::Unsafe; 405 h |= HlMod::Unsafe;
@@ -463,20 +435,20 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
463 }; 435 };
464 436
465 let tag = match parent.kind() { 437 let tag = match parent.kind() {
466 STRUCT => HlTag::Symbol(SymbolKind::Struct), 438 STRUCT => SymbolKind::Struct,
467 ENUM => HlTag::Symbol(SymbolKind::Enum), 439 ENUM => SymbolKind::Enum,
468 VARIANT => HlTag::Symbol(SymbolKind::Variant), 440 VARIANT => SymbolKind::Variant,
469 UNION => HlTag::Symbol(SymbolKind::Union), 441 UNION => SymbolKind::Union,
470 TRAIT => HlTag::Symbol(SymbolKind::Trait), 442 TRAIT => SymbolKind::Trait,
471 TYPE_ALIAS => HlTag::Symbol(SymbolKind::TypeAlias), 443 TYPE_ALIAS => SymbolKind::TypeAlias,
472 TYPE_PARAM => HlTag::Symbol(SymbolKind::TypeParam), 444 TYPE_PARAM => SymbolKind::TypeParam,
473 RECORD_FIELD => HlTag::Symbol(SymbolKind::Field), 445 RECORD_FIELD => SymbolKind::Field,
474 MODULE => HlTag::Symbol(SymbolKind::Module), 446 MODULE => SymbolKind::Module,
475 FN => HlTag::Symbol(SymbolKind::Function), 447 FN => SymbolKind::Function,
476 CONST => HlTag::Symbol(SymbolKind::Const), 448 CONST => SymbolKind::Const,
477 STATIC => HlTag::Symbol(SymbolKind::Static), 449 STATIC => SymbolKind::Static,
478 IDENT_PAT => HlTag::Symbol(SymbolKind::Local), 450 IDENT_PAT => SymbolKind::Local,
479 _ => default, 451 _ => return default.into(),
480 }; 452 };
481 453
482 tag.into() 454 tag.into()
@@ -494,20 +466,15 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
494 METHOD_CALL_EXPR => { 466 METHOD_CALL_EXPR => {
495 return ast::MethodCallExpr::cast(parent) 467 return ast::MethodCallExpr::cast(parent)
496 .and_then(|it| highlight_method_call(sema, &it)) 468 .and_then(|it| highlight_method_call(sema, &it))
497 .unwrap_or_else(|| HlTag::Symbol(SymbolKind::Function).into()); 469 .unwrap_or_else(|| SymbolKind::Function.into());
498 } 470 }
499 FIELD_EXPR => { 471 FIELD_EXPR => {
500 let h = HlTag::Symbol(SymbolKind::Field); 472 let h = HlTag::Symbol(SymbolKind::Field);
501 let is_union = ast::FieldExpr::cast(parent) 473 let is_union = ast::FieldExpr::cast(parent)
502 .and_then(|field_expr| { 474 .and_then(|field_expr| sema.resolve_field(&field_expr))
503 let field = sema.resolve_field(&field_expr)?; 475 .map_or(false, |field| {
504 Some(if let VariantDef::Union(_) = field.parent_def(sema.db) { 476 matches!(field.parent_def(sema.db), hir::VariantDef::Union(_))
505 true 477 });
506 } else {
507 false
508 })
509 })
510 .unwrap_or(false);
511 if is_union { 478 if is_union {
512 h | HlMod::Unsafe 479 h | HlMod::Unsafe
513 } else { 480 } else {
@@ -524,9 +491,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
524 _ => { 491 _ => {
525 // within path, decide whether it is module or adt by checking for uppercase name 492 // within path, decide whether it is module or adt by checking for uppercase name
526 return if name.text().chars().next().unwrap_or_default().is_uppercase() { 493 return if name.text().chars().next().unwrap_or_default().is_uppercase() {
527 HlTag::Symbol(SymbolKind::Struct) 494 SymbolKind::Struct
528 } else { 495 } else {
529 HlTag::Symbol(SymbolKind::Module) 496 SymbolKind::Module
530 } 497 }
531 .into(); 498 .into();
532 } 499 }
@@ -537,11 +504,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
537 }; 504 };
538 505
539 match parent.kind() { 506 match parent.kind() {
540 CALL_EXPR => HlTag::Symbol(SymbolKind::Function).into(), 507 CALL_EXPR => SymbolKind::Function.into(),
541 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { 508 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() {
542 HlTag::Symbol(SymbolKind::Struct) 509 SymbolKind::Struct
543 } else { 510 } else {
544 HlTag::Symbol(SymbolKind::Const) 511 SymbolKind::Const
545 } 512 }
546 .into(), 513 .into(),
547 } 514 }
@@ -576,6 +543,11 @@ fn parents_match(mut node: NodeOrToken<SyntaxNode, SyntaxToken>, mut kinds: &[Sy
576 kinds.len() == 0 543 kinds.len() == 0
577} 544}
578 545
546#[inline]
547fn parent_matches<N: AstNode>(element: &SyntaxElement) -> bool {
548 element.parent().map_or(false, |it| N::can_cast(it.kind()))
549}
550
579fn is_child_of_impl(element: &SyntaxElement) -> bool { 551fn is_child_of_impl(element: &SyntaxElement) -> bool {
580 match element.parent() { 552 match element.parent() {
581 Some(e) => e.kind() == IMPL, 553 Some(e) => e.kind() == IMPL,
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 3bee0ae46..a304b3250 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -234,6 +234,24 @@ impl From<HlTag> for Highlight {
234 } 234 }
235} 235}
236 236
237impl From<HlOperator> for Highlight {
238 fn from(op: HlOperator) -> Highlight {
239 Highlight::new(HlTag::Operator(op))
240 }
241}
242
243impl From<HlPunct> for Highlight {
244 fn from(punct: HlPunct) -> Highlight {
245 Highlight::new(HlTag::Punctuation(punct))
246 }
247}
248
249impl From<SymbolKind> for Highlight {
250 fn from(sym: SymbolKind) -> Highlight {
251 Highlight::new(HlTag::Symbol(sym))
252 }
253}
254
237impl Highlight { 255impl Highlight {
238 pub(crate) fn new(tag: HlTag) -> Highlight { 256 pub(crate) fn new(tag: HlTag) -> Highlight {
239 Highlight { tag, mods: HlMods::default() } 257 Highlight { tag, mods: HlMods::default() }