From a4b4fd7dc50575d015b404532ec9dd13e0a01835 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 2 Jan 2019 16:29:08 +0300 Subject: move symbols to ra_analysis --- crates/ra_analysis/src/imp.rs | 4 +- crates/ra_analysis/src/lib.rs | 5 +- crates/ra_analysis/src/symbol_index.rs | 123 +++++++++++++++++++++++++++++++-- 3 files changed, 124 insertions(+), 8 deletions(-) (limited to 'crates/ra_analysis/src') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 5669aa94d..f3b513de1 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -10,7 +10,7 @@ use hir::{ self, FnSignatureInfo, Problem, source_binder, }; use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; -use ra_editor::{self, FileSymbol, find_node_at_offset, LineIndex, LocalEdit, Severity}; +use ra_editor::{self, find_node_at_offset, LineIndex, LocalEdit, Severity}; use ra_syntax::{ algo::find_covering_node, ast::{self, ArgListOwner, Expr, FnDef, NameOwner}, @@ -25,7 +25,7 @@ use crate::{ completion::{CompletionItem, completions}, CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, - symbol_index::{LibrarySymbolsQuery, SymbolIndex, SymbolsDatabase}, + symbol_index::{LibrarySymbolsQuery, SymbolIndex, SymbolsDatabase, FileSymbol}, }; #[derive(Debug, Default)] diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index e6cfaecc3..ff28271ab 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -36,10 +36,11 @@ use crate::{ pub use crate::{ completion::{CompletionItem, CompletionItemKind, InsertText}, - runnables::{Runnable, RunnableKind} + runnables::{Runnable, RunnableKind}, + symbol_index::FileSymbol, }; pub use ra_editor::{ - FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, StructureNode, Severity + Fold, FoldKind, HighlightedRange, LineIndex, StructureNode, Severity }; pub use hir::FnSignatureInfo; diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index e5bdf0aa1..edb2268fb 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs @@ -4,10 +4,11 @@ use std::{ }; use fst::{self, Streamer}; -use ra_editor::{self, FileSymbol}; use ra_syntax::{ - SourceFileNode, + AstNode, SyntaxNodeRef, SourceFileNode, SmolStr, TextRange, + algo::visit::{visitor, Visitor}, SyntaxKind::{self, *}, + ast::{self, NameOwner, DocCommentsOwner}, }; use ra_db::{SyntaxDatabase, SourceRootId}; use rayon::prelude::*; @@ -65,8 +66,9 @@ impl SymbolIndex { ) -> SymbolIndex { let mut symbols = files .flat_map(|(file_id, file)| { - ra_editor::file_symbols(&file) - .into_iter() + file.syntax() + .descendants() + .filter_map(to_symbol) .map(move |symbol| (symbol.name.as_str().to_lowercase(), (file_id, symbol))) .collect::>() }) @@ -121,3 +123,116 @@ fn is_type(kind: SyntaxKind) -> bool { _ => false, } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FileSymbol { + pub name: SmolStr, + pub node_range: TextRange, + pub kind: SyntaxKind, +} + +impl FileSymbol { + pub 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 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) + } +} + +fn to_symbol(node: SyntaxNodeRef) -> Option { + fn decl<'a, N: NameOwner<'a>>(node: N) -> Option { + let name = node.name()?; + Some(FileSymbol { + name: name.text(), + node_range: node.syntax().range(), + kind: node.syntax().kind(), + }) + } + visitor() + .visit(decl::) + .visit(decl::) + .visit(decl::) + .visit(decl::) + .visit(decl::) + .visit(decl::) + .visit(decl::) + .visit(decl::) + .accept(node)? +} -- cgit v1.2.3