From 07f0069f342afa17536aa4b9db4250f4d6c83954 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Tue, 9 Apr 2019 14:43:11 +0300 Subject: Move display related things from hover to display --- crates/ra_ide_api/src/display/navigation_target.rs | 82 +++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide_api/src/display') 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 @@ -use ra_db::FileId; +use ra_db::{FileId, SourceDatabase}; use ra_syntax::{ - SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast, + SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, TreeArc, SyntaxKind::{self, NAME}, + ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, + algo::visit::{visitor, Visitor}, }; use hir::{ModuleSource, FieldSource, Name, ImplItem}; @@ -248,4 +250,80 @@ impl NavigationTarget { container_name: None, } } + + pub(crate) fn node(&self, db: &RootDatabase) -> Option> { + let source_file = db.parse(self.file_id()); + let source_file = source_file.syntax(); + let node = source_file + .descendants() + .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? + .to_owned(); + Some(node) + } + + pub(crate) fn docs(&self, db: &RootDatabase) -> Option { + let node = self.node(db)?; + fn doc_comments(node: &N) -> Option { + node.doc_comment_text() + } + + visitor() + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .accept(&node)? + } + + /// Get a description of this node. + /// + /// e.g. `struct Name`, `enum Name`, `fn Name` + pub(crate) fn description(&self, db: &RootDatabase) -> Option { + // FIXME: After type inference is done, add type information to improve the output + let node = self.node(db)?; + + fn visit_ascribed_node(node: &T, prefix: &str) -> Option + where + T: NameOwner + VisibilityOwner + TypeAscriptionOwner, + { + let mut string = visit_node(node, prefix)?; + + if let Some(type_ref) = node.ascribed_type() { + string.push_str(": "); + type_ref.syntax().text().push_to(&mut string); + } + + Some(string) + } + + fn visit_node(node: &T, label: &str) -> Option + where + T: NameOwner + VisibilityOwner, + { + let mut string = + node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); + string.push_str(label); + string.push_str(node.name()?.text().as_str()); + Some(string) + } + + visitor() + .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) + .visit(|node: &ast::StructDef| visit_node(node, "struct ")) + .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) + .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) + .visit(|node: &ast::Module| visit_node(node, "mod ")) + .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) + .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) + .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) + .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) + .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) + .accept(&node)? + } } -- cgit v1.2.3