aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/goto_definition.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-05 13:30:20 +0100
committerGitHub <[email protected]>2021-04-05 13:30:20 +0100
commitc2be91dcd826e1529ac6ac431b3f871ec72abebc (patch)
treee267eed3fc8966093fbd79389e47a051c435cd7d /crates/ide/src/goto_definition.rs
parentd8ee25bb976f50c0c0c8c247ca8bb030d9167bdb (diff)
parent8d786dc4c3ce26dbb3432023c7461bd879993bfd (diff)
Merge #8245
8245: Properly resolve intra doc links in hover and goto_definition r=matklad a=Veykril Unfortunately involves a bit of weird workarounds due to pulldown_cmark's incorrect lifetimes on `BrokenLinkCallback`... I should probably open an issue there asking for the fixes to be pushed to a release since they already exist in the repo for quite some time it seems. Fixes #8258, Fixes #8238 Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r--crates/ide/src/goto_definition.rs38
1 files changed, 33 insertions, 5 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 8574d1e3f..ca8ccb2da 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,5 +1,5 @@
1use either::Either; 1use either::Either;
2use hir::Semantics; 2use hir::{InFile, Semantics};
3use ide_db::{ 3use 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
9use crate::{ 9use 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
@@ -32,9 +32,16 @@ pub(crate) fn goto_definition(
32 let original_token = pick_best(file.token_at_offset(position.offset))?; 32 let original_token = pick_best(file.token_at_offset(position.offset))?;
33 let token = sema.descend_into_macros(original_token.clone()); 33 let token = sema.descend_into_macros(original_token.clone());
34 let parent = token.parent()?; 34 let parent = token.parent()?;
35 if let Some(comment) = ast::Comment::cast(token) { 35 if let Some(_) = ast::Comment::cast(token) {
36 let (_, link, ns) = extract_positioned_link_from_comment(position.offset, &comment)?; 36 let (attributes, def) = doc_attributes(&sema, &parent)?;
37 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 })?;
38 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)?;
39 return Some(RangeInfo::new(original_token.text_range(), vec![nav])); 46 return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
40 } 47 }
@@ -1160,4 +1167,25 @@ fn fn_macro() {}
1160 "#, 1167 "#,
1161 ) 1168 )
1162 } 1169 }
1170
1171 #[test]
1172 fn goto_intra_doc_links() {
1173 check(
1174 r#"
1175
1176pub 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
1185pub fn gimme() -> theitem::TheItem {
1186 theitem::TheItem
1187}
1188"#,
1189 );
1190 }
1163} 1191}