diff options
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index f6d7f3192..3c518faf5 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -1,7 +1,9 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::{FileId, SourceDatabase}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast, | 3 | SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, TreeArc, |
4 | SyntaxKind::{self, NAME}, | 4 | SyntaxKind::{self, NAME}, |
5 | ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, | ||
6 | algo::visit::{visitor, Visitor}, | ||
5 | }; | 7 | }; |
6 | use hir::{ModuleSource, FieldSource, Name, ImplItem}; | 8 | use hir::{ModuleSource, FieldSource, Name, ImplItem}; |
7 | 9 | ||
@@ -248,4 +250,80 @@ impl NavigationTarget { | |||
248 | container_name: None, | 250 | container_name: None, |
249 | } | 251 | } |
250 | } | 252 | } |
253 | |||
254 | pub(crate) fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> { | ||
255 | let source_file = db.parse(self.file_id()); | ||
256 | let source_file = source_file.syntax(); | ||
257 | let node = source_file | ||
258 | .descendants() | ||
259 | .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? | ||
260 | .to_owned(); | ||
261 | Some(node) | ||
262 | } | ||
263 | |||
264 | pub(crate) fn docs(&self, db: &RootDatabase) -> Option<String> { | ||
265 | let node = self.node(db)?; | ||
266 | fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> { | ||
267 | node.doc_comment_text() | ||
268 | } | ||
269 | |||
270 | visitor() | ||
271 | .visit(doc_comments::<ast::FnDef>) | ||
272 | .visit(doc_comments::<ast::StructDef>) | ||
273 | .visit(doc_comments::<ast::EnumDef>) | ||
274 | .visit(doc_comments::<ast::TraitDef>) | ||
275 | .visit(doc_comments::<ast::Module>) | ||
276 | .visit(doc_comments::<ast::TypeAliasDef>) | ||
277 | .visit(doc_comments::<ast::ConstDef>) | ||
278 | .visit(doc_comments::<ast::StaticDef>) | ||
279 | .visit(doc_comments::<ast::NamedFieldDef>) | ||
280 | .visit(doc_comments::<ast::EnumVariant>) | ||
281 | .accept(&node)? | ||
282 | } | ||
283 | |||
284 | /// Get a description of this node. | ||
285 | /// | ||
286 | /// e.g. `struct Name`, `enum Name`, `fn Name` | ||
287 | pub(crate) fn description(&self, db: &RootDatabase) -> Option<String> { | ||
288 | // FIXME: After type inference is done, add type information to improve the output | ||
289 | let node = self.node(db)?; | ||
290 | |||
291 | fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> | ||
292 | where | ||
293 | T: NameOwner + VisibilityOwner + TypeAscriptionOwner, | ||
294 | { | ||
295 | let mut string = visit_node(node, prefix)?; | ||
296 | |||
297 | if let Some(type_ref) = node.ascribed_type() { | ||
298 | string.push_str(": "); | ||
299 | type_ref.syntax().text().push_to(&mut string); | ||
300 | } | ||
301 | |||
302 | Some(string) | ||
303 | } | ||
304 | |||
305 | fn visit_node<T>(node: &T, label: &str) -> Option<String> | ||
306 | where | ||
307 | T: NameOwner + VisibilityOwner, | ||
308 | { | ||
309 | let mut string = | ||
310 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); | ||
311 | string.push_str(label); | ||
312 | string.push_str(node.name()?.text().as_str()); | ||
313 | Some(string) | ||
314 | } | ||
315 | |||
316 | visitor() | ||
317 | .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) | ||
318 | .visit(|node: &ast::StructDef| visit_node(node, "struct ")) | ||
319 | .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) | ||
320 | .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) | ||
321 | .visit(|node: &ast::Module| visit_node(node, "mod ")) | ||
322 | .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) | ||
323 | .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) | ||
324 | .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) | ||
325 | .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) | ||
326 | .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) | ||
327 | .accept(&node)? | ||
328 | } | ||
251 | } | 329 | } |