Resolve local names first

This commit is contained in:
Jeremy A. Kolb 2018-10-06 12:02:15 -04:00
parent 1d4c767879
commit 828bd73195
3 changed files with 14 additions and 15 deletions

View file

@ -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
})); }));

View file

@ -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)]

View file

@ -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());