aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/syntax_highlighting.rs139
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs30
-rw-r--r--crates/ide/test_data/highlighting.html34
3 files changed, 136 insertions, 67 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 15a78a614..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)]
5mod tests; 5mod tests;
6 6
7use hir::{Mutability, Name, Semantics, VariantDef}; 7use hir::{Mutability, Name, SelfKind, Semantics, VariantDef};
8use ide_db::{ 8use 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
705fn 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
714fn 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
703fn highlight_name( 734fn highlight_name(
704 sema: &Semantics<RootDatabase>, 735 sema: &Semantics<RootDatabase>,
705 db: &RootDatabase, 736 db: &RootDatabase,
@@ -722,30 +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 if func.has_self_param(db) { 769 },
739 match func.mutability_of_self_param(db) { 770 None => h,
740 Some(mutability) => match mutability { 771 }
741 Mutability::Mut => h | HighlightModifier::Mutable, 772 } else {
742 Mutability::Shared => h, 773 h
743 }, 774 };
744 None => h | HighlightModifier::Consuming, 775 });
745 }
746 } else {
747 h
748 };
749 } 776 }
750 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, 777 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct,
751 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, 778 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum,
@@ -817,27 +844,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
817 844
818 match parent.kind() { 845 match parent.kind() {
819 METHOD_CALL_EXPR => { 846 METHOD_CALL_EXPR => {
820 let mut h = Highlight::new(HighlightTag::Function); 847 return ast::MethodCallExpr::cast(parent)
821 ast::MethodCallExpr::cast(parent) 848 .and_then(|method_call| highlight_method_call(sema, &method_call))
822 .and_then(|method_call_expr| { 849 .unwrap_or_else(|| HighlightTag::Function.into());
823 if sema.is_unsafe_method_call(&method_call_expr) {
824 h |= HighlightModifier::Unsafe;
825 }
826
827 let func = sema.resolve_method_call(&method_call_expr)?;
828 if !func.has_self_param(sema.db) {
829 return Some(h);
830 }
831
832 Some(match func.mutability_of_self_param(sema.db) {
833 Some(mutability) => match mutability {
834 Mutability::Mut => h | HighlightModifier::Mutable,
835 Mutability::Shared => h,
836 },
837 None => h | HighlightModifier::Consuming,
838 })
839 })
840 .unwrap_or_else(|| h)
841 } 850 }
842 FIELD_EXPR => { 851 FIELD_EXPR => {
843 let h = HighlightTag::Field; 852 let h = HighlightTag::Field;
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 6cb955d29..ccb76f552 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -12,6 +12,12 @@ fn test_highlighting() {
12use inner::{self as inner_mod}; 12use inner::{self as inner_mod};
13mod inner {} 13mod inner {}
14 14
15// Needed for function consuming vs normal
16pub mod marker {
17 #[lang = "copy"]
18 pub trait Copy {}
19}
20
15#[derive(Clone, Debug)] 21#[derive(Clone, Debug)]
16struct Foo { 22struct Foo {
17 pub x: i32, 23 pub x: i32,
@@ -42,6 +48,25 @@ impl Foo {
42 } 48 }
43} 49}
44 50
51#[derive(Copy, Clone)]
52struct FooCopy {
53 x: u32,
54}
55
56impl FooCopy {
57 fn baz(self) -> u32 {
58 self.x
59 }
60
61 fn qux(&mut self) {
62 self.x = 0;
63 }
64
65 fn quop(&self) -> u32 {
66 self.x
67 }
68}
69
45static mut STATIC_MUT: i32 = 0; 70static mut STATIC_MUT: i32 = 0;
46 71
47fn foo<'a, T>() -> T { 72fn foo<'a, T>() -> T {
@@ -96,6 +121,11 @@ fn main() {
96 foo.quop(); 121 foo.quop();
97 foo.qux(); 122 foo.qux();
98 foo.baz(); 123 foo.baz();
124
125 let mut copy = FooCopy { x };
126 copy.quop();
127 copy.qux();
128 copy.baz();
99} 129}
100 130
101enum Option<T> { 131enum Option<T> {
diff --git a/crates/ide/test_data/highlighting.html b/crates/ide/test_data/highlighting.html
index 2aad06a92..a6b79589b 100644
--- a/crates/ide/test_data/highlighting.html
+++ b/crates/ide/test_data/highlighting.html
@@ -38,6 +38,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span> 38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span>
39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span> 39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span>
40 40
41<span class="comment">// Needed for function consuming vs normal</span>
42<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="punctuation">{</span>
43 <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">lang</span><span class="attribute"> </span><span class="operator">=</span><span class="attribute"> </span><span class="string_literal">"copy"</span><span class="attribute">]</span>
44 <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span>
45<span class="punctuation">}</span>
46
41<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> 47<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span>
42<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> 48<span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
43 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> 49 <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
@@ -55,7 +61,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
55<span class="punctuation">}</span> 61<span class="punctuation">}</span>
56 62
57<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 63<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
58 <span class="keyword">fn</span> <span class="function declaration consuming">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 64 <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
59 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> 65 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
60 <span class="punctuation">}</span> 66 <span class="punctuation">}</span>
61 67
@@ -68,6 +74,25 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
68 <span class="punctuation">}</span> 74 <span class="punctuation">}</span>
69<span class="punctuation">}</span> 75<span class="punctuation">}</span>
70 76
77<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Copy</span><span class="punctuation">,</span><span class="attribute"> Clone</span><span class="punctuation">)</span><span class="attribute">]</span>
78<span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="punctuation">{</span>
79 <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span>
80<span class="punctuation">}</span>
81
82<span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span>
83 <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
84 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
85 <span class="punctuation">}</span>
86
87 <span class="keyword">fn</span> <span class="function declaration mutable">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
88 <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
89 <span class="punctuation">}</span>
90
91 <span class="keyword">fn</span> <span class="function declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
92 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
93 <span class="punctuation">}</span>
94<span class="punctuation">}</span>
95
71<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="punctuation">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> 96<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="punctuation">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
72 97
73<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">&lt;</span><span class="lifetime declaration">'a</span><span class="punctuation">,</span> <span class="type_param declaration">T</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="type_param">T</span> <span class="punctuation">{</span> 98<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">&lt;</span><span class="lifetime declaration">'a</span><span class="punctuation">,</span> <span class="type_param declaration">T</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="type_param">T</span> <span class="punctuation">{</span>
@@ -122,6 +147,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
122 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 147 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
123 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 148 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
124 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 149 <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
150
151 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
152 <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
153 <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
154 <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
125<span class="punctuation">}</span> 155<span class="punctuation">}</span>
126 156
127<span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span> 157<span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
@@ -131,7 +161,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
131<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span> 161<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span>
132 162
133<span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span> 163<span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
134 <span class="keyword">fn</span> <span class="function declaration consuming">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span> 164 <span class="keyword">fn</span> <span class="function declaration">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
135 <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span> 165 <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span>
136 <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> 166 <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
137 <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span> 167 <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span>