diff options
-rw-r--r-- | crates/ra_ide_api/src/display.rs | 5 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 149 | ||||
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 2 |
5 files changed, 86 insertions, 80 deletions
diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index 1b06abf94..0eef11464 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs | |||
@@ -5,7 +5,6 @@ mod function_signature; | |||
5 | mod navigation_target; | 5 | mod navigation_target; |
6 | mod structure; | 6 | mod structure; |
7 | 7 | ||
8 | use crate::db::RootDatabase; | ||
9 | use ra_syntax::{ast::{self, AstNode, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; | 8 | use ra_syntax::{ast::{self, AstNode, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; |
10 | 9 | ||
11 | pub use navigation_target::NavigationTarget; | 10 | pub use navigation_target::NavigationTarget; |
@@ -73,8 +72,8 @@ where | |||
73 | 72 | ||
74 | // FIXME: this should not really use navigation target. Rather, approximately | 73 | // FIXME: this should not really use navigation target. Rather, approximately |
75 | // resolved symbol should return a `DefId`. | 74 | // resolved symbol should return a `DefId`. |
76 | pub(crate) fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option<String> { | 75 | pub(crate) fn doc_text_for(nav: NavigationTarget) -> Option<String> { |
77 | match (nav.description(db), nav.docs(db)) { | 76 | match (nav.description, nav.docs) { |
78 | (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), | 77 | (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), |
79 | (None, Some(docs)) => Some(docs), | 78 | (None, Some(docs)) => Some(docs), |
80 | _ => None, | 79 | _ => None, |
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 45002d098..f8a7bd3ad 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_db::{FileId, SourceDatabase}; | 1 | use ra_db::{FileId, SourceDatabase}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | SyntaxNode, AstNode, SmolStr, TextRange, TreeArc, AstPtr, | 3 | SyntaxNode, AstNode, SmolStr, TextRange, AstPtr, |
4 | SyntaxKind::{self, NAME}, | 4 | SyntaxKind::{self, NAME}, |
5 | ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, | 5 | ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, |
6 | algo::visit::{visitor, Visitor}, | 6 | algo::visit::{visitor, Visitor}, |
@@ -22,6 +22,9 @@ pub struct NavigationTarget { | |||
22 | full_range: TextRange, | 22 | full_range: TextRange, |
23 | focus_range: Option<TextRange>, | 23 | focus_range: Option<TextRange>, |
24 | container_name: Option<SmolStr>, | 24 | container_name: Option<SmolStr>, |
25 | |||
26 | pub(crate) description: Option<String>, | ||
27 | pub(crate) docs: Option<String>, | ||
25 | } | 28 | } |
26 | 29 | ||
27 | impl NavigationTarget { | 30 | impl NavigationTarget { |
@@ -63,7 +66,10 @@ impl NavigationTarget { | |||
63 | NavigationTarget::from_named(file_id, pat) | 66 | NavigationTarget::from_named(file_id, pat) |
64 | } | 67 | } |
65 | 68 | ||
66 | pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget { | 69 | pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { |
70 | let file = db.parse(symbol.file_id).tree; | ||
71 | let node = symbol.ptr.to_node(file.syntax()).to_owned(); | ||
72 | |||
67 | NavigationTarget { | 73 | NavigationTarget { |
68 | file_id: symbol.file_id, | 74 | file_id: symbol.file_id, |
69 | name: symbol.name.clone(), | 75 | name: symbol.name.clone(), |
@@ -71,6 +77,8 @@ impl NavigationTarget { | |||
71 | full_range: symbol.ptr.range(), | 77 | full_range: symbol.ptr.range(), |
72 | focus_range: symbol.name_range, | 78 | focus_range: symbol.name_range, |
73 | container_name: symbol.container_name.clone(), | 79 | container_name: symbol.container_name.clone(), |
80 | description: description_inner(&node), | ||
81 | docs: docs_inner(&node), | ||
74 | } | 82 | } |
75 | } | 83 | } |
76 | 84 | ||
@@ -84,6 +92,8 @@ impl NavigationTarget { | |||
84 | ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat), | 92 | ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat), |
85 | _ => ("_".into(), pat.syntax_node_ptr().range()), | 93 | _ => ("_".into(), pat.syntax_node_ptr().range()), |
86 | }; | 94 | }; |
95 | let node = pat.to_node(file.syntax()).syntax().to_owned(); | ||
96 | |||
87 | NavigationTarget { | 97 | NavigationTarget { |
88 | file_id, | 98 | file_id, |
89 | name, | 99 | name, |
@@ -91,14 +101,20 @@ impl NavigationTarget { | |||
91 | focus_range: None, | 101 | focus_range: None, |
92 | kind: NAME, | 102 | kind: NAME, |
93 | container_name: None, | 103 | container_name: None, |
104 | description: description_inner(&node), | ||
105 | docs: docs_inner(&node), | ||
94 | } | 106 | } |
95 | } | 107 | } |
96 | 108 | ||
97 | pub(crate) fn from_self_param( | 109 | pub(crate) fn from_self_param( |
110 | db: &RootDatabase, | ||
98 | file_id: FileId, | 111 | file_id: FileId, |
99 | par: AstPtr<ast::SelfParam>, | 112 | par: AstPtr<ast::SelfParam>, |
100 | ) -> NavigationTarget { | 113 | ) -> NavigationTarget { |
101 | let (name, full_range) = ("self".into(), par.syntax_node_ptr().range()); | 114 | let (name, full_range) = ("self".into(), par.syntax_node_ptr().range()); |
115 | let file = db.parse(file_id).tree; | ||
116 | let node = par.to_node(file.syntax()).syntax().to_owned(); | ||
117 | |||
102 | NavigationTarget { | 118 | NavigationTarget { |
103 | file_id, | 119 | file_id, |
104 | name, | 120 | name, |
@@ -106,6 +122,8 @@ impl NavigationTarget { | |||
106 | focus_range: None, | 122 | focus_range: None, |
107 | kind: NAME, | 123 | kind: NAME, |
108 | container_name: None, | 124 | container_name: None, |
125 | description: description_inner(&node), | ||
126 | docs: docs_inner(&node), | ||
109 | } | 127 | } |
110 | } | 128 | } |
111 | 129 | ||
@@ -290,83 +308,72 @@ impl NavigationTarget { | |||
290 | focus_range, | 308 | focus_range, |
291 | // ptr: Some(LocalSyntaxPtr::new(node)), | 309 | // ptr: Some(LocalSyntaxPtr::new(node)), |
292 | container_name: None, | 310 | container_name: None, |
311 | description: description_inner(node), | ||
312 | docs: docs_inner(node), | ||
293 | } | 313 | } |
294 | } | 314 | } |
315 | } | ||
295 | 316 | ||
296 | pub(crate) fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> { | 317 | fn docs_inner(node: &SyntaxNode) -> Option<String> { |
297 | let source_file = db.parse(self.file_id()).tree; | 318 | fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> { |
298 | let source_file = source_file.syntax(); | 319 | node.doc_comment_text() |
299 | let node = source_file | ||
300 | .descendants() | ||
301 | .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? | ||
302 | .to_owned(); | ||
303 | Some(node) | ||
304 | } | ||
305 | |||
306 | pub(crate) fn docs(&self, db: &RootDatabase) -> Option<String> { | ||
307 | let node = self.node(db)?; | ||
308 | fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> { | ||
309 | node.doc_comment_text() | ||
310 | } | ||
311 | |||
312 | visitor() | ||
313 | .visit(doc_comments::<ast::FnDef>) | ||
314 | .visit(doc_comments::<ast::StructDef>) | ||
315 | .visit(doc_comments::<ast::EnumDef>) | ||
316 | .visit(doc_comments::<ast::TraitDef>) | ||
317 | .visit(doc_comments::<ast::Module>) | ||
318 | .visit(doc_comments::<ast::TypeAliasDef>) | ||
319 | .visit(doc_comments::<ast::ConstDef>) | ||
320 | .visit(doc_comments::<ast::StaticDef>) | ||
321 | .visit(doc_comments::<ast::NamedFieldDef>) | ||
322 | .visit(doc_comments::<ast::EnumVariant>) | ||
323 | .visit(doc_comments::<ast::MacroCall>) | ||
324 | .accept(&node)? | ||
325 | } | 320 | } |
326 | 321 | ||
327 | /// Get a description of this node. | 322 | visitor() |
328 | /// | 323 | .visit(doc_comments::<ast::FnDef>) |
329 | /// e.g. `struct Name`, `enum Name`, `fn Name` | 324 | .visit(doc_comments::<ast::StructDef>) |
330 | pub(crate) fn description(&self, db: &RootDatabase) -> Option<String> { | 325 | .visit(doc_comments::<ast::EnumDef>) |
331 | // FIXME: After type inference is done, add type information to improve the output | 326 | .visit(doc_comments::<ast::TraitDef>) |
332 | let node = self.node(db)?; | 327 | .visit(doc_comments::<ast::Module>) |
333 | 328 | .visit(doc_comments::<ast::TypeAliasDef>) | |
334 | fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> | 329 | .visit(doc_comments::<ast::ConstDef>) |
335 | where | 330 | .visit(doc_comments::<ast::StaticDef>) |
336 | T: NameOwner + VisibilityOwner + TypeAscriptionOwner, | 331 | .visit(doc_comments::<ast::NamedFieldDef>) |
337 | { | 332 | .visit(doc_comments::<ast::EnumVariant>) |
338 | let mut string = visit_node(node, prefix)?; | 333 | .visit(doc_comments::<ast::MacroCall>) |
339 | 334 | .accept(&node)? | |
340 | if let Some(type_ref) = node.ascribed_type() { | 335 | } |
341 | string.push_str(": "); | ||
342 | type_ref.syntax().text().push_to(&mut string); | ||
343 | } | ||
344 | 336 | ||
345 | Some(string) | 337 | /// Get a description of this node. |
338 | /// | ||
339 | /// e.g. `struct Name`, `enum Name`, `fn Name` | ||
340 | fn description_inner(node: &SyntaxNode) -> Option<String> { | ||
341 | // FIXME: After type inference is done, add type information to improve the output | ||
342 | fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> | ||
343 | where | ||
344 | T: NameOwner + VisibilityOwner + TypeAscriptionOwner, | ||
345 | { | ||
346 | let mut string = visit_node(node, prefix)?; | ||
347 | |||
348 | if let Some(type_ref) = node.ascribed_type() { | ||
349 | string.push_str(": "); | ||
350 | type_ref.syntax().text().push_to(&mut string); | ||
346 | } | 351 | } |
347 | 352 | ||
348 | fn visit_node<T>(node: &T, label: &str) -> Option<String> | 353 | Some(string) |
349 | where | 354 | } |
350 | T: NameOwner + VisibilityOwner, | ||
351 | { | ||
352 | let mut string = | ||
353 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); | ||
354 | string.push_str(label); | ||
355 | string.push_str(node.name()?.text().as_str()); | ||
356 | Some(string) | ||
357 | } | ||
358 | 355 | ||
359 | visitor() | 356 | fn visit_node<T>(node: &T, label: &str) -> Option<String> |
360 | .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) | 357 | where |
361 | .visit(|node: &ast::StructDef| visit_node(node, "struct ")) | 358 | T: NameOwner + VisibilityOwner, |
362 | .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) | 359 | { |
363 | .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) | 360 | let mut string = |
364 | .visit(|node: &ast::Module| visit_node(node, "mod ")) | 361 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); |
365 | .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) | 362 | string.push_str(label); |
366 | .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) | 363 | string.push_str(node.name()?.text().as_str()); |
367 | .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) | 364 | Some(string) |
368 | .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) | ||
369 | .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) | ||
370 | .accept(&node)? | ||
371 | } | 365 | } |
366 | |||
367 | visitor() | ||
368 | .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) | ||
369 | .visit(|node: &ast::StructDef| visit_node(node, "struct ")) | ||
370 | .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) | ||
371 | .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) | ||
372 | .visit(|node: &ast::Module| visit_node(node, "mod ")) | ||
373 | .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) | ||
374 | .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) | ||
375 | .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) | ||
376 | .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) | ||
377 | .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) | ||
378 | .accept(&node)? | ||
372 | } | 379 | } |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index e72b7a6e7..31b6679ae 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -72,7 +72,7 @@ pub(crate) fn reference_definition( | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | Some(Pat(pat)) => return Exact(NavigationTarget::from_pat(db, file_id, pat)), | 74 | Some(Pat(pat)) => return Exact(NavigationTarget::from_pat(db, file_id, pat)), |
75 | Some(SelfParam(par)) => return Exact(NavigationTarget::from_self_param(file_id, par)), | 75 | Some(SelfParam(par)) => return Exact(NavigationTarget::from_self_param(db, file_id, par)), |
76 | Some(GenericParam(_)) => { | 76 | Some(GenericParam(_)) => { |
77 | // FIXME: go to the generic param def | 77 | // FIXME: go to the generic param def |
78 | } | 78 | } |
@@ -82,7 +82,7 @@ pub(crate) fn reference_definition( | |||
82 | // Fallback index based approach: | 82 | // Fallback index based approach: |
83 | let navs = crate::symbol_index::index_resolve(db, name_ref) | 83 | let navs = crate::symbol_index::index_resolve(db, name_ref) |
84 | .into_iter() | 84 | .into_iter() |
85 | .map(NavigationTarget::from_symbol) | 85 | .map(|s| NavigationTarget::from_symbol(db, s)) |
86 | .collect(); | 86 | .collect(); |
87 | Approximate(navs) | 87 | Approximate(navs) |
88 | } | 88 | } |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index f56965ef5..cb676eb12 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -86,13 +86,13 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
86 | use crate::goto_definition::{ReferenceResult::*, reference_definition}; | 86 | use crate::goto_definition::{ReferenceResult::*, reference_definition}; |
87 | let ref_result = reference_definition(db, position.file_id, name_ref); | 87 | let ref_result = reference_definition(db, position.file_id, name_ref); |
88 | match ref_result { | 88 | match ref_result { |
89 | Exact(nav) => res.extend(doc_text_for(db, nav)), | 89 | Exact(nav) => res.extend(doc_text_for(nav)), |
90 | Approximate(navs) => { | 90 | Approximate(navs) => { |
91 | // We are no longer exact | 91 | // We are no longer exact |
92 | res.exact = false; | 92 | res.exact = false; |
93 | 93 | ||
94 | for nav in navs { | 94 | for nav in navs { |
95 | res.extend(doc_text_for(db, nav)) | 95 | res.extend(doc_text_for(nav)) |
96 | } | 96 | } |
97 | } | 97 | } |
98 | } | 98 | } |
@@ -104,7 +104,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
104 | 104 | ||
105 | if let Some(navs) = navs { | 105 | if let Some(navs) = navs { |
106 | for nav in navs { | 106 | for nav in navs { |
107 | res.extend(doc_text_for(db, nav)) | 107 | res.extend(doc_text_for(nav)) |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 2fe46cd13..dbebf50a6 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -393,7 +393,7 @@ impl Analysis { | |||
393 | self.with_db(|db| { | 393 | self.with_db(|db| { |
394 | symbol_index::world_symbols(db, query) | 394 | symbol_index::world_symbols(db, query) |
395 | .into_iter() | 395 | .into_iter() |
396 | .map(NavigationTarget::from_symbol) | 396 | .map(|s| NavigationTarget::from_symbol(db, s)) |
397 | .collect::<Vec<_>>() | 397 | .collect::<Vec<_>>() |
398 | }) | 398 | }) |
399 | } | 399 | } |