From f534d2132b90fca8c0646cc81f8a60fa20423fe1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 2 Jan 2019 22:38:52 +0300 Subject: move some logic to navigation target --- crates/ra_analysis/src/imp.rs | 124 ++++++++++++++++++++++++++++----- crates/ra_analysis/src/lib.rs | 25 +++++-- crates/ra_analysis/src/symbol_index.rs | 91 ++---------------------- 3 files changed, 127 insertions(+), 113 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index ff13247de..5f67c95f6 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -8,11 +8,11 @@ use hir::{ use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; use ra_editor::{self, find_node_at_offset, LocalEdit, Severity}; use ra_syntax::{ - algo::find_covering_node, + algo::{find_covering_node, visit::{visitor, Visitor}}, ast::{self, ArgListOwner, Expr, FnDef, NameOwner}, AstNode, SourceFileNode, SyntaxKind::*, - SyntaxNodeRef, TextRange, TextUnit, + SyntaxNode, SyntaxNodeRef, TextRange, TextUnit, }; use crate::{ @@ -116,12 +116,12 @@ impl db::RootDatabase { }; let decl = decl.borrowed(); let decl_name = decl.name().unwrap(); - let symbol = FileSymbol { + Ok(vec![NavigationTarget { + file_id, name: decl_name.text(), - node_range: decl_name.syntax().range(), + range: decl_name.syntax().range(), kind: MODULE, - }; - Ok(vec![NavigationTarget { file_id, symbol }]) + }]) } /// Returns `Vec` for the same reason as `parent_module` pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable> { @@ -153,14 +153,12 @@ impl db::RootDatabase { let scope = fn_descr.scopes(self); // First try to resolve the symbol locally if let Some(entry) = scope.resolve_local_name(name_ref) { - rr.add_resolution( - position.file_id, - FileSymbol { - name: entry.name().to_string().into(), - node_range: entry.ptr().range(), - kind: NAME, - }, - ); + rr.resolves_to.push(NavigationTarget { + file_id: position.file_id, + name: entry.name().to_string().into(), + range: entry.ptr().range(), + kind: NAME, + }); return Ok(Some(rr)); }; } @@ -182,12 +180,13 @@ impl db::RootDatabase { Some(name) => name.to_string().into(), None => "".into(), }; - let symbol = FileSymbol { + let symbol = NavigationTarget { + file_id, name, - node_range: TextRange::offset_len(0.into(), 0.into()), + range: TextRange::offset_len(0.into(), 0.into()), kind: MODULE, }; - rr.add_resolution(file_id, symbol); + rr.resolves_to.push(symbol); return Ok(Some(rr)); } } @@ -253,8 +252,7 @@ impl db::RootDatabase { } } pub(crate) fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable> { - let file = self.source_file(nav.file_id); - let result = match (nav.symbol.description(&file), nav.symbol.docs(&file)) { + let result = match (nav.description(self), nav.docs(self)) { (Some(desc), Some(docs)) => { Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs) } @@ -511,3 +509,91 @@ impl<'a> FnCallNode<'a> { } } } + +impl NavigationTarget { + fn node(&self, db: &db::RootDatabase) -> Option { + let source_file = db.source_file(self.file_id); + let source_file = source_file.syntax(); + let node = source_file + .descendants() + .find(|node| node.kind() == self.kind && node.range() == self.range)? + .owned(); + Some(node) + } + + fn docs(&self, db: &db::RootDatabase) -> Option { + let node = self.node(db)?; + let node = node.borrowed(); + fn doc_comments<'a, N: ast::DocCommentsOwner<'a>>(node: N) -> Option { + let comments = node.doc_comment_text(); + if comments.is_empty() { + None + } else { + Some(comments) + } + } + + 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::) + .accept(node)? + } + + /// Get a description of this node. + /// + /// e.g. `struct Name`, `enum Name`, `fn Name` + fn description(&self, db: &db::RootDatabase) -> Option { + // TODO: After type inference is done, add type information to improve the output + let node = self.node(db)?; + let node = node.borrowed(); + // TODO: Refactor to be have less repetition + visitor() + .visit(|node: ast::FnDef| { + let mut string = "fn ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::StructDef| { + let mut string = "struct ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::EnumDef| { + let mut string = "enum ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::TraitDef| { + let mut string = "trait ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::Module| { + let mut string = "mod ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::TypeDef| { + let mut string = "type ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::ConstDef| { + let mut string = "const ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .visit(|node: ast::StaticDef| { + let mut string = "static ".to_string(); + node.name()?.syntax().text().push_to(&mut string); + Some(string) + }) + .accept(node)? + } +} diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index a01febf4e..8247914c0 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -222,21 +222,31 @@ impl Query { #[derive(Debug)] pub struct NavigationTarget { file_id: FileId, - symbol: FileSymbol, + name: SmolStr, + kind: SyntaxKind, + range: TextRange, } impl NavigationTarget { - pub fn name(&self) -> SmolStr { - self.symbol.name.clone() + fn from_symbol(file_id: FileId, symbol: FileSymbol) -> NavigationTarget { + NavigationTarget { + name: symbol.name.clone(), + kind: symbol.kind.clone(), + file_id, + range: symbol.node_range.clone(), + } + } + pub fn name(&self) -> &SmolStr { + &self.name } pub fn kind(&self) -> SyntaxKind { - self.symbol.kind + self.kind } pub fn file_id(&self) -> FileId { self.file_id } pub fn range(&self) -> TextRange { - self.symbol.node_range + self.range } } @@ -260,7 +270,8 @@ impl ReferenceResolution { } fn add_resolution(&mut self, file_id: FileId, symbol: FileSymbol) { - self.resolves_to.push(NavigationTarget { file_id, symbol }) + self.resolves_to + .push(NavigationTarget::from_symbol(file_id, symbol)) } } @@ -359,7 +370,7 @@ impl Analysis { pub fn symbol_search(&self, query: Query) -> Cancelable> { let res = symbol_index::world_symbols(&*self.db, query)? .into_iter() - .map(|(file_id, symbol)| NavigationTarget { file_id, symbol }) + .map(|(file_id, symbol)| NavigationTarget::from_symbol(file_id, symbol)) .collect(); Ok(res) } diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index ddcf3d052..65abaec2e 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs @@ -5,10 +5,10 @@ use std::{ use fst::{self, Streamer}; use ra_syntax::{ - AstNode, SyntaxNodeRef, SourceFileNode, SmolStr, TextRange, + SyntaxNodeRef, SourceFileNode, SmolStr, TextRange, algo::visit::{visitor, Visitor}, SyntaxKind::{self, *}, - ast::{self, NameOwner, DocCommentsOwner}, + ast::{self, NameOwner}, }; use ra_db::{SyntaxDatabase, SourceRootId, FilesDatabase}; use salsa::ParallelDatabase; @@ -165,91 +165,7 @@ pub(crate) struct FileSymbol { pub(crate) name: SmolStr, pub(crate) node_range: TextRange, pub(crate) kind: SyntaxKind, -} - -impl FileSymbol { - pub(crate) fn docs(&self, file: &SourceFileNode) -> Option { - file.syntax() - .descendants() - .filter(|node| node.kind() == self.kind && node.range() == self.node_range) - .filter_map(|node: SyntaxNodeRef| { - fn doc_comments<'a, N: DocCommentsOwner<'a>>(node: N) -> Option { - let comments = node.doc_comment_text(); - if comments.is_empty() { - None - } else { - Some(comments) - } - } - - 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::) - .accept(node)? - }) - .nth(0) - } - /// Get a description of this node. - /// - /// e.g. `struct Name`, `enum Name`, `fn Name` - pub(crate) fn description(&self, file: &SourceFileNode) -> Option { - // TODO: After type inference is done, add type information to improve the output - file.syntax() - .descendants() - .filter(|node| node.kind() == self.kind && node.range() == self.node_range) - .filter_map(|node: SyntaxNodeRef| { - // TODO: Refactor to be have less repetition - visitor() - .visit(|node: ast::FnDef| { - let mut string = "fn ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::StructDef| { - let mut string = "struct ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::EnumDef| { - let mut string = "enum ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::TraitDef| { - let mut string = "trait ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::Module| { - let mut string = "mod ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::TypeDef| { - let mut string = "type ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::ConstDef| { - let mut string = "const ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .visit(|node: ast::StaticDef| { - let mut string = "static ".to_string(); - node.name()?.syntax().text().push_to(&mut string); - Some(string) - }) - .accept(node)? - }) - .nth(0) - } + _x: (), } fn to_symbol(node: SyntaxNodeRef) -> Option { @@ -259,6 +175,7 @@ fn to_symbol(node: SyntaxNodeRef) -> Option { name: name.text(), node_range: node.syntax().range(), kind: node.syntax().kind(), + _x: (), }) } visitor() -- cgit v1.2.3