aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r--crates/ide/src/goto_definition.rs66
1 files changed, 8 insertions, 58 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 473d48c2f..a2c97061f 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,18 +1,14 @@
1use std::ops::Range;
2
3use either::Either; 1use either::Either;
4use hir::{HasAttrs, ModuleDef, Semantics}; 2use hir::Semantics;
5use ide_db::{ 3use ide_db::{
6 defs::{Definition, NameClass, NameRefClass}, 4 defs::{NameClass, NameRefClass},
7 RootDatabase, 5 RootDatabase,
8}; 6};
9use syntax::{ 7use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
10 ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, TextSize,
11 TokenAtOffset, T,
12};
13 8
14use crate::{ 9use crate::{
15 display::TryToNav, doc_links::extract_definitions_from_markdown, runnables::doc_owner_to_def, 10 display::TryToNav,
11 doc_links::{doc_owner_to_def, extract_positioned_link_from_comment, resolve_doc_path_for_def},
16 FilePosition, NavigationTarget, RangeInfo, 12 FilePosition, NavigationTarget, RangeInfo,
17}; 13};
18 14
@@ -35,7 +31,9 @@ pub(crate) fn goto_definition(
35 let token = sema.descend_into_macros(original_token.clone()); 31 let token = sema.descend_into_macros(original_token.clone());
36 let parent = token.parent()?; 32 let parent = token.parent()?;
37 if let Some(comment) = ast::Comment::cast(token) { 33 if let Some(comment) = ast::Comment::cast(token) {
38 let nav = def_for_doc_comment(&sema, position, &comment)?.try_to_nav(db)?; 34 let (_, link, ns) = extract_positioned_link_from_comment(position.offset, &comment)?;
35 let def = doc_owner_to_def(&sema, &parent)?;
36 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])); 37 return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
40 } 38 }
41 39
@@ -61,54 +59,6 @@ pub(crate) fn goto_definition(
61 Some(RangeInfo::new(original_token.text_range(), nav.into_iter().collect())) 59 Some(RangeInfo::new(original_token.text_range(), nav.into_iter().collect()))
62} 60}
63 61
64fn def_for_doc_comment(
65 sema: &Semantics<RootDatabase>,
66 position: FilePosition,
67 doc_comment: &ast::Comment,
68) -> Option<hir::ModuleDef> {
69 let parent = doc_comment.syntax().parent()?;
70 let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?;
71
72 let def = doc_owner_to_def(sema, parent)?;
73 match def {
74 Definition::ModuleDef(def) => match def {
75 ModuleDef::Module(it) => it.resolve_doc_path(sema.db, &link, ns),
76 ModuleDef::Function(it) => it.resolve_doc_path(sema.db, &link, ns),
77 ModuleDef::Adt(it) => it.resolve_doc_path(sema.db, &link, ns),
78 ModuleDef::Variant(it) => it.resolve_doc_path(sema.db, &link, ns),
79 ModuleDef::Const(it) => it.resolve_doc_path(sema.db, &link, ns),
80 ModuleDef::Static(it) => it.resolve_doc_path(sema.db, &link, ns),
81 ModuleDef::Trait(it) => it.resolve_doc_path(sema.db, &link, ns),
82 ModuleDef::TypeAlias(it) => it.resolve_doc_path(sema.db, &link, ns),
83 ModuleDef::BuiltinType(_) => return None,
84 },
85 Definition::Macro(it) => it.resolve_doc_path(sema.db, &link, ns),
86 Definition::Field(it) => it.resolve_doc_path(sema.db, &link, ns),
87 Definition::SelfType(_)
88 | Definition::Local(_)
89 | Definition::GenericParam(_)
90 | Definition::Label(_) => return None,
91 }
92}
93
94fn extract_positioned_link_from_comment(
95 position: FilePosition,
96 comment: &ast::Comment,
97) -> Option<(String, Option<hir::Namespace>)> {
98 let doc_comment = comment.doc_comment()?;
99 let comment_start =
100 comment.syntax().text_range().start() + TextSize::from(comment.prefix().len() as u32);
101 let def_links = extract_definitions_from_markdown(doc_comment);
102 let (def_link, ns, _) = def_links.into_iter().find(|&(_, _, Range { start, end })| {
103 TextRange::at(
104 comment_start + TextSize::from(start as u32),
105 TextSize::from((end - start) as u32),
106 )
107 .contains(position.offset)
108 })?;
109 Some((def_link, ns))
110}
111
112fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { 62fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
113 return tokens.max_by_key(priority); 63 return tokens.max_by_key(priority);
114 fn priority(n: &SyntaxToken) -> usize { 64 fn priority(n: &SyntaxToken) -> usize {