diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-08-19 12:27:02 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-08-19 12:27:02 +0100 |
commit | 529ca7e5e0573e15b23cd0067a691bf1ffebae84 (patch) | |
tree | 0cc09513805718a7c31cadb1776ff4eb865caaef /crates/ide/src/syntax_highlighting.rs | |
parent | c1cfd010096daa85f8acd6f1ea15d92097816e14 (diff) | |
parent | 3456e2eec7c1e18734f8fa41924a83b4c676dc00 (diff) |
Merge #5643
5643: Add new consuming modifier, apply consuming and mutable to methods r=matklad a=Nashenas88
This adds a new `consuming` semantic modifier for syntax highlighters.
This also emits `mutable` and `consuming` in two cases:
- When a method takes `&mut self`, then it now has `function.mutable` emitted.
- When a method takes `self`, and the type of `Self` is not `Copy`, then `function.consuming` is emitted.
CC @flodiebold
Co-authored-by: Paul Daniel Faria <[email protected]>
Diffstat (limited to 'crates/ide/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 117 |
1 files changed, 74 insertions, 43 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 5d7c7e8d0..9827c68af 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -4,7 +4,7 @@ mod injection; | |||
4 | #[cfg(test)] | 4 | #[cfg(test)] |
5 | mod tests; | 5 | mod tests; |
6 | 6 | ||
7 | use hir::{Name, Semantics, VariantDef}; | 7 | use hir::{Mutability, Name, SelfKind, Semantics, VariantDef}; |
8 | use ide_db::{ | 8 | use ide_db::{ |
9 | defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, | 9 | defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, |
10 | RootDatabase, | 10 | RootDatabase, |
@@ -519,27 +519,29 @@ fn highlight_element( | |||
519 | } | 519 | } |
520 | NAME_REF => { | 520 | NAME_REF => { |
521 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 521 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
522 | let possibly_unsafe = is_possibly_unsafe(&name_ref); | 522 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { |
523 | match classify_name_ref(sema, &name_ref) { | 523 | let possibly_unsafe = is_possibly_unsafe(&name_ref); |
524 | Some(name_kind) => match name_kind { | 524 | match classify_name_ref(sema, &name_ref) { |
525 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), | 525 | Some(name_kind) => match name_kind { |
526 | NameRefClass::Definition(def) => { | 526 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), |
527 | if let Definition::Local(local) = &def { | 527 | NameRefClass::Definition(def) => { |
528 | if let Some(name) = local.name(db) { | 528 | if let Definition::Local(local) = &def { |
529 | let shadow_count = | 529 | if let Some(name) = local.name(db) { |
530 | bindings_shadow_count.entry(name.clone()).or_default(); | 530 | let shadow_count = |
531 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | 531 | bindings_shadow_count.entry(name.clone()).or_default(); |
532 | } | 532 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) |
533 | }; | 533 | } |
534 | highlight_name(sema, db, def, Some(name_ref), possibly_unsafe) | 534 | }; |
535 | highlight_name(sema, db, def, Some(name_ref), possibly_unsafe) | ||
536 | } | ||
537 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | ||
538 | }, | ||
539 | None if syntactic_name_ref_highlighting => { | ||
540 | highlight_name_ref_by_syntax(name_ref, sema) | ||
535 | } | 541 | } |
536 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | 542 | None => HighlightTag::UnresolvedReference.into(), |
537 | }, | ||
538 | None if syntactic_name_ref_highlighting => { | ||
539 | highlight_name_ref_by_syntax(name_ref, sema) | ||
540 | } | 543 | } |
541 | None => HighlightTag::UnresolvedReference.into(), | 544 | }) |
542 | } | ||
543 | } | 545 | } |
544 | 546 | ||
545 | // Simple token-based highlighting | 547 | // Simple token-based highlighting |
@@ -700,6 +702,35 @@ fn is_child_of_impl(element: &SyntaxElement) -> bool { | |||
700 | } | 702 | } |
701 | } | 703 | } |
702 | 704 | ||
705 | fn highlight_func_by_name_ref( | ||
706 | sema: &Semantics<RootDatabase>, | ||
707 | name_ref: &ast::NameRef, | ||
708 | ) -> Option<Highlight> { | ||
709 | let parent = name_ref.syntax().parent()?; | ||
710 | let method_call = ast::MethodCallExpr::cast(parent)?; | ||
711 | highlight_method_call(sema, &method_call) | ||
712 | } | ||
713 | |||
714 | fn highlight_method_call( | ||
715 | sema: &Semantics<RootDatabase>, | ||
716 | method_call: &ast::MethodCallExpr, | ||
717 | ) -> Option<Highlight> { | ||
718 | let func = sema.resolve_method_call(&method_call)?; | ||
719 | let mut h = HighlightTag::Function.into(); | ||
720 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | ||
721 | h |= HighlightModifier::Unsafe; | ||
722 | } | ||
723 | |||
724 | sema.method_reciever_kind(&method_call) | ||
725 | .map(|self_kind| match self_kind { | ||
726 | SelfKind::Shared => h, | ||
727 | SelfKind::Mutable => h | HighlightModifier::Mutable, | ||
728 | SelfKind::Consuming => h | HighlightModifier::Consuming, | ||
729 | SelfKind::Copied => h, | ||
730 | }) | ||
731 | .or_else(|| Some(h)) | ||
732 | } | ||
733 | |||
703 | fn highlight_name( | 734 | fn highlight_name( |
704 | sema: &Semantics<RootDatabase>, | 735 | sema: &Semantics<RootDatabase>, |
705 | db: &RootDatabase, | 736 | db: &RootDatabase, |
@@ -722,20 +753,26 @@ fn highlight_name( | |||
722 | Definition::ModuleDef(def) => match def { | 753 | Definition::ModuleDef(def) => match def { |
723 | hir::ModuleDef::Module(_) => HighlightTag::Module, | 754 | hir::ModuleDef::Module(_) => HighlightTag::Module, |
724 | hir::ModuleDef::Function(func) => { | 755 | hir::ModuleDef::Function(func) => { |
725 | let mut h = HighlightTag::Function.into(); | 756 | return name_ref |
726 | if func.is_unsafe(db) { | 757 | .and_then(|name_ref| highlight_func_by_name_ref(sema, &name_ref)) |
727 | h |= HighlightModifier::Unsafe; | 758 | .unwrap_or_else(|| { |
728 | } else { | 759 | let mut h = HighlightTag::Function.into(); |
729 | let is_unsafe = name_ref | 760 | if func.is_unsafe(db) { |
730 | .and_then(|name_ref| name_ref.syntax().parent()) | 761 | h |= HighlightModifier::Unsafe; |
731 | .and_then(ast::MethodCallExpr::cast) | 762 | } |
732 | .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) | 763 | |
733 | .unwrap_or(false); | 764 | return if func.has_self_param(db) { |
734 | if is_unsafe { | 765 | match func.mutability_of_self_param(db) { |
735 | h |= HighlightModifier::Unsafe; | 766 | Some(mutability) => match mutability { |
736 | } | 767 | Mutability::Mut => h | HighlightModifier::Mutable, |
737 | } | 768 | Mutability::Shared => h, |
738 | return h; | 769 | }, |
770 | None => h, | ||
771 | } | ||
772 | } else { | ||
773 | h | ||
774 | }; | ||
775 | }); | ||
739 | } | 776 | } |
740 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, | 777 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, |
741 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, | 778 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, |
@@ -807,15 +844,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
807 | 844 | ||
808 | match parent.kind() { | 845 | match parent.kind() { |
809 | METHOD_CALL_EXPR => { | 846 | METHOD_CALL_EXPR => { |
810 | let mut h = Highlight::new(HighlightTag::Function); | 847 | return ast::MethodCallExpr::cast(parent) |
811 | let is_unsafe = ast::MethodCallExpr::cast(parent) | 848 | .and_then(|method_call| highlight_method_call(sema, &method_call)) |
812 | .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) | 849 | .unwrap_or_else(|| HighlightTag::Function.into()); |
813 | .unwrap_or(false); | ||
814 | if is_unsafe { | ||
815 | h |= HighlightModifier::Unsafe; | ||
816 | } | ||
817 | |||
818 | h | ||
819 | } | 850 | } |
820 | FIELD_EXPR => { | 851 | FIELD_EXPR => { |
821 | let h = HighlightTag::Field; | 852 | let h = HighlightTag::Field; |