diff options
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 93 |
1 files changed, 46 insertions, 47 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index b16edb969..377f7420f 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -7,7 +7,7 @@ use std::{ | |||
7 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; | 7 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; |
8 | use ra_syntax::{ | 8 | use ra_syntax::{ |
9 | ast::{self, ArgListOwner, Expr, NameOwner}, | 9 | ast::{self, ArgListOwner, Expr, NameOwner}, |
10 | AstNode, SourceFileNode, SmolStr, | 10 | AstNode, SourceFileNode, |
11 | SyntaxKind::*, | 11 | SyntaxKind::*, |
12 | SyntaxNodeRef, TextRange, TextUnit, | 12 | SyntaxNodeRef, TextRange, TextUnit, |
13 | }; | 13 | }; |
@@ -22,7 +22,6 @@ use crate::{ | |||
22 | hir::{ | 22 | hir::{ |
23 | FunctionDescriptor, FnSignatureInfo, ModuleDescriptor, | 23 | FunctionDescriptor, FnSignatureInfo, ModuleDescriptor, |
24 | Problem, | 24 | Problem, |
25 | DeclarationDescriptor, | ||
26 | }, | 25 | }, |
27 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, | 26 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, |
28 | symbol_index::SymbolIndex, | 27 | symbol_index::SymbolIndex, |
@@ -273,24 +272,27 @@ impl AnalysisImpl { | |||
273 | let file = self.db.file_syntax(position.file_id); | 272 | let file = self.db.file_syntax(position.file_id); |
274 | let syntax = file.syntax(); | 273 | let syntax = file.syntax(); |
275 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 274 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
276 | // First try to resolve the symbol locally | 275 | if let Some(fn_descr) = |
277 | return if let Some((name, range)) = | 276 | FunctionDescriptor::guess_for_name_ref(&*self.db, position.file_id, name_ref) |
278 | resolve_local_name(&self.db, position.file_id, name_ref) | ||
279 | { | 277 | { |
280 | let mut vec = vec![]; | 278 | let scope = fn_descr.scope(&*self.db); |
281 | vec.push(( | 279 | // First try to resolve the symbol locally |
282 | position.file_id, | 280 | return if let Some(entry) = scope.resolve_local_name(name_ref) { |
283 | FileSymbol { | 281 | let mut vec = vec![]; |
284 | name, | 282 | vec.push(( |
285 | node_range: range, | 283 | position.file_id, |
286 | kind: NAME, | 284 | FileSymbol { |
287 | }, | 285 | name: entry.name().clone(), |
288 | )); | 286 | node_range: entry.ptr().range(), |
289 | Ok(vec) | 287 | kind: NAME, |
290 | } else { | 288 | }, |
291 | // If that fails try the index based approach. | 289 | )); |
292 | self.index_resolve(name_ref) | 290 | Ok(vec) |
293 | }; | 291 | } else { |
292 | // If that fails try the index based approach. | ||
293 | self.index_resolve(name_ref) | ||
294 | }; | ||
295 | } | ||
294 | } | 296 | } |
295 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 297 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
296 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 298 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
@@ -320,31 +322,41 @@ impl AnalysisImpl { | |||
320 | 322 | ||
321 | pub fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { | 323 | pub fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { |
322 | let file = self.db.file_syntax(position.file_id); | 324 | let file = self.db.file_syntax(position.file_id); |
323 | let syntax = file.syntax(); | ||
324 | |||
325 | // Find the binding associated with the offset | 325 | // Find the binding associated with the offset |
326 | let maybe_binding = | 326 | let (binding, descr) = match find_binding(&self.db, &file, position) { |
327 | find_node_at_offset::<ast::BindPat>(syntax, position.offset).or_else(|| { | ||
328 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?; | ||
329 | let resolved = resolve_local_name(&self.db, position.file_id, name_ref)?; | ||
330 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) | ||
331 | }); | ||
332 | |||
333 | let binding = match maybe_binding { | ||
334 | None => return Vec::new(), | 327 | None => return Vec::new(), |
335 | Some(it) => it, | 328 | Some(it) => it, |
336 | }; | 329 | }; |
337 | 330 | ||
338 | let decl = DeclarationDescriptor::new(binding); | 331 | let mut ret = vec![(position.file_id, binding.syntax().range())]; |
339 | |||
340 | let mut ret = vec![(position.file_id, decl.range)]; | ||
341 | ret.extend( | 332 | ret.extend( |
342 | decl.find_all_refs() | 333 | descr |
334 | .scope(&*self.db) | ||
335 | .find_all_refs(binding) | ||
343 | .into_iter() | 336 | .into_iter() |
344 | .map(|ref_desc| (position.file_id, ref_desc.range)), | 337 | .map(|ref_desc| (position.file_id, ref_desc.range)), |
345 | ); | 338 | ); |
346 | 339 | ||
347 | ret | 340 | return ret; |
341 | |||
342 | fn find_binding<'a>( | ||
343 | db: &db::RootDatabase, | ||
344 | source_file: &'a SourceFileNode, | ||
345 | position: FilePosition, | ||
346 | ) -> Option<(ast::BindPat<'a>, FunctionDescriptor)> { | ||
347 | let syntax = source_file.syntax(); | ||
348 | if let Some(binding) = find_node_at_offset::<ast::BindPat>(syntax, position.offset) { | ||
349 | let descr = FunctionDescriptor::guess_for_bind_pat(db, position.file_id, binding)?; | ||
350 | return Some((binding, descr)); | ||
351 | }; | ||
352 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?; | ||
353 | let descr = FunctionDescriptor::guess_for_name_ref(db, position.file_id, name_ref)?; | ||
354 | let scope = descr.scope(db); | ||
355 | let resolved = scope.resolve_local_name(name_ref)?; | ||
356 | let resolved = resolved.ptr().resolve(source_file); | ||
357 | let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?; | ||
358 | Some((binding, descr)) | ||
359 | } | ||
348 | } | 360 | } |
349 | 361 | ||
350 | pub fn doc_comment_for( | 362 | pub fn doc_comment_for( |
@@ -582,16 +594,3 @@ impl<'a> FnCallNode<'a> { | |||
582 | } | 594 | } |
583 | } | 595 | } |
584 | } | 596 | } |
585 | |||
586 | fn resolve_local_name( | ||
587 | db: &db::RootDatabase, | ||
588 | file_id: FileId, | ||
589 | name_ref: ast::NameRef, | ||
590 | ) -> Option<(SmolStr, TextRange)> { | ||
591 | let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?; | ||
592 | let function = FunctionDescriptor::guess_from_source(db, file_id, fn_def); | ||
593 | let scopes = function.scope(db); | ||
594 | let scope_entry = scopes.resolve_local_name(name_ref)?; | ||
595 | let syntax = db.resolve_syntax_ptr(scope_entry.ptr().into_global(file_id)); | ||
596 | Some((scope_entry.name().clone(), syntax.range())) | ||
597 | } | ||