diff options
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
-rw-r--r-- | crates/ide/src/goto_definition.rs | 66 |
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 @@ | |||
1 | use std::ops::Range; | ||
2 | |||
3 | use either::Either; | 1 | use either::Either; |
4 | use hir::{HasAttrs, ModuleDef, Semantics}; | 2 | use hir::Semantics; |
5 | use ide_db::{ | 3 | use ide_db::{ |
6 | defs::{Definition, NameClass, NameRefClass}, | 4 | defs::{NameClass, NameRefClass}, |
7 | RootDatabase, | 5 | RootDatabase, |
8 | }; | 6 | }; |
9 | use syntax::{ | 7 | use 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 | ||
14 | use crate::{ | 9 | use 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 | ||
64 | fn 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 | |||
94 | fn 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 | |||
112 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | 62 | fn 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 { |