From d9c77c54534fcde7c432c6e11746d636d972a20b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 8 Mar 2020 10:51:40 +0100 Subject: Handle visibility for path completion (not in all cases yet) --- crates/ra_hir/src/code_model.rs | 12 +++++++- crates/ra_ide/src/completion/complete_path.rs | 44 ++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index f93b43fb6..4d1e8f921 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -204,10 +204,20 @@ impl Module { } /// Returns a `ModuleScope`: a set of items, visible in this module. - pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { + pub fn scope(self, db: &impl HirDatabase, visible_from: Option) -> Vec<(Name, ScopeDef)> { db.crate_def_map(self.id.krate)[self.id.local_id] .scope .entries() + .filter_map(|(name, def)| if let Some(m) = visible_from { + let filtered = def.filter_visibility(|vis| vis.is_visible_from(db, m.id)); + if filtered.is_none() && !def.is_none() { + None + } else { + Some((name, filtered)) + } + } else { + Some((name, def)) + }) .map(|(name, def)| (name.clone(), def.into())) .collect() } diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs index 1a9699466..f99b1c2c4 100644 --- a/crates/ra_ide/src/completion/complete_path.rs +++ b/crates/ra_ide/src/completion/complete_path.rs @@ -1,6 +1,6 @@ //! Completion of paths, including when writing a single name. -use hir::{Adt, PathResolution, ScopeDef}; +use hir::{Adt, PathResolution, ScopeDef, HasVisibility}; use ra_syntax::AstNode; use test_utils::tested_by; @@ -15,9 +15,10 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { Some(PathResolution::Def(def)) => def, _ => return, }; + let context_module = ctx.scope().module(); match def { hir::ModuleDef::Module(module) => { - let module_scope = module.scope(ctx.db); + let module_scope = module.scope(ctx.db, context_module); for (name, def) in module_scope { if ctx.use_item_syntax.is_some() { if let ScopeDef::Unknown = def { @@ -53,7 +54,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { match item { hir::AssocItem::Function(func) => { - if !func.has_self_param(ctx.db) { + if !func.has_self_param(ctx.db) && context_module.map_or(true, |m| func.is_visible_from(ctx.db, m)) { acc.add_function(ctx, func); } } @@ -169,6 +170,41 @@ mod tests { ); } + #[test] + fn path_visibility() { + assert_debug_snapshot!( + do_reference_completion( + r" + use self::my::<|>; + + mod my { + struct Bar; + pub struct Foo; + pub use Bar as PublicBar; + } + " + ), + @r###" + [ + CompletionItem { + label: "Foo", + source_range: [31; 31), + delete: [31; 31), + insert: "Foo", + kind: Struct, + }, + CompletionItem { + label: "PublicBar", + source_range: [31; 31), + delete: [31; 31), + insert: "PublicBar", + kind: Struct, + }, + ] + "### + ); + } + #[test] fn completes_use_item_starting_with_self() { assert_debug_snapshot!( @@ -177,7 +213,7 @@ mod tests { use self::m::<|>; mod m { - struct Bar; + pub struct Bar; } " ), -- cgit v1.2.3