aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs78
1 files changed, 42 insertions, 36 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index a67b1717a..32e9bb6d7 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -19,8 +19,8 @@ use rustc_hash::FxHashSet;
19use crate::{ 19use crate::{
20 descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem}, 20 descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem},
21 roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot}, 21 roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot},
22 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, JobToken, Position, 22 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position,
23 Query, SourceChange, SourceFileEdit, 23 Query, SourceChange, SourceFileEdit, Cancelable,
24}; 24};
25 25
26#[derive(Clone, Debug)] 26#[derive(Clone, Debug)]
@@ -148,19 +148,21 @@ impl AnalysisImpl {
148 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { 148 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> {
149 self.root(file_id).lines(file_id) 149 self.root(file_id).lines(file_id)
150 } 150 }
151 pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { 151 pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> {
152 let mut buf = Vec::new(); 152 let mut buf = Vec::new();
153 if query.libs { 153 if query.libs {
154 self.data.libs.iter().for_each(|it| it.symbols(&mut buf)); 154 for lib in self.data.libs.iter() {
155 lib.symbols(&mut buf)?;
156 }
155 } else { 157 } else {
156 self.data.root.symbols(&mut buf); 158 self.data.root.symbols(&mut buf)?;
157 } 159 }
158 query.search(&buf, token) 160 Ok(query.search(&buf))
159 } 161 }
160 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { 162 pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> {
161 let root = self.root(file_id); 163 let root = self.root(file_id);
162 let module_tree = root.module_tree(); 164 let module_tree = root.module_tree()?;
163 module_tree 165 let res = module_tree
164 .parent_modules(file_id) 166 .parent_modules(file_id)
165 .iter() 167 .iter()
166 .map(|link| { 168 .map(|link| {
@@ -174,10 +176,11 @@ impl AnalysisImpl {
174 }; 176 };
175 (file_id, sym) 177 (file_id, sym)
176 }) 178 })
177 .collect() 179 .collect();
180 Ok(res)
178 } 181 }
179 pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { 182 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
180 let module_tree = self.root(file_id).module_tree(); 183 let module_tree = self.root(file_id).module_tree()?;
181 let crate_graph = &self.data.crate_graph; 184 let crate_graph = &self.data.crate_graph;
182 let mut res = Vec::new(); 185 let mut res = Vec::new();
183 let mut work = VecDeque::new(); 186 let mut work = VecDeque::new();
@@ -195,7 +198,7 @@ impl AnalysisImpl {
195 .filter(|&id| visited.insert(id)); 198 .filter(|&id| visited.insert(id));
196 work.extend(parents); 199 work.extend(parents);
197 } 200 }
198 res 201 Ok(res)
199 } 202 }
200 pub fn crate_root(&self, crate_id: CrateId) -> FileId { 203 pub fn crate_root(&self, crate_id: CrateId) -> FileId {
201 self.data.crate_graph.crate_roots[&crate_id] 204 self.data.crate_graph.crate_roots[&crate_id]
@@ -204,15 +207,14 @@ impl AnalysisImpl {
204 &self, 207 &self,
205 file_id: FileId, 208 file_id: FileId,
206 offset: TextUnit, 209 offset: TextUnit,
207 token: &JobToken, 210 ) -> Cancelable<Vec<(FileId, FileSymbol)>> {
208 ) -> Vec<(FileId, FileSymbol)> {
209 let root = self.root(file_id); 211 let root = self.root(file_id);
210 let module_tree = root.module_tree(); 212 let module_tree = root.module_tree()?;
211 let file = root.syntax(file_id); 213 let file = root.syntax(file_id);
212 let syntax = file.syntax(); 214 let syntax = file.syntax();
213 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { 215 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
214 // First try to resolve the symbol locally 216 // First try to resolve the symbol locally
215 if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) { 217 return if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) {
216 let mut vec = vec![]; 218 let mut vec = vec![];
217 vec.push(( 219 vec.push((
218 file_id, 220 file_id,
@@ -222,12 +224,11 @@ impl AnalysisImpl {
222 kind: NAME, 224 kind: NAME,
223 }, 225 },
224 )); 226 ));
225 227 Ok(vec)
226 return vec;
227 } else { 228 } else {
228 // If that fails try the index based approach. 229 // If that fails try the index based approach.
229 return self.index_resolve(name_ref, token); 230 self.index_resolve(name_ref)
230 } 231 };
231 } 232 }
232 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { 233 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) {
233 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { 234 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
@@ -250,14 +251,14 @@ impl AnalysisImpl {
250 }) 251 })
251 .collect(); 252 .collect();
252 253
253 return res; 254 return Ok(res);
254 } 255 }
255 } 256 }
256 } 257 }
257 vec![] 258 Ok(vec![])
258 } 259 }
259 260
260 pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, _token: &JobToken) -> Vec<(FileId, TextRange)> { 261 pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, TextRange)> {
261 let root = self.root(file_id); 262 let root = self.root(file_id);
262 let file = root.syntax(file_id); 263 let file = root.syntax(file_id);
263 let syntax = file.syntax(); 264 let syntax = file.syntax();
@@ -289,9 +290,9 @@ impl AnalysisImpl {
289 ret 290 ret
290 } 291 }
291 292
292 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { 293 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
293 let root = self.root(file_id); 294 let root = self.root(file_id);
294 let module_tree = root.module_tree(); 295 let module_tree = root.module_tree()?;
295 let syntax = root.syntax(file_id); 296 let syntax = root.syntax(file_id);
296 297
297 let mut res = ra_editor::diagnostics(&syntax) 298 let mut res = ra_editor::diagnostics(&syntax)
@@ -346,7 +347,7 @@ impl AnalysisImpl {
346 }; 347 };
347 res.push(diag) 348 res.push(diag)
348 } 349 }
349 res 350 Ok(res)
350 } 351 }
351 352
352 pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec<SourceChange> { 353 pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec<SourceChange> {
@@ -379,18 +380,23 @@ impl AnalysisImpl {
379 &self, 380 &self,
380 file_id: FileId, 381 file_id: FileId,
381 offset: TextUnit, 382 offset: TextUnit,
382 token: &JobToken, 383 ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> {
383 ) -> Option<(FnDescriptor, Option<usize>)> {
384 let root = self.root(file_id); 384 let root = self.root(file_id);
385 let file = root.syntax(file_id); 385 let file = root.syntax(file_id);
386 let syntax = file.syntax(); 386 let syntax = file.syntax();
387 387
388 // Find the calling expression and it's NameRef 388 // Find the calling expression and it's NameRef
389 let calling_node = FnCallNode::with_node(syntax, offset)?; 389 let calling_node = match FnCallNode::with_node(syntax, offset) {
390 let name_ref = calling_node.name_ref()?; 390 Some(node) => node,
391 None => return Ok(None),
392 };
393 let name_ref = match calling_node.name_ref() {
394 Some(name) => name,
395 None => return Ok(None),
396 };
391 397
392 // Resolve the function's NameRef (NOTE: this isn't entirely accurate). 398 // Resolve the function's NameRef (NOTE: this isn't entirely accurate).
393 let file_symbols = self.index_resolve(name_ref, token); 399 let file_symbols = self.index_resolve(name_ref)?;
394 for (_, fs) in file_symbols { 400 for (_, fs) in file_symbols {
395 if fs.kind == FN_DEF { 401 if fs.kind == FN_DEF {
396 if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) { 402 if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) {
@@ -432,21 +438,21 @@ impl AnalysisImpl {
432 } 438 }
433 } 439 }
434 440
435 return Some((descriptor, current_parameter)); 441 return Ok(Some((descriptor, current_parameter)));
436 } 442 }
437 } 443 }
438 } 444 }
439 } 445 }
440 446
441 None 447 Ok(None)
442 } 448 }
443 449
444 fn index_resolve(&self, name_ref: ast::NameRef, token: &JobToken) -> Vec<(FileId, FileSymbol)> { 450 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> {
445 let name = name_ref.text(); 451 let name = name_ref.text();
446 let mut query = Query::new(name.to_string()); 452 let mut query = Query::new(name.to_string());
447 query.exact(); 453 query.exact();
448 query.limit(4); 454 query.limit(4);
449 self.world_symbols(query, token) 455 self.world_symbols(query)
450 } 456 }
451 457
452 fn resolve_module( 458 fn resolve_module(