aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/defs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r--crates/ra_ide_db/src/defs.rs22
1 files changed, 12 insertions, 10 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 7cd2384e9..8b06cbfc5 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -14,7 +14,6 @@ use ra_syntax::{
14 ast::{self, AstNode}, 14 ast::{self, AstNode},
15 match_ast, 15 match_ast,
16}; 16};
17use test_utils::tested_by;
18 17
19use crate::RootDatabase; 18use crate::RootDatabase;
20 19
@@ -42,12 +41,10 @@ impl Definition {
42 } 41 }
43 42
44 pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> { 43 pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
45 let module = self.module(db);
46
47 match self { 44 match self {
48 Definition::Macro(_) => None, 45 Definition::Macro(_) => None,
49 Definition::Field(sf) => Some(sf.visibility(db)), 46 Definition::Field(sf) => Some(sf.visibility(db)),
50 Definition::ModuleDef(def) => module?.visibility_of(db, def), 47 Definition::ModuleDef(def) => def.definition_visibility(db),
51 Definition::SelfType(_) => None, 48 Definition::SelfType(_) => None,
52 Definition::Local(_) => None, 49 Definition::Local(_) => None,
53 Definition::TypeParam(_) => None, 50 Definition::TypeParam(_) => None,
@@ -119,6 +116,15 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
119 116
120 match_ast! { 117 match_ast! {
121 match parent { 118 match parent {
119 ast::Alias(it) => {
120 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
121 let path = use_tree.path()?;
122 let path_segment = path.segment()?;
123 let name_ref = path_segment.name_ref()?;
124 let name_ref_class = classify_name_ref(sema, &name_ref)?;
125
126 Some(name_ref_class.definition())
127 },
122 ast::BindPat(it) => { 128 ast::BindPat(it) => {
123 let local = sema.to_def(&it)?; 129 let local = sema.to_def(&it)?;
124 Some(Definition::Local(local)) 130 Some(Definition::Local(local))
@@ -195,6 +201,8 @@ impl NameRefClass {
195 } 201 }
196} 202}
197 203
204// Note: we don't have unit-tests for this rather important function.
205// It is primarily exercised via goto definition tests in `ra_ide`.
198pub fn classify_name_ref( 206pub fn classify_name_ref(
199 sema: &Semantics<RootDatabase>, 207 sema: &Semantics<RootDatabase>,
200 name_ref: &ast::NameRef, 208 name_ref: &ast::NameRef,
@@ -204,22 +212,18 @@ pub fn classify_name_ref(
204 let parent = name_ref.syntax().parent()?; 212 let parent = name_ref.syntax().parent()?;
205 213
206 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { 214 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
207 tested_by!(goto_def_for_methods; force);
208 if let Some(func) = sema.resolve_method_call(&method_call) { 215 if let Some(func) = sema.resolve_method_call(&method_call) {
209 return Some(NameRefClass::Definition(Definition::ModuleDef(func.into()))); 216 return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
210 } 217 }
211 } 218 }
212 219
213 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { 220 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
214 tested_by!(goto_def_for_fields; force);
215 if let Some(field) = sema.resolve_field(&field_expr) { 221 if let Some(field) = sema.resolve_field(&field_expr) {
216 return Some(NameRefClass::Definition(Definition::Field(field))); 222 return Some(NameRefClass::Definition(Definition::Field(field)));
217 } 223 }
218 } 224 }
219 225
220 if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { 226 if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
221 tested_by!(goto_def_for_record_fields; force);
222 tested_by!(goto_def_for_field_init_shorthand; force);
223 if let Some((field, local)) = sema.resolve_record_field(&record_field) { 227 if let Some((field, local)) = sema.resolve_record_field(&record_field) {
224 let field = Definition::Field(field); 228 let field = Definition::Field(field);
225 let res = match local { 229 let res = match local {
@@ -231,7 +235,6 @@ pub fn classify_name_ref(
231 } 235 }
232 236
233 if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) { 237 if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
234 tested_by!(goto_def_for_record_field_pats; force);
235 if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { 238 if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
236 let field = Definition::Field(field); 239 let field = Definition::Field(field);
237 return Some(NameRefClass::Definition(field)); 240 return Some(NameRefClass::Definition(field));
@@ -239,7 +242,6 @@ pub fn classify_name_ref(
239 } 242 }
240 243
241 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { 244 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
242 tested_by!(goto_def_for_macros; force);
243 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) { 245 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
244 return Some(NameRefClass::Definition(Definition::Macro(macro_def))); 246 return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
245 } 247 }