From 11f19b784923ac701bc6fc39a6aea712f0091bf7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 17:51:02 +0300 Subject: name res uses paths --- .../src/completion/reference_completion.rs | 64 ++++++++-------------- 1 file changed, 22 insertions(+), 42 deletions(-) (limited to 'crates/ra_analysis/src/completion') diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index 84383b547..a96570415 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -10,8 +10,11 @@ use ra_syntax::{ use crate::{ db::RootDatabase, completion::CompletionItem, - descriptors::module::{ModuleDescriptor}, - descriptors::function::FnScopes, + descriptors::{ + module::{ModuleDescriptor}, + function::FnScopes, + Path, PathKind, + }, Cancelable }; @@ -55,7 +58,7 @@ pub(super) fn completions( }), ); } - NameRefKind::CratePath(path) => complete_path(acc, db, module, path)?, + NameRefKind::Path(path) => complete_path(acc, db, module, path)?, NameRefKind::BareIdentInMod => { let name_range = name_ref.syntax().range(); let top_node = name_ref @@ -79,8 +82,8 @@ enum NameRefKind<'a> { LocalRef { enclosing_fn: Option>, }, - /// NameRef is the last segment in crate:: path - CratePath(Vec>), + /// NameRef is the last segment in some path + Path(Path), /// NameRef is bare identifier at the module's root. /// Used for keyword completion BareIdentInMod, @@ -102,8 +105,10 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option { let parent = name_ref.syntax().parent()?; if let Some(segment) = ast::PathSegment::cast(parent) { let path = segment.parent_path(); - if let Some(crate_path) = crate_path(path) { - return Some(NameRefKind::CratePath(crate_path)); + if let Some(path) = Path::from_ast(path) { + if !path.is_ident() { + return Some(NameRefKind::Path(path)); + } } if path.qualifier().is_none() { let enclosing_fn = name_ref @@ -117,32 +122,6 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option { None } -fn crate_path(mut path: ast::Path) -> Option> { - let mut res = Vec::new(); - loop { - let segment = path.segment()?; - match segment.kind()? { - ast::PathSegmentKind::Name(name) => res.push(name), - ast::PathSegmentKind::CrateKw => break, - ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => return None, - } - path = qualifier(path)?; - } - res.reverse(); - return Some(res); - - fn qualifier(path: ast::Path) -> Option { - if let Some(q) = path.qualifier() { - return Some(q); - } - // TODO: this bottom up traversal is not too precise. - // Should we handle do a top-down analysiss, recording results? - let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; - let use_tree = use_tree_list.parent_use_tree(); - use_tree.path() - } -} - fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec) { let mut shadowed = FxHashSet::default(); acc.extend( @@ -169,9 +148,9 @@ fn complete_path( acc: &mut Vec, db: &RootDatabase, module: &ModuleDescriptor, - crate_path: Vec, + path: Path, ) -> Cancelable<()> { - let target_module = match find_target_module(module, crate_path) { + let target_module = match find_target_module(module, path) { None => return Ok(()), Some(it) => it, }; @@ -188,14 +167,15 @@ fn complete_path( Ok(()) } -fn find_target_module( - module: &ModuleDescriptor, - mut crate_path: Vec, -) -> Option { - crate_path.pop(); +fn find_target_module(module: &ModuleDescriptor, path: Path) -> Option { + if path.kind != PathKind::Crate { + return None; + } + let mut segments = path.segments; + segments.pop(); let mut target_module = module.crate_root(); - for name in crate_path { - target_module = target_module.child(name.text().as_str())?; + for name in segments { + target_module = target_module.child(&name)?; } Some(target_module) } -- cgit v1.2.3