aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-02 13:29:08 +0000
committerAleksey Kladov <[email protected]>2019-01-02 13:29:08 +0000
commita4b4fd7dc50575d015b404532ec9dd13e0a01835 (patch)
tree4ba01eb7201bccdb3f4c018a607b55599743c685 /crates/ra_analysis
parente4ffd7b31780b1f2ac6dcb731566b583bf562647 (diff)
move symbols to ra_analysis
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/imp.rs4
-rw-r--r--crates/ra_analysis/src/lib.rs5
-rw-r--r--crates/ra_analysis/src/symbol_index.rs123
3 files changed, 124 insertions, 8 deletions
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::{
10 self, FnSignatureInfo, Problem, source_binder, 10 self, FnSignatureInfo, Problem, source_binder,
11}; 11};
12use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; 12use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase};
13use ra_editor::{self, FileSymbol, find_node_at_offset, LineIndex, LocalEdit, Severity}; 13use ra_editor::{self, find_node_at_offset, LineIndex, LocalEdit, Severity};
14use ra_syntax::{ 14use ra_syntax::{
15 algo::find_covering_node, 15 algo::find_covering_node,
16 ast::{self, ArgListOwner, Expr, FnDef, NameOwner}, 16 ast::{self, ArgListOwner, Expr, FnDef, NameOwner},
@@ -25,7 +25,7 @@ use crate::{
25 completion::{CompletionItem, completions}, 25 completion::{CompletionItem, completions},
26 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, 26 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit,
27 Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, 27 Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit,
28 symbol_index::{LibrarySymbolsQuery, SymbolIndex, SymbolsDatabase}, 28 symbol_index::{LibrarySymbolsQuery, SymbolIndex, SymbolsDatabase, FileSymbol},
29}; 29};
30 30
31#[derive(Debug, Default)] 31#[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::{
36 36
37pub use crate::{ 37pub use crate::{
38 completion::{CompletionItem, CompletionItemKind, InsertText}, 38 completion::{CompletionItem, CompletionItemKind, InsertText},
39 runnables::{Runnable, RunnableKind} 39 runnables::{Runnable, RunnableKind},
40 symbol_index::FileSymbol,
40}; 41};
41pub use ra_editor::{ 42pub use ra_editor::{
42 FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, StructureNode, Severity 43 Fold, FoldKind, HighlightedRange, LineIndex, StructureNode, Severity
43}; 44};
44pub use hir::FnSignatureInfo; 45pub use hir::FnSignatureInfo;
45 46
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::{
4}; 4};
5 5
6use fst::{self, Streamer}; 6use fst::{self, Streamer};
7use ra_editor::{self, FileSymbol};
8use ra_syntax::{ 7use ra_syntax::{
9 SourceFileNode, 8 AstNode, SyntaxNodeRef, SourceFileNode, SmolStr, TextRange,
9 algo::visit::{visitor, Visitor},
10 SyntaxKind::{self, *}, 10 SyntaxKind::{self, *},
11 ast::{self, NameOwner, DocCommentsOwner},
11}; 12};
12use ra_db::{SyntaxDatabase, SourceRootId}; 13use ra_db::{SyntaxDatabase, SourceRootId};
13use rayon::prelude::*; 14use rayon::prelude::*;
@@ -65,8 +66,9 @@ impl SymbolIndex {
65 ) -> SymbolIndex { 66 ) -> SymbolIndex {
66 let mut symbols = files 67 let mut symbols = files
67 .flat_map(|(file_id, file)| { 68 .flat_map(|(file_id, file)| {
68 ra_editor::file_symbols(&file) 69 file.syntax()
69 .into_iter() 70 .descendants()
71 .filter_map(to_symbol)
70 .map(move |symbol| (symbol.name.as_str().to_lowercase(), (file_id, symbol))) 72 .map(move |symbol| (symbol.name.as_str().to_lowercase(), (file_id, symbol)))
71 .collect::<Vec<_>>() 73 .collect::<Vec<_>>()
72 }) 74 })
@@ -121,3 +123,116 @@ fn is_type(kind: SyntaxKind) -> bool {
121 _ => false, 123 _ => false,
122 } 124 }
123} 125}
126
127#[derive(Debug, Clone, PartialEq, Eq, Hash)]
128pub struct FileSymbol {
129 pub name: SmolStr,
130 pub node_range: TextRange,
131 pub kind: SyntaxKind,
132}
133
134impl FileSymbol {
135 pub fn docs(&self, file: &SourceFileNode) -> Option<String> {
136 file.syntax()
137 .descendants()
138 .filter(|node| node.kind() == self.kind && node.range() == self.node_range)
139 .filter_map(|node: SyntaxNodeRef| {
140 fn doc_comments<'a, N: DocCommentsOwner<'a>>(node: N) -> Option<String> {
141 let comments = node.doc_comment_text();
142 if comments.is_empty() {
143 None
144 } else {
145 Some(comments)
146 }
147 }
148
149 visitor()
150 .visit(doc_comments::<ast::FnDef>)
151 .visit(doc_comments::<ast::StructDef>)
152 .visit(doc_comments::<ast::EnumDef>)
153 .visit(doc_comments::<ast::TraitDef>)
154 .visit(doc_comments::<ast::Module>)
155 .visit(doc_comments::<ast::TypeDef>)
156 .visit(doc_comments::<ast::ConstDef>)
157 .visit(doc_comments::<ast::StaticDef>)
158 .accept(node)?
159 })
160 .nth(0)
161 }
162 /// Get a description of this node.
163 ///
164 /// e.g. `struct Name`, `enum Name`, `fn Name`
165 pub fn description(&self, file: &SourceFileNode) -> Option<String> {
166 // TODO: After type inference is done, add type information to improve the output
167 file.syntax()
168 .descendants()
169 .filter(|node| node.kind() == self.kind && node.range() == self.node_range)
170 .filter_map(|node: SyntaxNodeRef| {
171 // TODO: Refactor to be have less repetition
172 visitor()
173 .visit(|node: ast::FnDef| {
174 let mut string = "fn ".to_string();
175 node.name()?.syntax().text().push_to(&mut string);
176 Some(string)
177 })
178 .visit(|node: ast::StructDef| {
179 let mut string = "struct ".to_string();
180 node.name()?.syntax().text().push_to(&mut string);
181 Some(string)
182 })
183 .visit(|node: ast::EnumDef| {
184 let mut string = "enum ".to_string();
185 node.name()?.syntax().text().push_to(&mut string);
186 Some(string)
187 })
188 .visit(|node: ast::TraitDef| {
189 let mut string = "trait ".to_string();
190 node.name()?.syntax().text().push_to(&mut string);
191 Some(string)
192 })
193 .visit(|node: ast::Module| {
194 let mut string = "mod ".to_string();
195 node.name()?.syntax().text().push_to(&mut string);
196 Some(string)
197 })
198 .visit(|node: ast::TypeDef| {
199 let mut string = "type ".to_string();
200 node.name()?.syntax().text().push_to(&mut string);
201 Some(string)
202 })
203 .visit(|node: ast::ConstDef| {
204 let mut string = "const ".to_string();
205 node.name()?.syntax().text().push_to(&mut string);
206 Some(string)
207 })
208 .visit(|node: ast::StaticDef| {
209 let mut string = "static ".to_string();
210 node.name()?.syntax().text().push_to(&mut string);
211 Some(string)
212 })
213 .accept(node)?
214 })
215 .nth(0)
216 }
217}
218
219fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> {
220 fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<FileSymbol> {
221 let name = node.name()?;
222 Some(FileSymbol {
223 name: name.text(),
224 node_range: node.syntax().range(),
225 kind: node.syntax().kind(),
226 })
227 }
228 visitor()
229 .visit(decl::<ast::FnDef>)
230 .visit(decl::<ast::StructDef>)
231 .visit(decl::<ast::EnumDef>)
232 .visit(decl::<ast::TraitDef>)
233 .visit(decl::<ast::Module>)
234 .visit(decl::<ast::TypeDef>)
235 .visit(decl::<ast::ConstDef>)
236 .visit(decl::<ast::StaticDef>)
237 .accept(node)?
238}