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 From 7ffc7d33082475ffd3b8768be001af5b8988a54b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 18:20:44 +0300 Subject: Move path completion to descriptors --- crates/ra_analysis/src/completion/mod.rs | 14 +++++++++++++ .../src/completion/reference_completion.rs | 23 +++++++--------------- 2 files changed, 21 insertions(+), 16 deletions(-) (limited to 'crates/ra_analysis/src/completion') diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs index a8a752fc7..8034060de 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion/mod.rs @@ -220,6 +220,20 @@ mod tests { ); } + #[test] + fn test_completion_self_path() { + check_scope_completion( + r" + use self::m::B<|>; + + mod m { + struct Bar; + } + ", + r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }]"#, + ); + } + #[test] fn test_completion_mod_scope_nested() { check_scope_completion( diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index a96570415..d301a3c02 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -13,7 +13,7 @@ use crate::{ descriptors::{ module::{ModuleDescriptor}, function::FnScopes, - Path, PathKind, + Path, }, Cancelable }; @@ -148,9 +148,13 @@ fn complete_path( acc: &mut Vec, db: &RootDatabase, module: &ModuleDescriptor, - path: Path, + mut path: Path, ) -> Cancelable<()> { - let target_module = match find_target_module(module, path) { + if path.segments.is_empty() { + return Ok(()); + } + path.segments.pop(); + let target_module = match module.resolve_path(path) { None => return Ok(()), Some(it) => it, }; @@ -167,19 +171,6 @@ fn complete_path( Ok(()) } -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 segments { - target_module = target_module.child(&name)?; - } - Some(target_module) -} - fn complete_mod_item_snippets(acc: &mut Vec) { acc.push(CompletionItem { label: "tfn".to_string(), -- cgit v1.2.3 From edeec6a41487e6458a9d96b328c9b784525d8f06 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 18:34:20 +0300 Subject: Complete paths after :: --- crates/ra_analysis/src/completion/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_analysis/src/completion') diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs index 8034060de..c7717ab61 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion/mod.rs @@ -224,7 +224,7 @@ mod tests { fn test_completion_self_path() { check_scope_completion( r" - use self::m::B<|>; + use self::m::<|>; mod m { struct Bar; -- cgit v1.2.3