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.rs46
1 files changed, 43 insertions, 3 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 2c634990d..bee8e9df2 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -3,7 +3,9 @@
3use hir::{db::AstDatabase, InFile}; 3use hir::{db::AstDatabase, InFile};
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{self, DocCommentsOwner}, 5 ast::{self, DocCommentsOwner},
6 match_ast, AstNode, SyntaxNode, 6 match_ast, AstNode,
7 SyntaxKind::*,
8 SyntaxNode, SyntaxToken, TokenAtOffset,
7}; 9};
8 10
9use crate::{ 11use crate::{
@@ -19,8 +21,7 @@ pub(crate) fn goto_definition(
19 position: FilePosition, 21 position: FilePosition,
20) -> Option<RangeInfo<Vec<NavigationTarget>>> { 22) -> Option<RangeInfo<Vec<NavigationTarget>>> {
21 let file = db.parse_or_expand(position.file_id.into())?; 23 let file = db.parse_or_expand(position.file_id.into())?;
22 let original_token = 24 let original_token = pick_best(file.token_at_offset(position.offset))?;
23 file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?;
24 let token = descend_into_macros(db, position.file_id, original_token.clone()); 25 let token = descend_into_macros(db, position.file_id, original_token.clone());
25 26
26 let nav_targets = match_ast! { 27 let nav_targets = match_ast! {
@@ -38,6 +39,17 @@ pub(crate) fn goto_definition(
38 Some(RangeInfo::new(original_token.text_range(), nav_targets)) 39 Some(RangeInfo::new(original_token.text_range(), nav_targets))
39} 40}
40 41
42fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
43 return tokens.max_by_key(priority);
44 fn priority(n: &SyntaxToken) -> usize {
45 match n.kind() {
46 IDENT | INT_NUMBER => 2,
47 kind if kind.is_trivia() => 0,
48 _ => 1,
49 }
50 }
51}
52
41#[derive(Debug)] 53#[derive(Debug)]
42pub(crate) enum ReferenceResult { 54pub(crate) enum ReferenceResult {
43 Exact(NavigationTarget), 55 Exact(NavigationTarget),
@@ -253,6 +265,18 @@ mod tests {
253 } 265 }
254 266
255 #[test] 267 #[test]
268 fn goto_definition_works_at_start_of_item() {
269 check_goto(
270 "
271 //- /lib.rs
272 struct Foo;
273 enum E { X(<|>Foo) }
274 ",
275 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
276 );
277 }
278
279 #[test]
256 fn goto_definition_resolves_correct_name() { 280 fn goto_definition_resolves_correct_name() {
257 check_goto( 281 check_goto(
258 " 282 "
@@ -453,6 +477,22 @@ mod tests {
453 } 477 }
454 478
455 #[test] 479 #[test]
480 fn goto_for_tuple_fields() {
481 check_goto(
482 "
483 //- /lib.rs
484 struct Foo(u32);
485
486 fn bar() {
487 let foo = Foo(0);
488 foo.<|>0;
489 }
490 ",
491 "TUPLE_FIELD_DEF FileId(1) [11; 14)",
492 );
493 }
494
495 #[test]
456 fn goto_definition_works_for_ufcs_inherent_methods() { 496 fn goto_definition_works_for_ufcs_inherent_methods() {
457 check_goto( 497 check_goto(
458 " 498 "