diff options
-rw-r--r-- | crates/ra_hir/src/semantics.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 31 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 13 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlighting.html | 42 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/rainbow_highlighting.html | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 25 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/html.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tags.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tests.rs | 24 | ||||
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 33 | ||||
-rw-r--r-- | crates/ra_ide_db/src/imports_locator.rs | 3 |
13 files changed, 144 insertions, 71 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index eecccdae2..178d74be1 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs | |||
@@ -17,8 +17,8 @@ use crate::{ | |||
17 | db::HirDatabase, | 17 | db::HirDatabase, |
18 | source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer}, | 18 | source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer}, |
19 | source_binder::{ChildContainer, SourceBinder}, | 19 | source_binder::{ChildContainer, SourceBinder}, |
20 | Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution, | 20 | Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path, |
21 | ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, | 21 | PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, |
22 | }; | 22 | }; |
23 | use hir_expand::ExpansionInfo; | 23 | use hir_expand::ExpansionInfo; |
24 | use ra_prof::profile; | 24 | use ra_prof::profile; |
@@ -129,6 +129,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
129 | self.analyze(path.syntax()).resolve_path(self.db, path) | 129 | self.analyze(path.syntax()).resolve_path(self.db, path) |
130 | } | 130 | } |
131 | 131 | ||
132 | pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { | ||
133 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) | ||
134 | } | ||
135 | |||
132 | // FIXME: use this instead? | 136 | // FIXME: use this instead? |
133 | // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>; | 137 | // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>; |
134 | 138 | ||
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index b655e2c32..c650a9e08 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -11,9 +11,9 @@ use either::Either; | |||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | body::{ | 12 | body::{ |
13 | scope::{ExprScopes, ScopeId}, | 13 | scope::{ExprScopes, ScopeId}, |
14 | BodySourceMap, | 14 | Body, BodySourceMap, |
15 | }, | 15 | }, |
16 | expr::{ExprId, PatId}, | 16 | expr::{ExprId, Pat, PatId}, |
17 | resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, | 17 | resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, |
18 | AsMacroCall, DefWithBodyId, | 18 | AsMacroCall, DefWithBodyId, |
19 | }; | 19 | }; |
@@ -25,8 +25,8 @@ use ra_syntax::{ | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | use crate::{ | 27 | use crate::{ |
28 | db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, Path, Static, Struct, | 28 | db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static, |
29 | Trait, Type, TypeAlias, TypeParam, | 29 | Struct, Trait, Type, TypeAlias, TypeParam, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of | 32 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of |
@@ -35,6 +35,7 @@ use crate::{ | |||
35 | pub(crate) struct SourceAnalyzer { | 35 | pub(crate) struct SourceAnalyzer { |
36 | file_id: HirFileId, | 36 | file_id: HirFileId, |
37 | pub(crate) resolver: Resolver, | 37 | pub(crate) resolver: Resolver, |
38 | body: Option<Arc<Body>>, | ||
38 | body_source_map: Option<Arc<BodySourceMap>>, | 39 | body_source_map: Option<Arc<BodySourceMap>>, |
39 | infer: Option<Arc<InferenceResult>>, | 40 | infer: Option<Arc<InferenceResult>>, |
40 | scopes: Option<Arc<ExprScopes>>, | 41 | scopes: Option<Arc<ExprScopes>>, |
@@ -66,7 +67,7 @@ impl SourceAnalyzer { | |||
66 | node: InFile<&SyntaxNode>, | 67 | node: InFile<&SyntaxNode>, |
67 | offset: Option<TextUnit>, | 68 | offset: Option<TextUnit>, |
68 | ) -> SourceAnalyzer { | 69 | ) -> SourceAnalyzer { |
69 | let (_body, source_map) = db.body_with_source_map(def); | 70 | let (body, source_map) = db.body_with_source_map(def); |
70 | let scopes = db.expr_scopes(def); | 71 | let scopes = db.expr_scopes(def); |
71 | let scope = match offset { | 72 | let scope = match offset { |
72 | None => scope_for(&scopes, &source_map, node), | 73 | None => scope_for(&scopes, &source_map, node), |
@@ -75,6 +76,7 @@ impl SourceAnalyzer { | |||
75 | let resolver = resolver_for_scope(db, def, scope); | 76 | let resolver = resolver_for_scope(db, def, scope); |
76 | SourceAnalyzer { | 77 | SourceAnalyzer { |
77 | resolver, | 78 | resolver, |
79 | body: Some(body), | ||
78 | body_source_map: Some(source_map), | 80 | body_source_map: Some(source_map), |
79 | infer: Some(db.infer(def)), | 81 | infer: Some(db.infer(def)), |
80 | scopes: Some(scopes), | 82 | scopes: Some(scopes), |
@@ -88,6 +90,7 @@ impl SourceAnalyzer { | |||
88 | ) -> SourceAnalyzer { | 90 | ) -> SourceAnalyzer { |
89 | SourceAnalyzer { | 91 | SourceAnalyzer { |
90 | resolver, | 92 | resolver, |
93 | body: None, | ||
91 | body_source_map: None, | 94 | body_source_map: None, |
92 | infer: None, | 95 | infer: None, |
93 | scopes: None, | 96 | scopes: None, |
@@ -197,6 +200,24 @@ impl SourceAnalyzer { | |||
197 | self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) | 200 | self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) |
198 | } | 201 | } |
199 | 202 | ||
203 | pub(crate) fn resolve_bind_pat_to_const( | ||
204 | &self, | ||
205 | db: &impl HirDatabase, | ||
206 | pat: &ast::BindPat, | ||
207 | ) -> Option<ModuleDef> { | ||
208 | let pat_id = self.pat_id(&pat.clone().into())?; | ||
209 | let body = self.body.as_ref()?; | ||
210 | let path = match &body[pat_id] { | ||
211 | Pat::Path(path) => path, | ||
212 | _ => return None, | ||
213 | }; | ||
214 | let res = resolve_hir_path(db, &self.resolver, &path)?; | ||
215 | match res { | ||
216 | PathResolution::Def(def) => Some(def), | ||
217 | _ => None, | ||
218 | } | ||
219 | } | ||
220 | |||
200 | pub(crate) fn resolve_path( | 221 | pub(crate) fn resolve_path( |
201 | &self, | 222 | &self, |
202 | db: &impl HirDatabase, | 223 | db: &impl HirDatabase, |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 6053c1bb6..621ab982c 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -30,7 +30,9 @@ pub(crate) fn goto_definition( | |||
30 | reference_definition(&sema, &name_ref).to_vec() | 30 | reference_definition(&sema, &name_ref).to_vec() |
31 | }, | 31 | }, |
32 | ast::Name(name) => { | 32 | ast::Name(name) => { |
33 | name_definition(&sema, &name)? | 33 | let def = classify_name(&sema, &name)?.definition(); |
34 | let nav = def.try_to_nav(sema.db)?; | ||
35 | vec![nav] | ||
34 | }, | 36 | }, |
35 | _ => return None, | 37 | _ => return None, |
36 | } | 38 | } |
@@ -88,15 +90,6 @@ pub(crate) fn reference_definition( | |||
88 | Approximate(navs) | 90 | Approximate(navs) |
89 | } | 91 | } |
90 | 92 | ||
91 | fn name_definition( | ||
92 | sema: &Semantics<RootDatabase>, | ||
93 | name: &ast::Name, | ||
94 | ) -> Option<Vec<NavigationTarget>> { | ||
95 | let def = classify_name(sema, name)?; | ||
96 | let nav = def.try_to_nav(sema.db)?; | ||
97 | Some(vec![nav]) | ||
98 | } | ||
99 | |||
100 | #[cfg(test)] | 93 | #[cfg(test)] |
101 | mod tests { | 94 | mod tests { |
102 | use test_utils::{assert_eq_text, covers}; | 95 | use test_utils::{assert_eq_text, covers}; |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index cc79f1fab..5073bb1cf 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -156,7 +156,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
156 | classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d)) | 156 | classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d)) |
157 | }, | 157 | }, |
158 | ast::Name(name) => { | 158 | ast::Name(name) => { |
159 | classify_name(&sema, &name).map(|d| (name.syntax().clone(), d)) | 159 | classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition())) |
160 | }, | 160 | }, |
161 | _ => None, | 161 | _ => None, |
162 | } | 162 | } |
@@ -785,13 +785,13 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
785 | fn test_hover_through_literal_string_in_builtin_macro() { | 785 | fn test_hover_through_literal_string_in_builtin_macro() { |
786 | check_hover_no_result( | 786 | check_hover_no_result( |
787 | r#" | 787 | r#" |
788 | //- /lib.rs | 788 | //- /lib.rs |
789 | #[rustc_builtin_macro] | 789 | #[rustc_builtin_macro] |
790 | macro_rules! assert { | 790 | macro_rules! assert { |
791 | ($cond:expr) => {{ /* compiler built-in */ }}; | 791 | ($cond:expr) => {{ /* compiler built-in */ }}; |
792 | ($cond:expr,) => {{ /* compiler built-in */ }}; | 792 | ($cond:expr,) => {{ /* compiler built-in */ }}; |
793 | ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; | 793 | ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; |
794 | } | 794 | } |
795 | 795 | ||
796 | fn foo() { | 796 | fn foo() { |
797 | assert!("hel<|>lo"); | 797 | assert!("hel<|>lo"); |
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index baa8a4d29..f763013ae 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -155,7 +155,7 @@ fn find_name( | |||
155 | opt_name: Option<ast::Name>, | 155 | opt_name: Option<ast::Name>, |
156 | ) -> Option<RangeInfo<(String, NameDefinition)>> { | 156 | ) -> Option<RangeInfo<(String, NameDefinition)>> { |
157 | if let Some(name) = opt_name { | 157 | if let Some(name) = opt_name { |
158 | let def = classify_name(sema, &name)?; | 158 | let def = classify_name(sema, &name)?.definition(); |
159 | let range = name.syntax().text_range(); | 159 | let range = name.syntax().text_range(); |
160 | return Some(RangeInfo::new(range, (name.text().to_string(), def))); | 160 | return Some(RangeInfo::new(range, (name.text().to_string(), def))); |
161 | } | 161 | } |
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index 8c372ad27..495b07f69 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html | |||
@@ -3,7 +3,7 @@ | |||
3 | body { margin: 0; } | 3 | body { margin: 0; } |
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } |
5 | 5 | ||
6 | 6 | .lifetime { color: #DFAF8F; font-style: italic; } | |
7 | .comment { color: #7F9F7F; } | 7 | .comment { color: #7F9F7F; } |
8 | .struct, .enum { color: #7CB8BB; } | 8 | .struct, .enum { color: #7CB8BB; } |
9 | .enum_variant { color: #BDE0F3; } | 9 | .enum_variant { color: #BDE0F3; } |
@@ -27,14 +27,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
27 | .control { font-style: italic; } | 27 | .control { font-style: italic; } |
28 | </style> | 28 | </style> |
29 | <pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> | 29 | <pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> |
30 | <span class="keyword">struct</span> <span class="struct">Foo</span> { | 30 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> { |
31 | <span class="keyword">pub</span> <span class="field">x</span>: <span class="builtin_type">i32</span>, | 31 | <span class="keyword">pub</span> <span class="field declaration">x</span>: <span class="builtin_type">i32</span>, |
32 | <span class="keyword">pub</span> <span class="field">y</span>: <span class="builtin_type">i32</span>, | 32 | <span class="keyword">pub</span> <span class="field declaration">y</span>: <span class="builtin_type">i32</span>, |
33 | } | 33 | } |
34 | 34 | ||
35 | <span class="keyword">fn</span> <span class="function">foo</span><<span class="type_param">T</span>>() -> <span class="type_param">T</span> { | 35 | <span class="keyword">fn</span> <span class="function declaration">foo</span><<span class="lifetime declaration">'a</span>, <span class="type_param declaration">T</span>>() -> <span class="type_param">T</span> { |
36 | <span class="macro">unimplemented</span><span class="macro">!</span>(); | 36 | <span class="function">foo</span>::<<span class="lifetime">'a</span>, <span class="builtin_type">i32</span>>() |
37 | <span class="function">foo</span>::<<span class="builtin_type">i32</span>>(); | ||
38 | } | 37 | } |
39 | 38 | ||
40 | <span class="macro">macro_rules</span><span class="macro">!</span> def_fn { | 39 | <span class="macro">macro_rules</span><span class="macro">!</span> def_fn { |
@@ -42,33 +41,40 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
42 | } | 41 | } |
43 | 42 | ||
44 | <span class="macro">def_fn</span><span class="macro">!</span> { | 43 | <span class="macro">def_fn</span><span class="macro">!</span> { |
45 | <span class="keyword">fn</span> <span class="function">bar</span>() -> <span class="builtin_type">u32</span> { | 44 | <span class="keyword">fn</span> <span class="function declaration">bar</span>() -> <span class="builtin_type">u32</span> { |
46 | <span class="numeric_literal">100</span> | 45 | <span class="numeric_literal">100</span> |
47 | } | 46 | } |
48 | } | 47 | } |
49 | 48 | ||
50 | <span class="comment">// comment</span> | 49 | <span class="comment">// comment</span> |
51 | <span class="keyword">fn</span> <span class="function">main</span>() { | 50 | <span class="keyword">fn</span> <span class="function declaration">main</span>() { |
52 | <span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>); | 51 | <span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>); |
53 | 52 | ||
54 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">vec</span> = Vec::new(); | 53 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">vec</span> = Vec::new(); |
55 | <span class="keyword control">if</span> <span class="keyword">true</span> { | 54 | <span class="keyword control">if</span> <span class="keyword">true</span> { |
56 | <span class="keyword">let</span> <span class="variable">x</span> = <span class="numeric_literal">92</span>; | 55 | <span class="keyword">let</span> <span class="variable declaration">x</span> = <span class="numeric_literal">92</span>; |
57 | <span class="variable mutable">vec</span>.push(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> }); | 56 | <span class="variable mutable">vec</span>.push(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> }); |
58 | } | 57 | } |
59 | <span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); } | 58 | <span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); } |
60 | 59 | ||
61 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">x</span> = <span class="numeric_literal">42</span>; | 60 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> = <span class="numeric_literal">42</span>; |
62 | <span class="keyword">let</span> <span class="variable mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>; | 61 | <span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>; |
63 | <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable mutable">y</span>; | 62 | <span class="keyword">let</span> <span class="variable declaration">z</span> = &<span class="variable mutable">y</span>; |
64 | 63 | ||
65 | <span class="variable mutable">y</span>; | 64 | <span class="variable mutable">y</span>; |
66 | } | 65 | } |
67 | 66 | ||
68 | <span class="keyword">enum</span> <span class="enum">E</span><<span class="type_param">X</span>> { | 67 | <span class="keyword">enum</span> <span class="enum declaration">Option</span><<span class="type_param declaration">T</span>> { |
69 | <span class="enum_variant">V</span>(<span class="type_param">X</span>) | 68 | <span class="enum_variant declaration">Some</span>(<span class="type_param">T</span>), |
69 | <span class="enum_variant declaration">None</span>, | ||
70 | } | 70 | } |
71 | <span class="keyword">use</span> <span class="enum">Option</span>::*; | ||
71 | 72 | ||
72 | <span class="keyword">impl</span><<span class="type_param">X</span>> <span class="enum">E</span><<span class="type_param">X</span>> { | 73 | <span class="keyword">impl</span><<span class="type_param declaration">T</span>> <span class="enum">Option</span><<span class="type_param">T</span>> { |
73 | <span class="keyword">fn</span> <span class="function">new</span><<span class="type_param">T</span>>() -> <span class="enum">E</span><<span class="type_param">T</span>> {} | 74 | <span class="keyword">fn</span> <span class="function declaration">and</span><<span class="type_param declaration">U</span>>(<span class="keyword">self</span>, <span class="variable declaration">other</span>: <span class="enum">Option</span><<span class="type_param">U</span>>) -> <span class="enum">Option</span><(<span class="type_param">T</span>, <span class="type_param">U</span>)> { |
75 | <span class="keyword control">match</span> <span class="variable">other</span> { | ||
76 | <span class="enum_variant">None</span> => <span class="macro">unimplemented</span><span class="macro">!</span>(), | ||
77 | <span class="variable declaration">Nope</span> => <span class="variable">Nope</span>, | ||
78 | } | ||
79 | } | ||
74 | }</code></pre> \ No newline at end of file | 80 | }</code></pre> \ No newline at end of file |
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html index f63e64b6d..dddbfc0dd 100644 --- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html | |||
@@ -3,7 +3,7 @@ | |||
3 | body { margin: 0; } | 3 | body { margin: 0; } |
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } |
5 | 5 | ||
6 | 6 | .lifetime { color: #DFAF8F; font-style: italic; } | |
7 | .comment { color: #7F9F7F; } | 7 | .comment { color: #7F9F7F; } |
8 | .struct, .enum { color: #7CB8BB; } | 8 | .struct, .enum { color: #7CB8BB; } |
9 | .enum_variant { color: #BDE0F3; } | 9 | .enum_variant { color: #BDE0F3; } |
@@ -26,15 +26,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
26 | .keyword.unsafe { color: #BC8383; font-weight: bold; } | 26 | .keyword.unsafe { color: #BC8383; font-weight: bold; } |
27 | .control { font-style: italic; } | 27 | .control { font-style: italic; } |
28 | </style> | 28 | </style> |
29 | <pre><code><span class="keyword">fn</span> <span class="function">main</span>() { | 29 | <pre><code><span class="keyword">fn</span> <span class="function declaration">main</span>() { |
30 | <span class="keyword">let</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; | 30 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; |
31 | <span class="keyword">let</span> <span class="variable" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); | 31 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); |
32 | <span class="keyword">let</span> <span class="variable" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); | 32 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); |
33 | 33 | ||
34 | <span class="keyword">let</span> <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>; | 34 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>; |
35 | <span class="keyword">let</span> <span class="variable" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string(); | 35 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string(); |
36 | } | 36 | } |
37 | 37 | ||
38 | <span class="keyword">fn</span> <span class="function">bar</span>() { | 38 | <span class="keyword">fn</span> <span class="function declaration">bar</span>() { |
39 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; | 39 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; |
40 | }</code></pre> \ No newline at end of file | 40 | }</code></pre> \ No newline at end of file |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index c0f7c1c9f..b94b6a022 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -7,7 +7,7 @@ mod tests; | |||
7 | 7 | ||
8 | use hir::{Name, Semantics}; | 8 | use hir::{Name, Semantics}; |
9 | use ra_ide_db::{ | 9 | use ra_ide_db::{ |
10 | defs::{classify_name, NameDefinition}, | 10 | defs::{classify_name, NameClass, NameDefinition}, |
11 | RootDatabase, | 11 | RootDatabase, |
12 | }; | 12 | }; |
13 | use ra_prof::profile; | 13 | use ra_prof::profile; |
@@ -169,7 +169,7 @@ fn highlight_element( | |||
169 | let name = element.into_node().and_then(ast::Name::cast).unwrap(); | 169 | let name = element.into_node().and_then(ast::Name::cast).unwrap(); |
170 | let name_kind = classify_name(sema, &name); | 170 | let name_kind = classify_name(sema, &name); |
171 | 171 | ||
172 | if let Some(NameDefinition::Local(local)) = &name_kind { | 172 | if let Some(NameClass::NameDefinition(NameDefinition::Local(local))) = &name_kind { |
173 | if let Some(name) = local.name(db) { | 173 | if let Some(name) = local.name(db) { |
174 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); | 174 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); |
175 | *shadow_count += 1; | 175 | *shadow_count += 1; |
@@ -177,11 +177,13 @@ fn highlight_element( | |||
177 | } | 177 | } |
178 | }; | 178 | }; |
179 | 179 | ||
180 | let h = match name_kind { | 180 | match name_kind { |
181 | Some(name_kind) => highlight_name(db, name_kind), | 181 | Some(NameClass::NameDefinition(def)) => { |
182 | None => highlight_name_by_syntax(name), | 182 | highlight_name(db, def) | HighlightModifier::Definition |
183 | }; | 183 | } |
184 | h | HighlightModifier::Definition | 184 | Some(NameClass::ConstReference(def)) => highlight_name(db, def), |
185 | None => highlight_name_by_syntax(name) | HighlightModifier::Definition, | ||
186 | } | ||
185 | } | 187 | } |
186 | 188 | ||
187 | // Highlight references like the definitions they resolve to | 189 | // Highlight references like the definitions they resolve to |
@@ -212,8 +214,13 @@ fn highlight_element( | |||
212 | INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), | 214 | INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), |
213 | BYTE => HighlightTag::ByteLiteral.into(), | 215 | BYTE => HighlightTag::ByteLiteral.into(), |
214 | CHAR => HighlightTag::CharLiteral.into(), | 216 | CHAR => HighlightTag::CharLiteral.into(), |
215 | // FIXME: set Declaration for decls | 217 | LIFETIME => { |
216 | LIFETIME => HighlightTag::Lifetime.into(), | 218 | let h = Highlight::new(HighlightTag::Lifetime); |
219 | dbg!(match element.parent().map(|it| it.kind()) { | ||
220 | Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, | ||
221 | _ => h, | ||
222 | }) | ||
223 | } | ||
217 | 224 | ||
218 | k if k.is_keyword() => { | 225 | k if k.is_keyword() => { |
219 | let h = Highlight::new(HighlightTag::Keyword); | 226 | let h = Highlight::new(HighlightTag::Keyword); |
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs index 54678c278..e13766c9d 100644 --- a/crates/ra_ide/src/syntax_highlighting/html.rs +++ b/crates/ra_ide/src/syntax_highlighting/html.rs | |||
@@ -80,7 +80,7 @@ const STYLE: &str = " | |||
80 | body { margin: 0; } | 80 | body { margin: 0; } |
81 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 81 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } |
82 | 82 | ||
83 | 83 | .lifetime { color: #DFAF8F; font-style: italic; } | |
84 | .comment { color: #7F9F7F; } | 84 | .comment { color: #7F9F7F; } |
85 | .struct, .enum { color: #7CB8BB; } | 85 | .struct, .enum { color: #7CB8BB; } |
86 | .enum_variant { color: #BDE0F3; } | 86 | .enum_variant { color: #BDE0F3; } |
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs index 9da80823c..8835a5de2 100644 --- a/crates/ra_ide/src/syntax_highlighting/tags.rs +++ b/crates/ra_ide/src/syntax_highlighting/tags.rs | |||
@@ -90,8 +90,12 @@ impl fmt::Display for HighlightTag { | |||
90 | } | 90 | } |
91 | 91 | ||
92 | impl HighlightModifier { | 92 | impl HighlightModifier { |
93 | const ALL: &'static [HighlightModifier] = | 93 | const ALL: &'static [HighlightModifier] = &[ |
94 | &[HighlightModifier::Mutable, HighlightModifier::Unsafe, HighlightModifier::Control]; | 94 | HighlightModifier::Control, |
95 | HighlightModifier::Definition, | ||
96 | HighlightModifier::Mutable, | ||
97 | HighlightModifier::Unsafe, | ||
98 | ]; | ||
95 | 99 | ||
96 | fn as_str(self) -> &'static str { | 100 | fn as_str(self) -> &'static str { |
97 | match self { | 101 | match self { |
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 2d90a072f..98c030791 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs | |||
@@ -17,9 +17,8 @@ struct Foo { | |||
17 | pub y: i32, | 17 | pub y: i32, |
18 | } | 18 | } |
19 | 19 | ||
20 | fn foo<T>() -> T { | 20 | fn foo<'a, T>() -> T { |
21 | unimplemented!(); | 21 | foo::<'a, i32>() |
22 | foo::<i32>(); | ||
23 | } | 22 | } |
24 | 23 | ||
25 | macro_rules! def_fn { | 24 | macro_rules! def_fn { |
@@ -50,12 +49,19 @@ fn main() { | |||
50 | y; | 49 | y; |
51 | } | 50 | } |
52 | 51 | ||
53 | enum E<X> { | 52 | enum Option<T> { |
54 | V(X) | 53 | Some(T), |
54 | None, | ||
55 | } | 55 | } |
56 | 56 | use Option::*; | |
57 | impl<X> E<X> { | 57 | |
58 | fn new<T>() -> E<T> {} | 58 | impl<T> Option<T> { |
59 | fn and<U>(self, other: Option<U>) -> Option<(T, U)> { | ||
60 | match other { | ||
61 | None => unimplemented!(), | ||
62 | Nope => Nope, | ||
63 | } | ||
64 | } | ||
59 | } | 65 | } |
60 | "# | 66 | "# |
61 | .trim(), | 67 | .trim(), |
@@ -123,5 +129,5 @@ fn test_ranges() { | |||
123 | .highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) }) | 129 | .highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) }) |
124 | .unwrap(); | 130 | .unwrap(); |
125 | 131 | ||
126 | assert_eq!(&highlights[0].highlight.to_string(), "field"); | 132 | assert_eq!(&highlights[0].highlight.to_string(), "field.declaration"); |
127 | } | 133 | } |
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 484755158..93f32ba85 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -68,7 +68,38 @@ impl NameDefinition { | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> { | 71 | pub enum NameClass { |
72 | NameDefinition(NameDefinition), | ||
73 | /// `None` in `if let None = Some(82) {}` | ||
74 | ConstReference(NameDefinition), | ||
75 | } | ||
76 | |||
77 | impl NameClass { | ||
78 | pub fn into_definition(self) -> Option<NameDefinition> { | ||
79 | match self { | ||
80 | NameClass::NameDefinition(it) => Some(it), | ||
81 | NameClass::ConstReference(_) => None, | ||
82 | } | ||
83 | } | ||
84 | |||
85 | pub fn definition(self) -> NameDefinition { | ||
86 | match self { | ||
87 | NameClass::NameDefinition(it) | NameClass::ConstReference(it) => it, | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { | ||
93 | if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) { | ||
94 | if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { | ||
95 | return Some(NameClass::ConstReference(NameDefinition::ModuleDef(def))); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | classify_name_inner(sema, name).map(NameClass::NameDefinition) | ||
100 | } | ||
101 | |||
102 | fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> { | ||
72 | let _p = profile("classify_name"); | 103 | let _p = profile("classify_name"); |
73 | let parent = name.syntax().parent()?; | 104 | let parent = name.syntax().parent()?; |
74 | 105 | ||
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index e590d2a5c..e5fc3c470 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs | |||
@@ -59,6 +59,7 @@ impl<'a> ImportsLocator<'a> { | |||
59 | } else { | 59 | } else { |
60 | candidate_node | 60 | candidate_node |
61 | }; | 61 | }; |
62 | classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?) | 62 | let name = ast::Name::cast(candidate_name_node)?; |
63 | classify_name(&self.sema, &name)?.into_definition() | ||
63 | } | 64 | } |
64 | } | 65 | } |