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 cfe62037f..27052d72b 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),
@@ -235,6 +247,18 @@ mod tests {
235 } 247 }
236 248
237 #[test] 249 #[test]
250 fn goto_definition_works_at_start_of_item() {
251 check_goto(
252 "
253 //- /lib.rs
254 struct Foo;
255 enum E { X(<|>Foo) }
256 ",
257 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
258 );
259 }
260
261 #[test]
238 fn goto_definition_resolves_correct_name() { 262 fn goto_definition_resolves_correct_name() {
239 check_goto( 263 check_goto(
240 " 264 "
@@ -435,6 +459,22 @@ mod tests {
435 } 459 }
436 460
437 #[test] 461 #[test]
462 fn goto_for_tuple_fields() {
463 check_goto(
464 "
465 //- /lib.rs
466 struct Foo(u32);
467
468 fn bar() {
469 let foo = Foo(0);
470 foo.<|>0;
471 }
472 ",
473 "TUPLE_FIELD_DEF FileId(1) [11; 14)",
474 );
475 }
476
477 #[test]
438 fn goto_definition_works_for_ufcs_inherent_methods() { 478 fn goto_definition_works_for_ufcs_inherent_methods() {
439 check_goto( 479 check_goto(
440 " 480 "