move resolve local name
This commit is contained in:
parent
b67295134b
commit
c02be1502c
@ -10,7 +10,7 @@ use crate::{
|
||||
syntax_ptr::SyntaxPtr
|
||||
};
|
||||
|
||||
pub(crate) use self::scope::FnScopes;
|
||||
pub(crate) use self::scope::{FnScopes, resolve_local_name};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use ra_syntax::{
|
||||
algo::generate,
|
||||
@ -261,8 +261,6 @@ pub fn resolve_local_name<'a>(
|
||||
name_ref: ast::NameRef,
|
||||
scopes: &'a FnScopes,
|
||||
) -> Option<&'a ScopeEntry> {
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
let mut shadowed = FxHashSet::default();
|
||||
let ret = scopes
|
||||
.scope_chain(name_ref.syntax())
|
||||
|
@ -3,7 +3,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ra_editor::{self, find_node_at_offset, resolve_local_name, FileSymbol, LineIndex, LocalEdit, CompletionItem};
|
||||
use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit, CompletionItem};
|
||||
use ra_syntax::{
|
||||
ast::{self, ArgListOwner, Expr, NameOwner},
|
||||
AstNode, File, SmolStr,
|
||||
@ -21,10 +21,13 @@ use crate::{
|
||||
self, SyntaxDatabase, FileSyntaxQuery,
|
||||
},
|
||||
input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE},
|
||||
descriptors::DescriptorDatabase,
|
||||
descriptors::module::{ModuleTree, Problem},
|
||||
descriptors::function::{FnDescriptor},
|
||||
descriptors::{
|
||||
DescriptorDatabase,
|
||||
module::{ModuleTree, Problem},
|
||||
function::{FnDescriptor, FnId},
|
||||
},
|
||||
symbol_index::SymbolIndex,
|
||||
syntax_ptr::SyntaxPtrDatabase,
|
||||
CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position,
|
||||
Query, SourceChange, SourceFileEdit, Cancelable,
|
||||
};
|
||||
@ -272,7 +275,7 @@ impl AnalysisImpl {
|
||||
let syntax = file.syntax();
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
||||
// First try to resolve the symbol locally
|
||||
return if let Some((name, range)) = resolve_local_name(name_ref) {
|
||||
return if let Some((name, range)) = resolve_local_name(&self.db, file_id, name_ref) {
|
||||
let mut vec = vec![];
|
||||
vec.push((
|
||||
file_id,
|
||||
@ -326,7 +329,7 @@ impl AnalysisImpl {
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
||||
|
||||
// We are only handing local references for now
|
||||
if let Some(resolved) = resolve_local_name(name_ref) {
|
||||
if let Some(resolved) = resolve_local_name(&self.db, file_id, name_ref) {
|
||||
|
||||
ret.push((file_id, resolved.1));
|
||||
|
||||
@ -334,7 +337,7 @@ impl AnalysisImpl {
|
||||
|
||||
let refs : Vec<_> = fn_def.syntax().descendants()
|
||||
.filter_map(ast::NameRef::cast)
|
||||
.filter(|&n: &ast::NameRef| resolve_local_name(n) == Some(resolved.clone()))
|
||||
.filter(|&n: &ast::NameRef| resolve_local_name(&self.db, file_id, n) == Some(resolved.clone()))
|
||||
.collect();
|
||||
|
||||
for r in refs {
|
||||
@ -598,3 +601,16 @@ impl<'a> FnCallNode<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_local_name(
|
||||
db: &db::RootDatabase,
|
||||
file_id: FileId,
|
||||
name_ref: ast::NameRef,
|
||||
) -> Option<(SmolStr, TextRange)> {
|
||||
let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?;
|
||||
let fn_id = FnId::new(file_id, fn_def);
|
||||
let scopes = db.fn_scopes(fn_id);
|
||||
let scope_entry = crate::descriptors::function::resolve_local_name(name_ref, &scopes)?;
|
||||
let syntax = db.resolve_syntax_ptr(scope_entry.ptr().into_global(file_id));
|
||||
Some((scope_entry.name().clone(), syntax.range()))
|
||||
}
|
||||
|
@ -84,6 +84,10 @@ impl LocalSyntaxPtr {
|
||||
.unwrap_or_else(|| panic!("can't resovle local ptr to SyntaxNode: {:?}", self))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_global(self, file_id: FileId) -> SyntaxPtr {
|
||||
SyntaxPtr { file_id, local: self}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,15 +151,7 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>(
|
||||
leaf.ancestors().filter_map(N::cast).next()
|
||||
}
|
||||
|
||||
pub fn resolve_local_name(
|
||||
name_ref: ast::NameRef,
|
||||
) -> Option<(SmolStr, TextRange)> {
|
||||
let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?;
|
||||
let scopes = scope::FnScopes::new(fn_def);
|
||||
let scope_entry = scope::resolve_local_name(name_ref, &scopes)?;
|
||||
let name = scope_entry.ast().name()?;
|
||||
Some((scope_entry.name(), name.syntax().range()))
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -258,22 +258,6 @@ struct ScopeData {
|
||||
entries: Vec<ScopeEntry>,
|
||||
}
|
||||
|
||||
pub fn resolve_local_name<'a>(
|
||||
name_ref: ast::NameRef,
|
||||
scopes: &'a FnScopes,
|
||||
) -> Option<&'a ScopeEntry> {
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
let mut shadowed = FxHashSet::default();
|
||||
let ret = scopes
|
||||
.scope_chain(name_ref.syntax())
|
||||
.flat_map(|scope| scopes.entries(scope).iter())
|
||||
.filter(|entry| shadowed.insert(entry.name()))
|
||||
.filter(|entry| entry.name() == name_ref.text())
|
||||
.nth(0);
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -376,61 +360,4 @@ mod tests {
|
||||
&["x"],
|
||||
);
|
||||
}
|
||||
|
||||
fn do_check_local_name(code: &str, expected_offset: u32) {
|
||||
let (off, code) = extract_offset(code);
|
||||
let file = File::parse(&code);
|
||||
let fn_def: ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
|
||||
let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
|
||||
|
||||
let scopes = FnScopes::new(fn_def);
|
||||
|
||||
let local_name = resolve_local_name(name_ref, &scopes)
|
||||
.unwrap()
|
||||
.ast()
|
||||
.name()
|
||||
.unwrap();
|
||||
let expected_name =
|
||||
find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()).unwrap();
|
||||
assert_eq!(local_name.syntax().range(), expected_name.syntax().range());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_local_name() {
|
||||
do_check_local_name(
|
||||
r#"
|
||||
fn foo(x: i32, y: u32) {
|
||||
{
|
||||
let z = x * 2;
|
||||
}
|
||||
{
|
||||
let t = x<|> * 3;
|
||||
}
|
||||
}"#,
|
||||
21,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_local_name_declaration() {
|
||||
do_check_local_name(
|
||||
r#"
|
||||
fn foo(x: String) {
|
||||
let x : &str = &x<|>;
|
||||
}"#,
|
||||
21,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolve_local_name_shadow() {
|
||||
do_check_local_name(
|
||||
r"
|
||||
fn foo(x: String) {
|
||||
let x : &str = &x;
|
||||
x<|>
|
||||
}",
|
||||
46,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ mod fn_scope;
|
||||
mod mod_scope;
|
||||
|
||||
pub use self::{
|
||||
fn_scope::{resolve_local_name, FnScopes},
|
||||
fn_scope::{FnScopes},
|
||||
mod_scope::ModuleScope,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user