mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Add DeclarationDescriptor and ReferenceDescriptor
Fixes #142 Fixes #146
This commit is contained in:
parent
55ebe6380a
commit
406f366ccc
3 changed files with 77 additions and 4 deletions
|
@ -5,16 +5,17 @@ use std::sync::Arc;
|
|||
|
||||
use ra_syntax::{
|
||||
SmolStr,
|
||||
ast::{FnDefNode},
|
||||
ast::{self, AstNode, FnDefNode},
|
||||
TextRange
|
||||
};
|
||||
|
||||
use crate::{
|
||||
FileId, Cancelable,
|
||||
db::SyntaxDatabase,
|
||||
descriptors::module::{ModuleTree, ModuleId, ModuleScope},
|
||||
descriptors::function::{FnId, FnScopes},
|
||||
descriptors::function::{FnId, FnScopes, resolve_local_name},
|
||||
input::SourceRootId,
|
||||
syntax_ptr::SyntaxPtrDatabase,
|
||||
syntax_ptr::{SyntaxPtrDatabase, LocalSyntaxPtr},
|
||||
};
|
||||
|
||||
|
||||
|
@ -44,3 +45,53 @@ salsa::query_group! {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReferenceDescriptor {
|
||||
pub range: TextRange,
|
||||
pub name: String
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeclarationDescriptor<'a> {
|
||||
pat: ast::BindPat<'a>,
|
||||
pub range: TextRange
|
||||
}
|
||||
|
||||
impl<'a> DeclarationDescriptor<'a> {
|
||||
pub fn new(pat: ast::BindPat) -> DeclarationDescriptor {
|
||||
let range = pat.syntax().range();
|
||||
|
||||
DeclarationDescriptor {
|
||||
pat,
|
||||
range
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_all_refs(&self) -> Vec<ReferenceDescriptor> {
|
||||
let name_ptr = LocalSyntaxPtr::new(self.pat.syntax());
|
||||
|
||||
let fn_def = match self.pat.syntax().ancestors().find_map(ast::FnDef::cast) {
|
||||
Some(def) => def,
|
||||
None => return Default::default()
|
||||
};
|
||||
|
||||
let fn_scopes = FnScopes::new(fn_def);
|
||||
|
||||
let refs : Vec<_> = fn_def.syntax().descendants()
|
||||
.filter_map(ast::NameRef::cast)
|
||||
.filter(|name_ref| {
|
||||
match resolve_local_name(*name_ref, &fn_scopes) {
|
||||
None => false,
|
||||
Some(entry) => entry.ptr() == name_ptr,
|
||||
}
|
||||
})
|
||||
.map(|name_ref| ReferenceDescriptor {
|
||||
name: name_ref.syntax().text().to_string(),
|
||||
range : name_ref.syntax().range(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
refs
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
|||
},
|
||||
input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE},
|
||||
descriptors::{
|
||||
DescriptorDatabase,
|
||||
DescriptorDatabase, DeclarationDescriptor,
|
||||
module::{ModuleTree, Problem},
|
||||
function::{FnDescriptor, FnId},
|
||||
},
|
||||
|
@ -327,6 +327,17 @@ impl AnalysisImpl {
|
|||
|
||||
let mut ret = vec![];
|
||||
|
||||
if let Some(binding) = find_node_at_offset::<ast::BindPat>(syntax, offset) {
|
||||
let decl = DeclarationDescriptor::new(binding);
|
||||
|
||||
ret.push((file_id, decl.range));
|
||||
|
||||
ret.extend(decl.find_all_refs().into_iter()
|
||||
.map(|ref_desc| (file_id, ref_desc.range )));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Find the symbol we are looking for
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
||||
|
||||
|
|
|
@ -377,6 +377,17 @@ fn test_find_all_refs_for_param_inside() {
|
|||
assert_eq!(refs.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_all_refs_for_fn_param() {
|
||||
let code = r#"
|
||||
fn foo(i<|> : u32) -> u32 {
|
||||
i
|
||||
}"#;
|
||||
|
||||
let refs = get_all_refs(code);
|
||||
assert_eq!(refs.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complete_crate_path() {
|
||||
let (analysis, position) = analysis_and_position("
|
||||
|
|
Loading…
Reference in a new issue