aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/diagnostics.rs1
-rw-r--r--crates/ide/src/doc_links.rs63
-rw-r--r--crates/ide/src/folding_ranges.rs39
-rw-r--r--crates/ide/src/goto_definition.rs15
-rw-r--r--crates/ide/src/hover.rs1
-rw-r--r--crates/ide/src/move_item.rs268
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs32
7 files changed, 345 insertions, 74 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index 22697a537..dd42116a7 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -165,7 +165,6 @@ pub(crate) fn diagnostics(
165 sema.diagnostics_display_range(d.display_source()).range, 165 sema.diagnostics_display_range(d.display_source()).range,
166 d.message(), 166 d.message(),
167 ) 167 )
168 .with_unused(true)
169 .with_fix(d.fix(&sema)) 168 .with_fix(d.fix(&sema))
170 .with_code(Some(d.code())), 169 .with_code(Some(d.code())),
171 ); 170 );
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 4a9e8b21c..67e2e5a1c 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -98,6 +98,29 @@ pub(crate) fn remove_links(markdown: &str) -> String {
98 out 98 out
99} 99}
100 100
101/// Retrieve a link to documentation for the given symbol.
102pub(crate) fn external_docs(
103 db: &RootDatabase,
104 position: &FilePosition,
105) -> Option<DocumentationLink> {
106 let sema = Semantics::new(db);
107 let file = sema.parse(position.file_id).syntax().clone();
108 let token = pick_best(file.token_at_offset(position.offset))?;
109 let token = sema.descend_into_macros(token);
110
111 let node = token.parent()?;
112 let definition = match_ast! {
113 match node {
114 ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
115 ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)),
116 _ => None,
117 }
118 };
119
120 get_doc_link(db, definition?)
121}
122
123/// Extracts all links from a given markdown text.
101pub(crate) fn extract_definitions_from_markdown( 124pub(crate) fn extract_definitions_from_markdown(
102 markdown: &str, 125 markdown: &str,
103) -> Vec<(Range<usize>, String, Option<hir::Namespace>)> { 126) -> Vec<(Range<usize>, String, Option<hir::Namespace>)> {
@@ -178,15 +201,15 @@ pub(crate) fn resolve_doc_path_for_def(
178) -> Option<hir::ModuleDef> { 201) -> Option<hir::ModuleDef> {
179 match def { 202 match def {
180 Definition::ModuleDef(def) => match def { 203 Definition::ModuleDef(def) => match def {
181 ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns), 204 hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
182 ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns), 205 hir::ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
183 ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns), 206 hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
184 ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns), 207 hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
185 ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns), 208 hir::ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
186 ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns), 209 hir::ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
187 ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns), 210 hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
188 ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns), 211 hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
189 ModuleDef::BuiltinType(_) => None, 212 hir::ModuleDef::BuiltinType(_) => None,
190 }, 213 },
191 Definition::Macro(it) => it.resolve_doc_path(db, &link, ns), 214 Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
192 Definition::Field(it) => it.resolve_doc_path(db, &link, ns), 215 Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
@@ -328,28 +351,6 @@ fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option<S
328 .map(|url| url.into_string()) 351 .map(|url| url.into_string())
329} 352}
330 353
331/// Retrieve a link to documentation for the given symbol.
332pub(crate) fn external_docs(
333 db: &RootDatabase,
334 position: &FilePosition,
335) -> Option<DocumentationLink> {
336 let sema = Semantics::new(db);
337 let file = sema.parse(position.file_id).syntax().clone();
338 let token = pick_best(file.token_at_offset(position.offset))?;
339 let token = sema.descend_into_macros(token);
340
341 let node = token.parent()?;
342 let definition = match_ast! {
343 match node {
344 ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
345 ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)),
346 _ => None,
347 }
348 };
349
350 get_doc_link(db, definition?)
351}
352
353/// Rewrites a markdown document, applying 'callback' to each link. 354/// Rewrites a markdown document, applying 'callback' to each link.
354fn map_links<'e>( 355fn map_links<'e>(
355 events: impl Iterator<Item = Event<'e>>, 356 events: impl Iterator<Item = Event<'e>>,
diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs
index 4b1b24562..153726ce8 100644
--- a/crates/ide/src/folding_ranges.rs
+++ b/crates/ide/src/folding_ranges.rs
@@ -17,6 +17,8 @@ pub enum FoldKind {
17 Block, 17 Block,
18 ArgList, 18 ArgList,
19 Region, 19 Region,
20 Consts,
21 Statics,
20} 22}
21 23
22#[derive(Debug)] 24#[derive(Debug)]
@@ -30,6 +32,8 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
30 let mut visited_comments = FxHashSet::default(); 32 let mut visited_comments = FxHashSet::default();
31 let mut visited_imports = FxHashSet::default(); 33 let mut visited_imports = FxHashSet::default();
32 let mut visited_mods = FxHashSet::default(); 34 let mut visited_mods = FxHashSet::default();
35 let mut visited_consts = FxHashSet::default();
36 let mut visited_statics = FxHashSet::default();
33 // regions can be nested, here is a LIFO buffer 37 // regions can be nested, here is a LIFO buffer
34 let mut regions_starts: Vec<TextSize> = vec![]; 38 let mut regions_starts: Vec<TextSize> = vec![];
35 39
@@ -91,6 +95,19 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
91 res.push(Fold { range, kind: FoldKind::Mods }) 95 res.push(Fold { range, kind: FoldKind::Mods })
92 } 96 }
93 } 97 }
98
99 // Fold groups of consts
100 if node.kind() == CONST && !visited_consts.contains(&node) {
101 if let Some(range) = contiguous_range_for_group(&node, &mut visited_consts) {
102 res.push(Fold { range, kind: FoldKind::Consts })
103 }
104 }
105 // Fold groups of consts
106 if node.kind() == STATIC && !visited_statics.contains(&node) {
107 if let Some(range) = contiguous_range_for_group(&node, &mut visited_statics) {
108 res.push(Fold { range, kind: FoldKind::Statics })
109 }
110 }
94 } 111 }
95 } 112 }
96 } 113 }
@@ -250,6 +267,8 @@ mod tests {
250 FoldKind::Block => "block", 267 FoldKind::Block => "block",
251 FoldKind::ArgList => "arglist", 268 FoldKind::ArgList => "arglist",
252 FoldKind::Region => "region", 269 FoldKind::Region => "region",
270 FoldKind::Consts => "consts",
271 FoldKind::Statics => "statics",
253 }; 272 };
254 assert_eq!(kind, &attr.unwrap()); 273 assert_eq!(kind, &attr.unwrap());
255 } 274 }
@@ -457,4 +476,24 @@ calling_function(x,y);
457"#, 476"#,
458 ) 477 )
459 } 478 }
479
480 #[test]
481 fn fold_consecutive_const() {
482 check(
483 r#"
484<fold consts>const FIRST_CONST: &str = "first";
485const SECOND_CONST: &str = "second";</fold>
486 "#,
487 )
488 }
489
490 #[test]
491 fn fold_consecutive_static() {
492 check(
493 r#"
494<fold statics>static FIRST_STATIC: &str = "first";
495static SECOND_STATIC: &str = "second";</fold>
496 "#,
497 )
498 }
460} 499}
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index a2c97061f..c6556c487 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -918,6 +918,21 @@ fn f() -> impl Iterator<Item$0 = u8> {}
918 } 918 }
919 919
920 #[test] 920 #[test]
921 #[should_panic = "unresolved reference"]
922 fn unknown_assoc_ty() {
923 check(
924 r#"
925trait Iterator {
926 type Item;
927 //^^^^
928}
929
930fn f() -> impl Iterator<Invalid$0 = u8> {}
931 "#,
932 )
933 }
934
935 #[test]
921 fn goto_def_for_assoc_ty_in_path_multiple() { 936 fn goto_def_for_assoc_ty_in_path_multiple() {
922 check( 937 check(
923 r#" 938 r#"
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index dfd32c8c1..7e35a1450 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -470,6 +470,7 @@ fn find_std_module(famous_defs: &FamousDefs, name: &str) -> Option<hir::Module>
470 470
471fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { 471fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
472 return tokens.max_by_key(priority); 472 return tokens.max_by_key(priority);
473
473 fn priority(n: &SyntaxToken) -> usize { 474 fn priority(n: &SyntaxToken) -> usize {
474 match n.kind() { 475 match n.kind() {
475 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] => 3, 476 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] => 3,
diff --git a/crates/ide/src/move_item.rs b/crates/ide/src/move_item.rs
index 05fa8fc13..d36dcd4e4 100644
--- a/crates/ide/src/move_item.rs
+++ b/crates/ide/src/move_item.rs
@@ -4,10 +4,12 @@ use hir::Semantics;
4use ide_db::{base_db::FileRange, RootDatabase}; 4use ide_db::{base_db::FileRange, RootDatabase};
5use itertools::Itertools; 5use itertools::Itertools;
6use syntax::{ 6use syntax::{
7 algo, ast, match_ast, AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, 7 algo, ast, match_ast, AstNode, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange,
8 TokenAtOffset,
8}; 9};
9use text_edit::{TextEdit, TextEditBuilder}; 10use text_edit::{TextEdit, TextEditBuilder};
10 11
12#[derive(Copy, Clone, Debug)]
11pub enum Direction { 13pub enum Direction {
12 Up, 14 Up,
13 Down, 15 Down,
@@ -31,14 +33,19 @@ pub(crate) fn move_item(
31 let sema = Semantics::new(db); 33 let sema = Semantics::new(db);
32 let file = sema.parse(range.file_id); 34 let file = sema.parse(range.file_id);
33 35
34 let item = file.syntax().covering_element(range.range); 36 let item = if range.range.is_empty() {
37 SyntaxElement::Token(pick_best(file.syntax().token_at_offset(range.range.start()))?)
38 } else {
39 file.syntax().covering_element(range.range)
40 };
41
35 find_ancestors(item, direction, range.range) 42 find_ancestors(item, direction, range.range)
36} 43}
37 44
38fn find_ancestors(item: SyntaxElement, direction: Direction, range: TextRange) -> Option<TextEdit> { 45fn find_ancestors(item: SyntaxElement, direction: Direction, range: TextRange) -> Option<TextEdit> {
39 let root = match item { 46 let root = match item {
40 NodeOrToken::Node(node) => node, 47 SyntaxElement::Node(node) => node,
41 NodeOrToken::Token(token) => token.parent()?, 48 SyntaxElement::Token(token) => token.parent()?,
42 }; 49 };
43 50
44 let movable = [ 51 let movable = [
@@ -51,6 +58,11 @@ fn find_ancestors(item: SyntaxElement, direction: Direction, range: TextRange) -
51 SyntaxKind::PARAM, 58 SyntaxKind::PARAM,
52 SyntaxKind::LET_STMT, 59 SyntaxKind::LET_STMT,
53 SyntaxKind::EXPR_STMT, 60 SyntaxKind::EXPR_STMT,
61 SyntaxKind::IF_EXPR,
62 SyntaxKind::FOR_EXPR,
63 SyntaxKind::LOOP_EXPR,
64 SyntaxKind::WHILE_EXPR,
65 SyntaxKind::RETURN_EXPR,
54 SyntaxKind::MATCH_EXPR, 66 SyntaxKind::MATCH_EXPR,
55 SyntaxKind::MACRO_CALL, 67 SyntaxKind::MACRO_CALL,
56 SyntaxKind::TYPE_ALIAS, 68 SyntaxKind::TYPE_ALIAS,
@@ -83,11 +95,11 @@ fn move_in_direction(
83) -> Option<TextEdit> { 95) -> Option<TextEdit> {
84 match_ast! { 96 match_ast! {
85 match node { 97 match node {
86 ast::ArgList(it) => swap_sibling_in_list(it.args(), range, direction), 98 ast::ArgList(it) => swap_sibling_in_list(node, it.args(), range, direction),
87 ast::GenericParamList(it) => swap_sibling_in_list(it.generic_params(), range, direction), 99 ast::GenericParamList(it) => swap_sibling_in_list(node, it.generic_params(), range, direction),
88 ast::GenericArgList(it) => swap_sibling_in_list(it.generic_args(), range, direction), 100 ast::GenericArgList(it) => swap_sibling_in_list(node, it.generic_args(), range, direction),
89 ast::VariantList(it) => swap_sibling_in_list(it.variants(), range, direction), 101 ast::VariantList(it) => swap_sibling_in_list(node, it.variants(), range, direction),
90 ast::TypeBoundList(it) => swap_sibling_in_list(it.bounds(), range, direction), 102 ast::TypeBoundList(it) => swap_sibling_in_list(node, it.bounds(), range, direction),
91 _ => Some(replace_nodes(node, &match direction { 103 _ => Some(replace_nodes(node, &match direction {
92 Direction::Up => node.prev_sibling(), 104 Direction::Up => node.prev_sibling(),
93 Direction::Down => node.next_sibling(), 105 Direction::Down => node.next_sibling(),
@@ -97,19 +109,27 @@ fn move_in_direction(
97} 109}
98 110
99fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>( 111fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>(
112 node: &SyntaxNode,
100 list: I, 113 list: I,
101 range: TextRange, 114 range: TextRange,
102 direction: Direction, 115 direction: Direction,
103) -> Option<TextEdit> { 116) -> Option<TextEdit> {
104 let (l, r) = list 117 let list_lookup = list
105 .tuple_windows() 118 .tuple_windows()
106 .filter(|(l, r)| match direction { 119 .filter(|(l, r)| match direction {
107 Direction::Up => r.syntax().text_range().contains_range(range), 120 Direction::Up => r.syntax().text_range().contains_range(range),
108 Direction::Down => l.syntax().text_range().contains_range(range), 121 Direction::Down => l.syntax().text_range().contains_range(range),
109 }) 122 })
110 .next()?; 123 .next();
111 124
112 Some(replace_nodes(l.syntax(), r.syntax())) 125 if let Some((l, r)) = list_lookup {
126 Some(replace_nodes(l.syntax(), r.syntax()))
127 } else {
128 // Cursor is beyond any movable list item (for example, on curly brace in enum).
129 // It's not necessary, that parent of list is movable (arg list's parent is not, for example),
130 // and we have to continue tree traversal to find suitable node.
131 find_ancestors(SyntaxElement::Node(node.parent()?), direction, range)
132 }
113} 133}
114 134
115fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit { 135fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit {
@@ -121,6 +141,18 @@ fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit {
121 edit.finish() 141 edit.finish()
122} 142}
123 143
144fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
145 return tokens.max_by_key(priority);
146
147 fn priority(n: &SyntaxToken) -> usize {
148 match n.kind() {
149 SyntaxKind::IDENT | SyntaxKind::LIFETIME_IDENT => 2,
150 kind if kind.is_trivia() => 0,
151 _ => 1,
152 }
153 }
154}
155
124#[cfg(test)] 156#[cfg(test)]
125mod tests { 157mod tests {
126 use crate::fixture; 158 use crate::fixture;
@@ -265,6 +297,107 @@ fn main() {
265 "#]], 297 "#]],
266 Direction::Up, 298 Direction::Up,
267 ); 299 );
300 check(
301 r#"
302fn main() {
303 println!("Hello, world");
304
305 if true {
306 println!("Test");
307 }$0$0
308}
309 "#,
310 expect![[r#"
311fn main() {
312 if true {
313 println!("Test");
314 }
315
316 println!("Hello, world");
317}
318 "#]],
319 Direction::Up,
320 );
321 check(
322 r#"
323fn main() {
324 println!("Hello, world");
325
326 for i in 0..10 {
327 println!("Test");
328 }$0$0
329}
330 "#,
331 expect![[r#"
332fn main() {
333 for i in 0..10 {
334 println!("Test");
335 }
336
337 println!("Hello, world");
338}
339 "#]],
340 Direction::Up,
341 );
342 check(
343 r#"
344fn main() {
345 println!("Hello, world");
346
347 loop {
348 println!("Test");
349 }$0$0
350}
351 "#,
352 expect![[r#"
353fn main() {
354 loop {
355 println!("Test");
356 }
357
358 println!("Hello, world");
359}
360 "#]],
361 Direction::Up,
362 );
363 check(
364 r#"
365fn main() {
366 println!("Hello, world");
367
368 while true {
369 println!("Test");
370 }$0$0
371}
372 "#,
373 expect![[r#"
374fn main() {
375 while true {
376 println!("Test");
377 }
378
379 println!("Hello, world");
380}
381 "#]],
382 Direction::Up,
383 );
384 check(
385 r#"
386fn main() {
387 println!("Hello, world");
388
389 return 123;$0$0
390}
391 "#,
392 expect![[r#"
393fn main() {
394 return 123;
395
396 println!("Hello, world");
397}
398 "#]],
399 Direction::Up,
400 );
268 } 401 }
269 402
270 #[test] 403 #[test]
@@ -615,6 +748,115 @@ fn test() {
615 } 748 }
616 749
617 #[test] 750 #[test]
751 fn test_cursor_at_item_start() {
752 check(
753 r#"
754$0$0#[derive(Debug)]
755enum FooBar {
756 Foo,
757 Bar,
758}
759
760fn main() {}
761 "#,
762 expect![[r#"
763fn main() {}
764
765#[derive(Debug)]
766enum FooBar {
767 Foo,
768 Bar,
769}
770 "#]],
771 Direction::Down,
772 );
773 check(
774 r#"
775$0$0enum FooBar {
776 Foo,
777 Bar,
778}
779
780fn main() {}
781 "#,
782 expect![[r#"
783fn main() {}
784
785enum FooBar {
786 Foo,
787 Bar,
788}
789 "#]],
790 Direction::Down,
791 );
792 check(
793 r#"
794struct Test;
795
796trait SomeTrait {}
797
798$0$0impl SomeTrait for Test {}
799
800fn main() {}
801 "#,
802 expect![[r#"
803struct Test;
804
805impl SomeTrait for Test {}
806
807trait SomeTrait {}
808
809fn main() {}
810 "#]],
811 Direction::Up,
812 );
813 }
814
815 #[test]
816 fn test_cursor_at_item_end() {
817 check(
818 r#"
819enum FooBar {
820 Foo,
821 Bar,
822}$0$0
823
824fn main() {}
825 "#,
826 expect![[r#"
827fn main() {}
828
829enum FooBar {
830 Foo,
831 Bar,
832}
833 "#]],
834 Direction::Down,
835 );
836 check(
837 r#"
838struct Test;
839
840trait SomeTrait {}
841
842impl SomeTrait for Test {}$0$0
843
844fn main() {}
845 "#,
846 expect![[r#"
847struct Test;
848
849impl SomeTrait for Test {}
850
851trait SomeTrait {}
852
853fn main() {}
854 "#]],
855 Direction::Up,
856 );
857 }
858
859 #[test]
618 fn handles_empty_file() { 860 fn handles_empty_file() {
619 check(r#"$0$0"#, expect![[r#""#]], Direction::Up); 861 check(r#"$0$0"#, expect![[r#""#]], Direction::Up);
620 } 862 }
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 963c3fb59..b62d43256 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -11,7 +11,8 @@ use syntax::{
11}; 11};
12 12
13use crate::{ 13use crate::{
14 doc_links::extract_definitions_from_markdown, Analysis, HlMod, HlRange, HlTag, RootDatabase, 14 doc_links::{extract_definitions_from_markdown, resolve_doc_path_for_def},
15 Analysis, HlMod, HlRange, HlTag, RootDatabase,
15}; 16};
16 17
17use super::{highlights::Highlights, injector::Injector}; 18use super::{highlights::Highlights, injector::Injector};
@@ -190,7 +191,7 @@ pub(super) fn doc_comment(
190 extract_definitions_from_markdown(line) 191 extract_definitions_from_markdown(line)
191 .into_iter() 192 .into_iter()
192 .filter_map(|(range, link, ns)| { 193 .filter_map(|(range, link, ns)| {
193 Some(range).zip(validate_intra_doc_link(sema.db, &def, &link, ns)) 194 Some(range).zip(resolve_doc_path_for_def(sema.db, def, &link, ns))
194 }) 195 })
195 .map(|(Range { start, end }, def)| { 196 .map(|(Range { start, end }, def)| {
196 ( 197 (
@@ -283,33 +284,6 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
283 } 284 }
284} 285}
285 286
286fn validate_intra_doc_link(
287 db: &RootDatabase,
288 def: &Definition,
289 link: &str,
290 ns: Option<hir::Namespace>,
291) -> Option<hir::ModuleDef> {
292 match def {
293 Definition::ModuleDef(def) => match def {
294 hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
295 hir::ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
296 hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
297 hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
298 hir::ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
299 hir::ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
300 hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
301 hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
302 hir::ModuleDef::BuiltinType(_) => None,
303 },
304 Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
305 Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
306 Definition::SelfType(_)
307 | Definition::Local(_)
308 | Definition::GenericParam(_)
309 | Definition::Label(_) => None,
310 }
311}
312
313fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag { 287fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag {
314 let symbol = match def { 288 let symbol = match def {
315 hir::ModuleDef::Module(_) => SymbolKind::Module, 289 hir::ModuleDef::Module(_) => SymbolKind::Module,