aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r--crates/ide/src/goto_definition.rs57
1 files changed, 49 insertions, 8 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index b9810457f..173509b08 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,3 +1,4 @@
1use either::Either;
1use hir::Semantics; 2use hir::Semantics;
2use ide_db::{ 3use ide_db::{
3 base_db::FileId, 4 base_db::FileId,
@@ -33,7 +34,7 @@ pub(crate) fn goto_definition(
33 let nav_targets = match_ast! { 34 let nav_targets = match_ast! {
34 match parent { 35 match parent {
35 ast::NameRef(name_ref) => { 36 ast::NameRef(name_ref) => {
36 reference_definition(&sema, &name_ref).to_vec() 37 reference_definition(&sema, Either::Right(&name_ref)).to_vec()
37 }, 38 },
38 ast::Name(name) => { 39 ast::Name(name) => {
39 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db); 40 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
@@ -53,6 +54,13 @@ pub(crate) fn goto_definition(
53 let self_param = func.param_list()?.self_param()?; 54 let self_param = func.param_list()?.self_param()?;
54 vec![self_to_nav_target(self_param, position.file_id)?] 55 vec![self_to_nav_target(self_param, position.file_id)?]
55 }, 56 },
57 ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
58 let def = name_class.referenced_or_defined(sema.db);
59 let nav = def.try_to_nav(sema.db)?;
60 vec![nav]
61 } else {
62 reference_definition(&sema, Either::Left(&lt)).to_vec()
63 },
56 _ => return None, 64 _ => return None,
57 } 65 }
58 }; 66 };
@@ -64,7 +72,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
64 return tokens.max_by_key(priority); 72 return tokens.max_by_key(priority);
65 fn priority(n: &SyntaxToken) -> usize { 73 fn priority(n: &SyntaxToken) -> usize {
66 match n.kind() { 74 match n.kind() {
67 IDENT | INT_NUMBER | T![self] => 2, 75 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2,
68 kind if kind.is_trivia() => 0, 76 kind if kind.is_trivia() => 0,
69 _ => 1, 77 _ => 1,
70 } 78 }
@@ -102,9 +110,12 @@ impl ReferenceResult {
102 110
103pub(crate) fn reference_definition( 111pub(crate) fn reference_definition(
104 sema: &Semantics<RootDatabase>, 112 sema: &Semantics<RootDatabase>,
105 name_ref: &ast::NameRef, 113 name_ref: Either<&ast::Lifetime, &ast::NameRef>,
106) -> ReferenceResult { 114) -> ReferenceResult {
107 let name_kind = NameRefClass::classify(sema, name_ref); 115 let name_kind = name_ref.either(
116 |lifetime| NameRefClass::classify_lifetime(sema, lifetime),
117 |name_ref| NameRefClass::classify(sema, name_ref),
118 );
108 if let Some(def) = name_kind { 119 if let Some(def) = name_kind {
109 let def = def.referenced(sema.db); 120 let def = def.referenced(sema.db);
110 return match def.try_to_nav(sema.db) { 121 return match def.try_to_nav(sema.db) {
@@ -114,10 +125,9 @@ pub(crate) fn reference_definition(
114 } 125 }
115 126
116 // Fallback index based approach: 127 // Fallback index based approach:
117 let navs = symbol_index::index_resolve(sema.db, name_ref) 128 let name = name_ref.either(ast::Lifetime::text, ast::NameRef::text);
118 .into_iter() 129 let navs =
119 .map(|s| s.to_nav(sema.db)) 130 symbol_index::index_resolve(sema.db, name).into_iter().map(|s| s.to_nav(sema.db)).collect();
120 .collect();
121 ReferenceResult::Approximate(navs) 131 ReferenceResult::Approximate(navs)
122} 132}
123 133
@@ -1036,4 +1046,35 @@ impl Foo {
1036}"#, 1046}"#,
1037 ) 1047 )
1038 } 1048 }
1049
1050 #[test]
1051 fn goto_lifetime_param_on_decl() {
1052 check(
1053 r#"
1054fn foo<'foobar<|>>(_: &'foobar ()) {
1055 //^^^^^^^
1056}"#,
1057 )
1058 }
1059
1060 #[test]
1061 fn goto_lifetime_param_decl() {
1062 check(
1063 r#"
1064fn foo<'foobar>(_: &'foobar<|> ()) {
1065 //^^^^^^^
1066}"#,
1067 )
1068 }
1069
1070 #[test]
1071 fn goto_lifetime_param_decl_nested() {
1072 check(
1073 r#"
1074fn foo<'foobar>(_: &'foobar ()) {
1075 fn foo<'foobar>(_: &'foobar<|> ()) {}
1076 //^^^^^^^
1077}"#,
1078 )
1079 }
1039} 1080}