diff options
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r-- | crates/ide/src/goto_definition.rs | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index a2c97061f..ca8ccb2da 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use either::Either; | 1 | use either::Either; |
2 | use hir::Semantics; | 2 | use hir::{InFile, Semantics}; |
3 | use ide_db::{ | 3 | use ide_db::{ |
4 | defs::{NameClass, NameRefClass}, | 4 | defs::{NameClass, NameRefClass}, |
5 | RootDatabase, | 5 | RootDatabase, |
@@ -8,7 +8,7 @@ use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, Toke | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | display::TryToNav, | 10 | display::TryToNav, |
11 | doc_links::{doc_owner_to_def, extract_positioned_link_from_comment, resolve_doc_path_for_def}, | 11 | doc_links::{doc_attributes, extract_definitions_from_markdown, resolve_doc_path_for_def}, |
12 | FilePosition, NavigationTarget, RangeInfo, | 12 | FilePosition, NavigationTarget, RangeInfo, |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -21,6 +21,8 @@ use crate::{ | |||
21 | // | 21 | // |
22 | // | VS Code | kbd:[F12] | 22 | // | VS Code | kbd:[F12] |
23 | // |=== | 23 | // |=== |
24 | // | ||
25 | // image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[] | ||
24 | pub(crate) fn goto_definition( | 26 | pub(crate) fn goto_definition( |
25 | db: &RootDatabase, | 27 | db: &RootDatabase, |
26 | position: FilePosition, | 28 | position: FilePosition, |
@@ -30,9 +32,16 @@ pub(crate) fn goto_definition( | |||
30 | let original_token = pick_best(file.token_at_offset(position.offset))?; | 32 | let original_token = pick_best(file.token_at_offset(position.offset))?; |
31 | let token = sema.descend_into_macros(original_token.clone()); | 33 | let token = sema.descend_into_macros(original_token.clone()); |
32 | let parent = token.parent()?; | 34 | let parent = token.parent()?; |
33 | if let Some(comment) = ast::Comment::cast(token) { | 35 | if let Some(_) = ast::Comment::cast(token) { |
34 | let (_, link, ns) = extract_positioned_link_from_comment(position.offset, &comment)?; | 36 | let (attributes, def) = doc_attributes(&sema, &parent)?; |
35 | let def = doc_owner_to_def(&sema, &parent)?; | 37 | |
38 | let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?; | ||
39 | let (_, link, ns) = | ||
40 | extract_definitions_from_markdown(docs.as_str()).into_iter().find(|(range, ..)| { | ||
41 | doc_mapping.map(range.clone()).map_or(false, |InFile { file_id, value: range }| { | ||
42 | file_id == position.file_id.into() && range.contains(position.offset) | ||
43 | }) | ||
44 | })?; | ||
36 | let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?; | 45 | let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?; |
37 | return Some(RangeInfo::new(original_token.text_range(), vec![nav])); | 46 | return Some(RangeInfo::new(original_token.text_range(), vec![nav])); |
38 | } | 47 | } |
@@ -918,6 +927,21 @@ fn f() -> impl Iterator<Item$0 = u8> {} | |||
918 | } | 927 | } |
919 | 928 | ||
920 | #[test] | 929 | #[test] |
930 | #[should_panic = "unresolved reference"] | ||
931 | fn unknown_assoc_ty() { | ||
932 | check( | ||
933 | r#" | ||
934 | trait Iterator { | ||
935 | type Item; | ||
936 | //^^^^ | ||
937 | } | ||
938 | |||
939 | fn f() -> impl Iterator<Invalid$0 = u8> {} | ||
940 | "#, | ||
941 | ) | ||
942 | } | ||
943 | |||
944 | #[test] | ||
921 | fn goto_def_for_assoc_ty_in_path_multiple() { | 945 | fn goto_def_for_assoc_ty_in_path_multiple() { |
922 | check( | 946 | check( |
923 | r#" | 947 | r#" |
@@ -1143,4 +1167,25 @@ fn fn_macro() {} | |||
1143 | "#, | 1167 | "#, |
1144 | ) | 1168 | ) |
1145 | } | 1169 | } |
1170 | |||
1171 | #[test] | ||
1172 | fn goto_intra_doc_links() { | ||
1173 | check( | ||
1174 | r#" | ||
1175 | |||
1176 | pub mod theitem { | ||
1177 | /// This is the item. Cool! | ||
1178 | pub struct TheItem; | ||
1179 | //^^^^^^^ | ||
1180 | } | ||
1181 | |||
1182 | /// Gives you a [`TheItem$0`]. | ||
1183 | /// | ||
1184 | /// [`TheItem`]: theitem::TheItem | ||
1185 | pub fn gimme() -> theitem::TheItem { | ||
1186 | theitem::TheItem | ||
1187 | } | ||
1188 | "#, | ||
1189 | ); | ||
1190 | } | ||
1146 | } | 1191 | } |