aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/syntax_highlighting.rs117
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs3
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs39
-rw-r--r--crates/ide/test_data/highlighting.html41
4 files changed, 156 insertions, 44 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)]
5mod tests; 5mod tests;
6 6
7use hir::{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,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;
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 49ec94bdc..c1b817f06 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -62,6 +62,7 @@ pub enum HighlightModifier {
62 Documentation, 62 Documentation,
63 Injected, 63 Injected,
64 Mutable, 64 Mutable,
65 Consuming,
65 Unsafe, 66 Unsafe,
66} 67}
67 68
@@ -119,6 +120,7 @@ impl HighlightModifier {
119 HighlightModifier::Documentation, 120 HighlightModifier::Documentation,
120 HighlightModifier::Injected, 121 HighlightModifier::Injected,
121 HighlightModifier::Mutable, 122 HighlightModifier::Mutable,
123 HighlightModifier::Consuming,
122 HighlightModifier::Unsafe, 124 HighlightModifier::Unsafe,
123 ]; 125 ];
124 126
@@ -130,6 +132,7 @@ impl HighlightModifier {
130 HighlightModifier::Documentation => "documentation", 132 HighlightModifier::Documentation => "documentation",
131 HighlightModifier::Injected => "injected", 133 HighlightModifier::Injected => "injected",
132 HighlightModifier::Mutable => "mutable", 134 HighlightModifier::Mutable => "mutable",
135 HighlightModifier::Consuming => "consuming",
133 HighlightModifier::Unsafe => "unsafe", 136 HighlightModifier::Unsafe => "unsafe",
134 } 137 }
135 } 138 }
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 94f37d773..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,
@@ -36,6 +42,29 @@ impl Foo {
36 fn qux(&mut self) { 42 fn qux(&mut self) {
37 self.x = 0; 43 self.x = 0;
38 } 44 }
45
46 fn quop(&self) -> i32 {
47 self.x
48 }
49}
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 }
39} 68}
40 69
41static mut STATIC_MUT: i32 = 0; 70static mut STATIC_MUT: i32 = 0;
@@ -87,6 +116,16 @@ fn main() {
87 let Foo { x: z, y } = Foo { x: z, y }; 116 let Foo { x: z, y } = Foo { x: z, y };
88 117
89 y; 118 y;
119
120 let mut foo = Foo { x, y: x };
121 foo.quop();
122 foo.qux();
123 foo.baz();
124
125 let mut copy = FooCopy { x };
126 copy.quop();
127 copy.qux();
128 copy.baz();
90} 129}
91 130
92enum Option<T> { 131enum Option<T> {
diff --git a/crates/ide/test_data/highlighting.html b/crates/ide/test_data/highlighting.html
index 8e0160eee..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>
@@ -59,9 +65,32 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
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
62 <span class="keyword">fn</span> <span class="function declaration">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> 68 <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>
63 <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> 69 <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>
64 <span class="punctuation">}</span> 70 <span class="punctuation">}</span>
71
72 <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">i32</span> <span class="punctuation">{</span>
73 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
74 <span class="punctuation">}</span>
75<span class="punctuation">}</span>
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>
65<span class="punctuation">}</span> 94<span class="punctuation">}</span>
66 95
67<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>
@@ -113,6 +142,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
113 <span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span> 142 <span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span>
114 143
115 <span class="variable">y</span><span class="punctuation">;</span> 144 <span class="variable">y</span><span class="punctuation">;</span>
145
146 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</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>
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>
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>
116<span class="punctuation">}</span> 155<span class="punctuation">}</span>
117 156
118<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>