From 2136e75c0bce090d104bb5b5006e48e42fb22a0a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 21 Dec 2018 23:04:56 +0300 Subject: move path completion to a separate component --- crates/ra_analysis/src/completion/complete_path.rs | 95 ++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 crates/ra_analysis/src/completion/complete_path.rs (limited to 'crates/ra_analysis/src/completion/complete_path.rs') diff --git a/crates/ra_analysis/src/completion/complete_path.rs b/crates/ra_analysis/src/completion/complete_path.rs new file mode 100644 index 000000000..d04503e46 --- /dev/null +++ b/crates/ra_analysis/src/completion/complete_path.rs @@ -0,0 +1,95 @@ +use crate::{ + completion::{CompletionItem, Completions, CompletionKind::*, SyntaxContext}, + Cancelable, +}; + +pub(super) fn complete_path(acc: &mut Completions, ctx: &SyntaxContext) -> Cancelable<()> { + let (path, module) = match (&ctx.path_prefix, &ctx.module) { + (Some(path), Some(module)) => (path.clone(), module), + _ => return Ok(()), + }; + let def_id = match module.resolve_path(ctx.db, path)? { + None => return Ok(()), + Some(it) => it, + }; + let target_module = match def_id.resolve(ctx.db)? { + hir::Def::Module(it) => it, + _ => return Ok(()), + }; + let module_scope = target_module.scope(ctx.db)?; + module_scope.entries().for_each(|(name, _res)| { + CompletionItem::new(name.to_string()) + .kind(Reference) + .add_to(acc) + }); + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::completion::{CompletionKind, check_completion}; + + fn check_reference_completion(code: &str, expected_completions: &str) { + check_completion(code, expected_completions, CompletionKind::Reference); + } + + #[test] + fn completes_use_item_starting_with_self() { + check_reference_completion( + r" + use self::m::<|>; + + mod m { + struct Bar; + } + ", + "Bar", + ); + } + + #[test] + fn completes_use_item_starting_with_crate() { + check_reference_completion( + " + //- /lib.rs + mod foo; + struct Spam; + //- /foo.rs + use crate::Sp<|> + ", + "Spam;foo", + ); + } + + #[test] + fn completes_nested_use_tree() { + check_reference_completion( + " + //- /lib.rs + mod foo; + struct Spam; + //- /foo.rs + use crate::{Sp<|>}; + ", + "Spam;foo", + ); + } + + #[test] + fn completes_deeply_nested_use_tree() { + check_reference_completion( + " + //- /lib.rs + mod foo; + pub mod bar { + pub mod baz { + pub struct Spam; + } + } + //- /foo.rs + use crate::{bar::{baz::Sp<|>}}; + ", + "Spam", + ); + } +} -- cgit v1.2.3