aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/semantics.rs8
-rw-r--r--crates/ra_hir/src/source_analyzer.rs31
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html15
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs17
-rw-r--r--crates/ra_ide_db/src/defs.rs6
5 files changed, 61 insertions, 16 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index c3d8ee1ae..154adedb3 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -18,8 +18,8 @@ use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer}, 19 source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer},
20 source_binder::{ChildContainer, SourceBinder}, 20 source_binder::{ChildContainer, SourceBinder},
21 Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution, 21 Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path,
22 ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, 22 PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
23}; 23};
24use ra_prof::profile; 24use ra_prof::profile;
25 25
@@ -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;
11use hir_def::{ 11use 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
27use crate::{ 27use 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::{
35pub(crate) struct SourceAnalyzer { 35pub(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/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 8c372ad27..cb4097e05 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -65,10 +65,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
65 <span class="variable mutable">y</span>; 65 <span class="variable mutable">y</span>;
66} 66}
67 67
68<span class="keyword">enum</span> <span class="enum">E</span>&lt;<span class="type_param">X</span>&gt; { 68<span class="keyword">enum</span> <span class="enum">Option</span>&lt;<span class="type_param">T</span>&gt; {
69 <span class="enum_variant">V</span>(<span class="type_param">X</span>) 69 <span class="enum_variant">Some</span>(<span class="type_param">T</span>),
70 <span class="enum_variant">None</span>,
70} 71}
72<span class="keyword">use</span> <span class="enum">Option</span>::*;
71 73
72<span class="keyword">impl</span>&lt;<span class="type_param">X</span>&gt; <span class="enum">E</span>&lt;<span class="type_param">X</span>&gt; { 74<span class="keyword">impl</span>&lt;<span class="type_param">T</span>&gt; <span class="enum">Option</span>&lt;<span class="type_param">T</span>&gt; {
73 <span class="keyword">fn</span> <span class="function">new</span>&lt;<span class="type_param">T</span>&gt;() -&gt; <span class="enum">E</span>&lt;<span class="type_param">T</span>&gt; {} 75 <span class="keyword">fn</span> <span class="function">and</span>&lt;<span class="type_param">U</span>&gt;(<span class="keyword">self</span>, <span class="variable">other</span>: <span class="enum">Option</span>&lt;<span class="type_param">U</span>&gt;) -&gt; <span class="enum">Option</span>&lt;(<span class="type_param">T</span>, <span class="type_param">U</span>)&gt; {
76 <span class="keyword control">match</span> <span class="variable">other</span> {
77 <span class="enum_variant">None</span> =&gt; <span class="macro">todo</span><span class="macro">!</span>(),
78 <span class="variable">Nope</span> =&gt; <span class="variable">Nope</span>,
79 }
80 }
74}</code></pre> \ No newline at end of file 81}</code></pre> \ No newline at end of file
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 2d90a072f..21c4dd818 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -50,12 +50,19 @@ fn main() {
50 y; 50 y;
51} 51}
52 52
53enum E<X> { 53enum Option<T> {
54 V(X) 54 Some(T),
55 None,
55} 56}
56 57use Option::*;
57impl<X> E<X> { 58
58 fn new<T>() -> E<T> {} 59impl<T> Option<T> {
60 fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
61 match other {
62 None => todo!(),
63 Nope => Nope,
64 }
65 }
59} 66}
60"# 67"#
61 .trim(), 68 .trim(),
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 3079d1197..93f32ba85 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -90,6 +90,12 @@ impl NameClass {
90} 90}
91 91
92pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { 92pub 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
93 classify_name_inner(sema, name).map(NameClass::NameDefinition) 99 classify_name_inner(sema, name).map(NameClass::NameDefinition)
94} 100}
95 101