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.rs93
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::{
7use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; 7use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit};
8use ra_syntax::{ 8use 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
586fn 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}