diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 19 | ||||
-rw-r--r-- | crates/ra_ide_api/src/name_ref_kind.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/snapshots/rainbow_highlighting.html | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/syntax_highlighting.rs | 109 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 11 |
6 files changed, 92 insertions, 68 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index e7bc4df97..55eb7da35 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -181,7 +181,7 @@ pub enum PathResolution { | |||
181 | /// An item | 181 | /// An item |
182 | Def(crate::ModuleDef), | 182 | Def(crate::ModuleDef), |
183 | /// A local binding (only value namespace) | 183 | /// A local binding (only value namespace) |
184 | LocalBinding(Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>), | 184 | LocalBinding(Either<AstPtr<ast::BindPat>, AstPtr<ast::SelfParam>>), |
185 | /// A generic parameter | 185 | /// A generic parameter |
186 | GenericParam(u32), | 186 | GenericParam(u32), |
187 | SelfType(crate::ImplBlock), | 187 | SelfType(crate::ImplBlock), |
@@ -307,7 +307,18 @@ impl SourceAnalyzer { | |||
307 | let res = match res { | 307 | let res = match res { |
308 | crate::Resolution::Def(it) => PathResolution::Def(it), | 308 | crate::Resolution::Def(it) => PathResolution::Def(it), |
309 | crate::Resolution::LocalBinding(it) => { | 309 | crate::Resolution::LocalBinding(it) => { |
310 | PathResolution::LocalBinding(self.body_source_map.as_ref()?.pat_syntax(it)?) | 310 | // We get a `PatId` from resolver, but it actually can only |
311 | // point at `BindPat`, and not at the arbitrary pattern. | ||
312 | let pat_ptr = self.body_source_map.as_ref()?.pat_syntax(it)?; | ||
313 | let pat_ptr = match pat_ptr { | ||
314 | Either::A(pat) => { | ||
315 | let pat: AstPtr<ast::BindPat> = | ||
316 | pat.cast_checking_kind(|kind| kind == BIND_PAT).unwrap(); | ||
317 | Either::A(pat) | ||
318 | } | ||
319 | Either::B(self_param) => Either::B(self_param), | ||
320 | }; | ||
321 | PathResolution::LocalBinding(pat_ptr) | ||
311 | } | 322 | } |
312 | crate::Resolution::GenericParam(it) => PathResolution::GenericParam(it), | 323 | crate::Resolution::GenericParam(it) => PathResolution::GenericParam(it), |
313 | crate::Resolution::SelfType(it) => PathResolution::SelfType(it), | 324 | crate::Resolution::SelfType(it) => PathResolution::SelfType(it), |
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 8cc853dd1..8aff5f2cd 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -91,24 +91,11 @@ impl NavigationTarget { | |||
91 | pub(crate) fn from_pat( | 91 | pub(crate) fn from_pat( |
92 | db: &RootDatabase, | 92 | db: &RootDatabase, |
93 | file_id: FileId, | 93 | file_id: FileId, |
94 | pat: AstPtr<ast::Pat>, | 94 | pat: AstPtr<ast::BindPat>, |
95 | ) -> NavigationTarget { | 95 | ) -> NavigationTarget { |
96 | let parse = db.parse(file_id); | 96 | let parse = db.parse(file_id); |
97 | let (name, full_range) = match pat.to_node(parse.tree().syntax()).kind() { | 97 | let pat = pat.to_node(parse.tree().syntax()); |
98 | ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat), | 98 | NavigationTarget::from_bind_pat(file_id, &pat) |
99 | _ => ("_".into(), pat.syntax_node_ptr().range()), | ||
100 | }; | ||
101 | |||
102 | NavigationTarget { | ||
103 | file_id, | ||
104 | name, | ||
105 | full_range, | ||
106 | focus_range: None, | ||
107 | kind: NAME, | ||
108 | container_name: None, | ||
109 | description: None, //< No documentation for Description | ||
110 | docs: None, //< No documentation for Pattern | ||
111 | } | ||
112 | } | 99 | } |
113 | 100 | ||
114 | pub(crate) fn from_self_param( | 101 | pub(crate) fn from_self_param( |
diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs index 6832acf5d..f7db6c826 100644 --- a/crates/ra_ide_api/src/name_ref_kind.rs +++ b/crates/ra_ide_api/src/name_ref_kind.rs | |||
@@ -11,7 +11,7 @@ pub enum NameRefKind { | |||
11 | AssocItem(hir::ImplItem), | 11 | AssocItem(hir::ImplItem), |
12 | Def(hir::ModuleDef), | 12 | Def(hir::ModuleDef), |
13 | SelfType(hir::Ty), | 13 | SelfType(hir::Ty), |
14 | Pat(AstPtr<ast::Pat>), | 14 | Pat(AstPtr<ast::BindPat>), |
15 | SelfParam(AstPtr<ast::SelfParam>), | 15 | SelfParam(AstPtr<ast::SelfParam>), |
16 | GenericParam(u32), | 16 | GenericParam(u32), |
17 | } | 17 | } |
diff --git a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html b/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html index c625d47bf..ed664817e 100644 --- a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html | |||
@@ -26,4 +26,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
26 | 26 | ||
27 | <span class="keyword">let</span> <span class="variable" data-binding-hash="1903207544374197704" style="color: hsl(58,61%,61%);">x</span> = <span class="string">"other color please!"</span>; | 27 | <span class="keyword">let</span> <span class="variable" data-binding-hash="1903207544374197704" style="color: hsl(58,61%,61%);">x</span> = <span class="string">"other color please!"</span>; |
28 | <span class="keyword">let</span> <span class="variable" data-binding-hash="14878783531007968800" style="color: hsl(265,73%,83%);">y</span> = <span class="variable" data-binding-hash="1903207544374197704" style="color: hsl(58,61%,61%);">x</span>.<span class="text">to_string</span>(); | 28 | <span class="keyword">let</span> <span class="variable" data-binding-hash="14878783531007968800" style="color: hsl(265,73%,83%);">y</span> = <span class="variable" data-binding-hash="1903207544374197704" style="color: hsl(58,61%,61%);">x</span>.<span class="text">to_string</span>(); |
29 | } | ||
30 | |||
31 | <span class="keyword">fn</span> <span class="function">bar</span>() { | ||
32 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut" data-binding-hash="3888301305669440875" style="color: hsl(242,59%,59%);">hello</span> = <span class="string">"hello"</span>; | ||
29 | }</code></pre> \ No newline at end of file | 33 | }</code></pre> \ No newline at end of file |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 16a728789..0e5253025 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -4,10 +4,17 @@ use hir::{Mutability, Ty}; | |||
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_prof::profile; | 5 | use ra_prof::profile; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | ast, AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T, | 7 | ast::{self, NameOwner}, |
8 | AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, | ||
9 | SyntaxKind::*, | ||
10 | TextRange, T, | ||
8 | }; | 11 | }; |
9 | 12 | ||
10 | use crate::{db::RootDatabase, FileId}; | 13 | use crate::{ |
14 | db::RootDatabase, | ||
15 | name_ref_kind::{classify_name_ref, NameRefKind::*}, | ||
16 | FileId, | ||
17 | }; | ||
11 | 18 | ||
12 | #[derive(Debug)] | 19 | #[derive(Debug)] |
13 | pub struct HighlightedRange { | 20 | pub struct HighlightedRange { |
@@ -31,25 +38,24 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { | |||
31 | } | 38 | } |
32 | } | 39 | } |
33 | 40 | ||
34 | fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: ast::Pat) -> bool { | 41 | fn is_variable_mutable( |
35 | let ty = analyzer.type_of_pat(db, &pat).unwrap_or(Ty::Unknown); | 42 | db: &RootDatabase, |
36 | let is_ty_mut = { | 43 | analyzer: &hir::SourceAnalyzer, |
37 | if let Some((_, mutability)) = ty.as_reference() { | 44 | pat: ast::BindPat, |
38 | match mutability { | 45 | ) -> bool { |
39 | Mutability::Shared => false, | 46 | if pat.is_mutable() { |
40 | Mutability::Mut => true, | 47 | return true; |
41 | } | 48 | } |
42 | } else { | ||
43 | false | ||
44 | } | ||
45 | }; | ||
46 | |||
47 | let is_pat_mut = match pat.kind() { | ||
48 | ast::PatKind::BindPat(bind_pat) => bind_pat.is_mutable(), | ||
49 | _ => false, | ||
50 | }; | ||
51 | 49 | ||
52 | is_ty_mut || is_pat_mut | 50 | let ty = analyzer.type_of_pat(db, &pat.into()).unwrap_or(Ty::Unknown); |
51 | if let Some((_, mutability)) = ty.as_reference() { | ||
52 | match mutability { | ||
53 | Mutability::Shared => false, | ||
54 | Mutability::Mut => true, | ||
55 | } | ||
56 | } else { | ||
57 | false | ||
58 | } | ||
53 | } | 59 | } |
54 | 60 | ||
55 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 61 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { |
@@ -81,44 +87,45 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
81 | } | 87 | } |
82 | let mut binding_hash = None; | 88 | let mut binding_hash = None; |
83 | let tag = match node.kind() { | 89 | let tag = match node.kind() { |
90 | FN_DEF => { | ||
91 | bindings_shadow_count.clear(); | ||
92 | continue; | ||
93 | } | ||
84 | COMMENT => "comment", | 94 | COMMENT => "comment", |
85 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | 95 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", |
86 | ATTR => "attribute", | 96 | ATTR => "attribute", |
87 | NAME_REF => { | 97 | NAME_REF => { |
88 | if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) { | 98 | if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) { |
89 | // FIXME: revisit this after #1340 | ||
90 | use crate::name_ref_kind::{classify_name_ref, NameRefKind::*}; | ||
91 | use hir::{ImplItem, ModuleDef}; | ||
92 | |||
93 | // FIXME: try to reuse the SourceAnalyzers | 99 | // FIXME: try to reuse the SourceAnalyzers |
94 | let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); | 100 | let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); |
95 | match classify_name_ref(db, &analyzer, &name_ref) { | 101 | match classify_name_ref(db, &analyzer, &name_ref) { |
96 | Some(Method(_)) => "function", | 102 | Some(Method(_)) => "function", |
97 | Some(Macro(_)) => "macro", | 103 | Some(Macro(_)) => "macro", |
98 | Some(FieldAccess(_)) => "field", | 104 | Some(FieldAccess(_)) => "field", |
99 | Some(AssocItem(ImplItem::Method(_))) => "function", | 105 | Some(AssocItem(hir::ImplItem::Method(_))) => "function", |
100 | Some(AssocItem(ImplItem::Const(_))) => "constant", | 106 | Some(AssocItem(hir::ImplItem::Const(_))) => "constant", |
101 | Some(AssocItem(ImplItem::TypeAlias(_))) => "type", | 107 | Some(AssocItem(hir::ImplItem::TypeAlias(_))) => "type", |
102 | Some(Def(ModuleDef::Module(_))) => "module", | 108 | Some(Def(hir::ModuleDef::Module(_))) => "module", |
103 | Some(Def(ModuleDef::Function(_))) => "function", | 109 | Some(Def(hir::ModuleDef::Function(_))) => "function", |
104 | Some(Def(ModuleDef::Struct(_))) => "type", | 110 | Some(Def(hir::ModuleDef::Struct(_))) => "type", |
105 | Some(Def(ModuleDef::Union(_))) => "type", | 111 | Some(Def(hir::ModuleDef::Union(_))) => "type", |
106 | Some(Def(ModuleDef::Enum(_))) => "type", | 112 | Some(Def(hir::ModuleDef::Enum(_))) => "type", |
107 | Some(Def(ModuleDef::EnumVariant(_))) => "constant", | 113 | Some(Def(hir::ModuleDef::EnumVariant(_))) => "constant", |
108 | Some(Def(ModuleDef::Const(_))) => "constant", | 114 | Some(Def(hir::ModuleDef::Const(_))) => "constant", |
109 | Some(Def(ModuleDef::Static(_))) => "constant", | 115 | Some(Def(hir::ModuleDef::Static(_))) => "constant", |
110 | Some(Def(ModuleDef::Trait(_))) => "type", | 116 | Some(Def(hir::ModuleDef::Trait(_))) => "type", |
111 | Some(Def(ModuleDef::TypeAlias(_))) => "type", | 117 | Some(Def(hir::ModuleDef::TypeAlias(_))) => "type", |
112 | Some(Def(ModuleDef::BuiltinType(_))) => "type", | 118 | Some(Def(hir::ModuleDef::BuiltinType(_))) => "type", |
113 | Some(SelfType(_)) => "type", | 119 | Some(SelfType(_)) => "type", |
114 | Some(Pat(ptr)) => { | 120 | Some(Pat(ptr)) => { |
115 | binding_hash = Some({ | 121 | let pat = ptr.to_node(&root); |
116 | let text = | 122 | if let Some(name) = pat.name() { |
117 | ptr.syntax_node_ptr().to_node(&root).text().to_smol_string(); | 123 | let text = name.text(); |
118 | let shadow_count = | 124 | let shadow_count = |
119 | bindings_shadow_count.entry(text.clone()).or_default(); | 125 | bindings_shadow_count.entry(text.clone()).or_default(); |
120 | calc_binding_hash(file_id, &text, *shadow_count) | 126 | binding_hash = |
121 | }); | 127 | Some(calc_binding_hash(file_id, &text, *shadow_count)) |
128 | } | ||
122 | 129 | ||
123 | if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) { | 130 | if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) { |
124 | "variable.mut" | 131 | "variable.mut" |
@@ -137,14 +144,14 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
137 | NAME => { | 144 | NAME => { |
138 | if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) { | 145 | if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) { |
139 | let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); | 146 | let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); |
140 | if let Some(pat) = name.syntax().ancestors().find_map(ast::Pat::cast) { | 147 | if let Some(pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) { |
141 | binding_hash = Some({ | 148 | if let Some(name) = pat.name() { |
142 | let text = name.syntax().text().to_smol_string(); | 149 | let text = name.text(); |
143 | let shadow_count = | 150 | let shadow_count = |
144 | bindings_shadow_count.entry(text.clone()).or_insert(0); | 151 | bindings_shadow_count.entry(text.clone()).or_default(); |
145 | *shadow_count += 1; | 152 | *shadow_count += 1; |
146 | calc_binding_hash(file_id, &text, *shadow_count) | 153 | binding_hash = Some(calc_binding_hash(file_id, &text, *shadow_count)) |
147 | }); | 154 | } |
148 | 155 | ||
149 | if is_variable_mutable(db, &analyzer, pat) { | 156 | if is_variable_mutable(db, &analyzer, pat) { |
150 | "variable.mut" | 157 | "variable.mut" |
@@ -353,6 +360,10 @@ fn main() { | |||
353 | let x = "other color please!"; | 360 | let x = "other color please!"; |
354 | let y = x.to_string(); | 361 | let y = x.to_string(); |
355 | } | 362 | } |
363 | |||
364 | fn bar() { | ||
365 | let mut hello = "hello"; | ||
366 | } | ||
356 | "# | 367 | "# |
357 | .trim(), | 368 | .trim(), |
358 | ); | 369 | ); |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 016256075..25824722f 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -60,6 +60,17 @@ impl<N: AstNode> AstPtr<N> { | |||
60 | pub fn syntax_node_ptr(self) -> SyntaxNodePtr { | 60 | pub fn syntax_node_ptr(self) -> SyntaxNodePtr { |
61 | self.raw | 61 | self.raw |
62 | } | 62 | } |
63 | |||
64 | // FIXME: extend AstNode to do this safely | ||
65 | pub fn cast_checking_kind<U: AstNode>( | ||
66 | self, | ||
67 | cond: impl FnOnce(SyntaxKind) -> bool, | ||
68 | ) -> Option<AstPtr<U>> { | ||
69 | if !cond(self.raw.kind()) { | ||
70 | return None; | ||
71 | } | ||
72 | Some(AstPtr { raw: self.raw, _ty: PhantomData }) | ||
73 | } | ||
63 | } | 74 | } |
64 | 75 | ||
65 | impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr { | 76 | impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr { |