diff options
Diffstat (limited to 'crates/ide/src/syntax_highlighting/highlight.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting/highlight.rs | 107 |
1 files changed, 74 insertions, 33 deletions
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 058e37ff0..9503c936d 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -19,6 +19,7 @@ use crate::{ | |||
19 | 19 | ||
20 | pub(super) fn element( | 20 | pub(super) fn element( |
21 | sema: &Semantics<RootDatabase>, | 21 | sema: &Semantics<RootDatabase>, |
22 | krate: Option<hir::Crate>, | ||
22 | bindings_shadow_count: &mut FxHashMap<hir::Name, u32>, | 23 | bindings_shadow_count: &mut FxHashMap<hir::Name, u32>, |
23 | syntactic_name_ref_highlighting: bool, | 24 | syntactic_name_ref_highlighting: bool, |
24 | element: SyntaxElement, | 25 | element: SyntaxElement, |
@@ -46,8 +47,10 @@ pub(super) fn element( | |||
46 | 47 | ||
47 | match name_kind { | 48 | match name_kind { |
48 | Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), | 49 | Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), |
49 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | 50 | Some(NameClass::Definition(def)) => { |
50 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), | 51 | highlight_def(db, krate, def) | HlMod::Definition |
52 | } | ||
53 | Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def), | ||
51 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { | 54 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { |
52 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); | 55 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); |
53 | if let Definition::Field(field) = field_ref { | 56 | if let Definition::Field(field) = field_ref { |
@@ -68,7 +71,7 @@ pub(super) fn element( | |||
68 | } | 71 | } |
69 | NAME_REF => { | 72 | NAME_REF => { |
70 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 73 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
71 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | 74 | highlight_func_by_name_ref(sema, krate, &name_ref).unwrap_or_else(|| { |
72 | let is_self = name_ref.self_token().is_some(); | 75 | let is_self = name_ref.self_token().is_some(); |
73 | let h = match NameRefClass::classify(sema, &name_ref) { | 76 | let h = match NameRefClass::classify(sema, &name_ref) { |
74 | Some(name_kind) => match name_kind { | 77 | Some(name_kind) => match name_kind { |
@@ -82,7 +85,7 @@ pub(super) fn element( | |||
82 | } | 85 | } |
83 | }; | 86 | }; |
84 | 87 | ||
85 | let mut h = highlight_def(db, def); | 88 | let mut h = highlight_def(db, krate, def); |
86 | 89 | ||
87 | if let Definition::Local(local) = &def { | 90 | if let Definition::Local(local) = &def { |
88 | if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { | 91 | if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { |
@@ -105,7 +108,7 @@ pub(super) fn element( | |||
105 | NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), | 108 | NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), |
106 | }, | 109 | }, |
107 | None if syntactic_name_ref_highlighting => { | 110 | None if syntactic_name_ref_highlighting => { |
108 | highlight_name_ref_by_syntax(name_ref, sema) | 111 | highlight_name_ref_by_syntax(name_ref, sema, krate) |
109 | } | 112 | } |
110 | None => HlTag::UnresolvedReference.into(), | 113 | None => HlTag::UnresolvedReference.into(), |
111 | }; | 114 | }; |
@@ -136,9 +139,11 @@ pub(super) fn element( | |||
136 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); | 139 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); |
137 | 140 | ||
138 | match NameClass::classify_lifetime(sema, &lifetime) { | 141 | match NameClass::classify_lifetime(sema, &lifetime) { |
139 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | 142 | Some(NameClass::Definition(def)) => { |
143 | highlight_def(db, krate, def) | HlMod::Definition | ||
144 | } | ||
140 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { | 145 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { |
141 | Some(NameRefClass::Definition(def)) => highlight_def(db, def), | 146 | Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def), |
142 | _ => SymbolKind::LifetimeParam.into(), | 147 | _ => SymbolKind::LifetimeParam.into(), |
143 | }, | 148 | }, |
144 | _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, | 149 | _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, |
@@ -277,12 +282,12 @@ pub(super) fn element( | |||
277 | hash((name, shadow_count)) | 282 | hash((name, shadow_count)) |
278 | } | 283 | } |
279 | } | 284 | } |
280 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | 285 | fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition) -> Highlight { |
281 | match def { | 286 | let mut h = match def { |
282 | Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), | 287 | Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)), |
283 | Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), | 288 | Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)), |
284 | Definition::ModuleDef(def) => match def { | 289 | Definition::ModuleDef(def) => match def { |
285 | hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), | 290 | hir::ModuleDef::Module(_) => Highlight::new(HlTag::Symbol(SymbolKind::Module)), |
286 | hir::ModuleDef::Function(func) => { | 291 | hir::ModuleDef::Function(func) => { |
287 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); | 292 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); |
288 | if let Some(item) = func.as_assoc_item(db) { | 293 | if let Some(item) = func.as_assoc_item(db) { |
@@ -314,14 +319,22 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
314 | if func.is_async(db) { | 319 | if func.is_async(db) { |
315 | h |= HlMod::Async; | 320 | h |= HlMod::Async; |
316 | } | 321 | } |
317 | return h; | 322 | |
323 | h | ||
324 | } | ||
325 | hir::ModuleDef::Adt(adt) => { | ||
326 | let h = match adt { | ||
327 | hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct), | ||
328 | hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum), | ||
329 | hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union), | ||
330 | }; | ||
331 | |||
332 | Highlight::new(h) | ||
318 | } | 333 | } |
319 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), | 334 | hir::ModuleDef::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)), |
320 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), | ||
321 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), | ||
322 | hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), | ||
323 | hir::ModuleDef::Const(konst) => { | 335 | hir::ModuleDef::Const(konst) => { |
324 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); | 336 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); |
337 | |||
325 | if let Some(item) = konst.as_assoc_item(db) { | 338 | if let Some(item) = konst.as_assoc_item(db) { |
326 | h |= HlMod::Associated; | 339 | h |= HlMod::Associated; |
327 | match item.container(db) { | 340 | match item.container(db) { |
@@ -336,7 +349,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
336 | } | 349 | } |
337 | } | 350 | } |
338 | 351 | ||
339 | return h; | 352 | h |
340 | } | 353 | } |
341 | hir::ModuleDef::Trait(trait_) => { | 354 | hir::ModuleDef::Trait(trait_) => { |
342 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait)); | 355 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait)); |
@@ -344,10 +357,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
344 | if trait_.is_unsafe(db) { | 357 | if trait_.is_unsafe(db) { |
345 | h |= HlMod::Unsafe; | 358 | h |= HlMod::Unsafe; |
346 | } | 359 | } |
347 | return h; | 360 | |
361 | h | ||
348 | } | 362 | } |
349 | hir::ModuleDef::TypeAlias(type_) => { | 363 | hir::ModuleDef::TypeAlias(type_) => { |
350 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); | 364 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); |
365 | |||
351 | if let Some(item) = type_.as_assoc_item(db) { | 366 | if let Some(item) = type_.as_assoc_item(db) { |
352 | h |= HlMod::Associated; | 367 | h |= HlMod::Associated; |
353 | match item.container(db) { | 368 | match item.container(db) { |
@@ -361,23 +376,30 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
361 | } | 376 | } |
362 | } | 377 | } |
363 | } | 378 | } |
364 | return h; | 379 | |
380 | h | ||
365 | } | 381 | } |
366 | hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, | 382 | hir::ModuleDef::BuiltinType(_) => Highlight::new(HlTag::BuiltinType), |
367 | hir::ModuleDef::Static(s) => { | 383 | hir::ModuleDef::Static(s) => { |
368 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); | 384 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); |
385 | |||
369 | if s.is_mut(db) { | 386 | if s.is_mut(db) { |
370 | h |= HlMod::Mutable; | 387 | h |= HlMod::Mutable; |
371 | h |= HlMod::Unsafe; | 388 | h |= HlMod::Unsafe; |
372 | } | 389 | } |
373 | return h; | 390 | |
391 | h | ||
374 | } | 392 | } |
375 | }, | 393 | }, |
376 | Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), | 394 | Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)), |
377 | Definition::GenericParam(it) => match it { | 395 | Definition::GenericParam(it) => match it { |
378 | hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), | 396 | hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)), |
379 | hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), | 397 | hir::GenericParam::ConstParam(_) => { |
380 | hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), | 398 | Highlight::new(HlTag::Symbol(SymbolKind::ConstParam)) |
399 | } | ||
400 | hir::GenericParam::LifetimeParam(_) => { | ||
401 | Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) | ||
402 | } | ||
381 | }, | 403 | }, |
382 | Definition::Local(local) => { | 404 | Definition::Local(local) => { |
383 | let tag = if local.is_self(db) { | 405 | let tag = if local.is_self(db) { |
@@ -395,28 +417,40 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
395 | if ty.as_callable(db).is_some() || ty.impls_fnonce(db) { | 417 | if ty.as_callable(db).is_some() || ty.impls_fnonce(db) { |
396 | h |= HlMod::Callable; | 418 | h |= HlMod::Callable; |
397 | } | 419 | } |
398 | return h; | 420 | h |
399 | } | 421 | } |
400 | Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), | 422 | Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)), |
423 | }; | ||
424 | |||
425 | let is_from_other_crate = def.module(db).map(hir::Module::krate) != krate; | ||
426 | let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_))); | ||
427 | |||
428 | if is_from_other_crate && !is_builtin_type { | ||
429 | h |= HlMod::Library; | ||
401 | } | 430 | } |
402 | .into() | 431 | |
432 | h | ||
403 | } | 433 | } |
404 | 434 | ||
405 | fn highlight_func_by_name_ref( | 435 | fn highlight_func_by_name_ref( |
406 | sema: &Semantics<RootDatabase>, | 436 | sema: &Semantics<RootDatabase>, |
437 | krate: Option<hir::Crate>, | ||
407 | name_ref: &ast::NameRef, | 438 | name_ref: &ast::NameRef, |
408 | ) -> Option<Highlight> { | 439 | ) -> Option<Highlight> { |
409 | let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; | 440 | let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; |
410 | highlight_method_call(sema, &mc) | 441 | highlight_method_call(sema, krate, &mc) |
411 | } | 442 | } |
412 | 443 | ||
413 | fn highlight_method_call( | 444 | fn highlight_method_call( |
414 | sema: &Semantics<RootDatabase>, | 445 | sema: &Semantics<RootDatabase>, |
446 | krate: Option<hir::Crate>, | ||
415 | method_call: &ast::MethodCallExpr, | 447 | method_call: &ast::MethodCallExpr, |
416 | ) -> Option<Highlight> { | 448 | ) -> Option<Highlight> { |
417 | let func = sema.resolve_method_call(&method_call)?; | 449 | let func = sema.resolve_method_call(&method_call)?; |
450 | |||
418 | let mut h = SymbolKind::Function.into(); | 451 | let mut h = SymbolKind::Function.into(); |
419 | h |= HlMod::Associated; | 452 | h |= HlMod::Associated; |
453 | |||
420 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | 454 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { |
421 | h |= HlMod::Unsafe; | 455 | h |= HlMod::Unsafe; |
422 | } | 456 | } |
@@ -424,7 +458,10 @@ fn highlight_method_call( | |||
424 | h |= HlMod::Async; | 458 | h |= HlMod::Async; |
425 | } | 459 | } |
426 | if func.as_assoc_item(sema.db).and_then(|it| it.containing_trait(sema.db)).is_some() { | 460 | if func.as_assoc_item(sema.db).and_then(|it| it.containing_trait(sema.db)).is_some() { |
427 | h |= HlMod::Trait | 461 | h |= HlMod::Trait; |
462 | } | ||
463 | if Some(func.module(sema.db).krate()) != krate { | ||
464 | h |= HlMod::Library; | ||
428 | } | 465 | } |
429 | 466 | ||
430 | if let Some(self_param) = func.self_param(sema.db) { | 467 | if let Some(self_param) = func.self_param(sema.db) { |
@@ -473,7 +510,11 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
473 | tag.into() | 510 | tag.into() |
474 | } | 511 | } |
475 | 512 | ||
476 | fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight { | 513 | fn highlight_name_ref_by_syntax( |
514 | name: ast::NameRef, | ||
515 | sema: &Semantics<RootDatabase>, | ||
516 | krate: Option<hir::Crate>, | ||
517 | ) -> Highlight { | ||
477 | let default = HlTag::UnresolvedReference; | 518 | let default = HlTag::UnresolvedReference; |
478 | 519 | ||
479 | let parent = match name.syntax().parent() { | 520 | let parent = match name.syntax().parent() { |
@@ -484,7 +525,7 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
484 | match parent.kind() { | 525 | match parent.kind() { |
485 | METHOD_CALL_EXPR => { | 526 | METHOD_CALL_EXPR => { |
486 | return ast::MethodCallExpr::cast(parent) | 527 | return ast::MethodCallExpr::cast(parent) |
487 | .and_then(|it| highlight_method_call(sema, &it)) | 528 | .and_then(|it| highlight_method_call(sema, krate, &it)) |
488 | .unwrap_or_else(|| SymbolKind::Function.into()); | 529 | .unwrap_or_else(|| SymbolKind::Function.into()); |
489 | } | 530 | } |
490 | FIELD_EXPR => { | 531 | FIELD_EXPR => { |