aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/goto_definition.rs')
-rw-r--r--crates/ra_ide/src/goto_definition.rs42
1 files changed, 17 insertions, 25 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index feff1ec3f..621ab982c 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::AstDatabase, InFile, SourceBinder}; 3use hir::Semantics;
4use ra_ide_db::{symbol_index, RootDatabase}; 4use ra_ide_db::{defs::classify_name, symbol_index, RootDatabase};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self}, 6 ast::{self},
7 match_ast, AstNode, 7 match_ast, AstNode,
@@ -11,8 +11,7 @@ use ra_syntax::{
11 11
12use crate::{ 12use crate::{
13 display::{ToNav, TryToNav}, 13 display::{ToNav, TryToNav},
14 expand::descend_into_macros, 14 references::classify_name_ref,
15 references::{classify_name, classify_name_ref},
16 FilePosition, NavigationTarget, RangeInfo, 15 FilePosition, NavigationTarget, RangeInfo,
17}; 16};
18 17
@@ -20,18 +19,20 @@ pub(crate) fn goto_definition(
20 db: &RootDatabase, 19 db: &RootDatabase,
21 position: FilePosition, 20 position: FilePosition,
22) -> Option<RangeInfo<Vec<NavigationTarget>>> { 21) -> Option<RangeInfo<Vec<NavigationTarget>>> {
23 let file = db.parse_or_expand(position.file_id.into())?; 22 let sema = Semantics::new(db);
23 let file = sema.parse(position.file_id).syntax().clone();
24 let original_token = pick_best(file.token_at_offset(position.offset))?; 24 let original_token = pick_best(file.token_at_offset(position.offset))?;
25 let token = descend_into_macros(db, position.file_id, original_token.clone()); 25 let token = sema.descend_into_macros(original_token.clone());
26 26
27 let mut sb = SourceBinder::new(db);
28 let nav_targets = match_ast! { 27 let nav_targets = match_ast! {
29 match (token.value.parent()) { 28 match (token.parent()) {
30 ast::NameRef(name_ref) => { 29 ast::NameRef(name_ref) => {
31 reference_definition(&mut sb, token.with_value(&name_ref)).to_vec() 30 reference_definition(&sema, &name_ref).to_vec()
32 }, 31 },
33 ast::Name(name) => { 32 ast::Name(name) => {
34 name_definition(&mut sb, token.with_value(&name))? 33 let def = classify_name(&sema, &name)?.definition();
34 let nav = def.try_to_nav(sema.db)?;
35 vec![nav]
35 }, 36 },
36 _ => return None, 37 _ => return None,
37 } 38 }
@@ -68,36 +69,27 @@ impl ReferenceResult {
68} 69}
69 70
70pub(crate) fn reference_definition( 71pub(crate) fn reference_definition(
71 sb: &mut SourceBinder<RootDatabase>, 72 sema: &Semantics<RootDatabase>,
72 name_ref: InFile<&ast::NameRef>, 73 name_ref: &ast::NameRef,
73) -> ReferenceResult { 74) -> ReferenceResult {
74 use self::ReferenceResult::*; 75 use self::ReferenceResult::*;
75 76
76 let name_kind = classify_name_ref(sb, name_ref); 77 let name_kind = classify_name_ref(sema, name_ref);
77 if let Some(def) = name_kind { 78 if let Some(def) = name_kind {
78 return match def.try_to_nav(sb.db) { 79 return match def.try_to_nav(sema.db) {
79 Some(nav) => ReferenceResult::Exact(nav), 80 Some(nav) => ReferenceResult::Exact(nav),
80 None => ReferenceResult::Approximate(Vec::new()), 81 None => ReferenceResult::Approximate(Vec::new()),
81 }; 82 };
82 } 83 }
83 84
84 // Fallback index based approach: 85 // Fallback index based approach:
85 let navs = symbol_index::index_resolve(sb.db, name_ref.value) 86 let navs = symbol_index::index_resolve(sema.db, name_ref)
86 .into_iter() 87 .into_iter()
87 .map(|s| s.to_nav(sb.db)) 88 .map(|s| s.to_nav(sema.db))
88 .collect(); 89 .collect();
89 Approximate(navs) 90 Approximate(navs)
90} 91}
91 92
92fn name_definition(
93 sb: &mut SourceBinder<RootDatabase>,
94 name: InFile<&ast::Name>,
95) -> Option<Vec<NavigationTarget>> {
96 let def = classify_name(sb, name)?;
97 let nav = def.try_to_nav(sb.db)?;
98 Some(vec![nav])
99}
100
101#[cfg(test)] 93#[cfg(test)]
102mod tests { 94mod tests {
103 use test_utils::{assert_eq_text, covers}; 95 use test_utils::{assert_eq_text, covers};