mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +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::{
|
use ra_syntax::{
|
||||||
SmolStr,
|
SmolStr,
|
||||||
ast::{FnDefNode},
|
ast::{self, AstNode, FnDefNode},
|
||||||
|
TextRange
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
FileId, Cancelable,
|
FileId, Cancelable,
|
||||||
db::SyntaxDatabase,
|
db::SyntaxDatabase,
|
||||||
descriptors::module::{ModuleTree, ModuleId, ModuleScope},
|
descriptors::module::{ModuleTree, ModuleId, ModuleScope},
|
||||||
descriptors::function::{FnId, FnScopes},
|
descriptors::function::{FnId, FnScopes, resolve_local_name},
|
||||||
input::SourceRootId,
|
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},
|
input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE},
|
||||||
descriptors::{
|
descriptors::{
|
||||||
DescriptorDatabase,
|
DescriptorDatabase, DeclarationDescriptor,
|
||||||
module::{ModuleTree, Problem},
|
module::{ModuleTree, Problem},
|
||||||
function::{FnDescriptor, FnId},
|
function::{FnDescriptor, FnId},
|
||||||
},
|
},
|
||||||
|
@ -327,6 +327,17 @@ impl AnalysisImpl {
|
||||||
|
|
||||||
let mut ret = vec![];
|
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
|
// Find the symbol we are looking for
|
||||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
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);
|
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]
|
#[test]
|
||||||
fn test_complete_crate_path() {
|
fn test_complete_crate_path() {
|
||||||
let (analysis, position) = analysis_and_position("
|
let (analysis, position) = analysis_and_position("
|
||||||
|
|
Loading…
Reference in a new issue