mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 15:15:24 +00:00
Resolve local names first
This commit is contained in:
parent
1d4c767879
commit
828bd73195
3 changed files with 14 additions and 15 deletions
|
@ -199,11 +199,11 @@ impl AnalysisImpl {
|
||||||
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) {
|
||||||
|
|
||||||
// First try to resolve the symbol locally
|
// First try to resolve the symbol locally
|
||||||
if let Some(name) = resolve_local_name(&file, offset, name_ref) {
|
if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) {
|
||||||
let vec: Vec<(FileId, FileSymbol)>::new();
|
let mut vec = vec![];
|
||||||
vec.push((file_id, FileSymbol {
|
vec.push((file_id, FileSymbol {
|
||||||
name: name.text(),
|
name,
|
||||||
node_range: name.syntax().range(),
|
node_range: range,
|
||||||
kind : NAME
|
kind : NAME
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod scope;
|
||||||
mod test_utils;
|
mod test_utils;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
File, TextUnit, TextRange, SyntaxNodeRef,
|
File, TextUnit, TextRange, SmolStr, SyntaxNodeRef,
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
algo::find_leaf_at_offset,
|
algo::find_leaf_at_offset,
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
|
@ -164,12 +164,12 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>(
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_local_name<'a>(file: &'a File, offset: TextUnit, name_ref: ast::NameRef) -> Option<ast::Name<'a>> {
|
pub fn resolve_local_name(file: &File, offset: TextUnit, name_ref: ast::NameRef) -> Option<(SmolStr, TextRange)> {
|
||||||
let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?;
|
let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?;
|
||||||
let scopes = scope::FnScopes::new(fn_def);
|
let scopes = scope::FnScopes::new(fn_def);
|
||||||
|
let scope_entry = scope::resolve_local_name(name_ref, &scopes)?;
|
||||||
// TODO: This doesn't work because of scopes lifetime
|
let name = scope_entry.ast().name()?;
|
||||||
scope::resolve_local_name(name_ref, &scopes)
|
Some((scope_entry.name(), name.syntax().range()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl ScopeEntry {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.text()
|
.text()
|
||||||
}
|
}
|
||||||
fn ast(&self) -> ast::BindPat {
|
pub fn ast(&self) -> ast::BindPat {
|
||||||
ast::BindPat::cast(self.syntax.borrowed())
|
ast::BindPat::cast(self.syntax.borrowed())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -241,16 +241,15 @@ struct ScopeData {
|
||||||
entries: Vec<ScopeEntry>
|
entries: Vec<ScopeEntry>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_local_name<'a>(name_ref: ast::NameRef, scopes: &'a FnScopes) -> Option<ast::Name<'a>> {
|
pub fn resolve_local_name<'a>(name_ref: ast::NameRef, scopes: &'a FnScopes) -> Option<&'a ScopeEntry> {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
let mut shadowed = HashSet::new();
|
let mut shadowed = HashSet::new();
|
||||||
let names = scopes.scope_chain(name_ref.syntax())
|
scopes.scope_chain(name_ref.syntax())
|
||||||
.flat_map(|scope| scopes.entries(scope).iter())
|
.flat_map(|scope| scopes.entries(scope).iter())
|
||||||
.filter(|entry| shadowed.insert(entry.name()))
|
.filter(|entry| shadowed.insert(entry.name()))
|
||||||
.filter(|entry| entry.name() == name_ref.text())
|
.filter(|entry| entry.name() == name_ref.text())
|
||||||
.nth(0)?;
|
.nth(0)
|
||||||
names.ast().name()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -365,7 +364,7 @@ mod tests {
|
||||||
|
|
||||||
let scopes = FnScopes::new(fn_def);
|
let scopes = FnScopes::new(fn_def);
|
||||||
|
|
||||||
let local_name = resolve_local_name(name_ref, &scopes).unwrap();
|
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();
|
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());
|
assert_eq!(local_name.syntax().range(), expected_name.syntax().range());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue