diff options
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r-- | crates/ide/src/goto_definition.rs | 57 |
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 @@ | |||
1 | use either::Either; | ||
1 | use hir::Semantics; | 2 | use hir::Semantics; |
2 | use ide_db::{ | 3 | use 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, <) { | ||
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(<)).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 | ||
103 | pub(crate) fn reference_definition( | 111 | pub(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#" | ||
1054 | fn foo<'foobar<|>>(_: &'foobar ()) { | ||
1055 | //^^^^^^^ | ||
1056 | }"#, | ||
1057 | ) | ||
1058 | } | ||
1059 | |||
1060 | #[test] | ||
1061 | fn goto_lifetime_param_decl() { | ||
1062 | check( | ||
1063 | r#" | ||
1064 | fn foo<'foobar>(_: &'foobar<|> ()) { | ||
1065 | //^^^^^^^ | ||
1066 | }"#, | ||
1067 | ) | ||
1068 | } | ||
1069 | |||
1070 | #[test] | ||
1071 | fn goto_lifetime_param_decl_nested() { | ||
1072 | check( | ||
1073 | r#" | ||
1074 | fn foo<'foobar>(_: &'foobar ()) { | ||
1075 | fn foo<'foobar>(_: &'foobar<|> ()) {} | ||
1076 | //^^^^^^^ | ||
1077 | }"#, | ||
1078 | ) | ||
1079 | } | ||
1039 | } | 1080 | } |