From 05e1c7b1972a87abe6d352b5d0cd8a58e2b7adc7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 8 Mar 2020 15:11:57 +0100 Subject: Handle visibility for assoc item path completion as well --- crates/ra_ide/src/completion/complete_path.rs | 67 ++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide/src/completion') diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs index f99b1c2c4..d2c758571 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, HasVisibility}; +use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; use ra_syntax::AstNode; use test_utils::tested_by; @@ -52,9 +52,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { if let Some(krate) = krate { let traits_in_scope = ctx.scope().traits_in_scope(); ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { + if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { + return None; + } match item { hir::AssocItem::Function(func) => { - if !func.has_self_param(ctx.db) && context_module.map_or(true, |m| func.is_visible_from(ctx.db, m)) { + if !func.has_self_param(ctx.db) { acc.add_function(ctx, func); } } @@ -65,6 +68,9 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { }); ty.iterate_impl_items(ctx.db, krate, |item| { + if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { + return None; + } match item { hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {} hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), @@ -75,6 +81,9 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { } hir::ModuleDef::Trait(t) => { for item in t.items(ctx.db) { + if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { + continue; + } match item { hir::AssocItem::Function(func) => { if !func.has_self_param(ctx.db) { @@ -537,6 +546,60 @@ mod tests { ); } + #[test] + fn associated_item_visibility() { + assert_debug_snapshot!( + do_reference_completion( + " + //- /lib.rs + struct S; + + mod m { + impl super::S { + pub(super) fn public_method() { } + fn private_method() { } + pub(super) type PublicType = u32; + type PrivateType = u32; + pub(super) const PUBLIC_CONST: u32 = 1; + const PRIVATE_CONST: u32 = 1; + } + } + + fn foo() { let _ = S::<|> } + " + ), + @r###" + [ + CompletionItem { + label: "PUBLIC_CONST", + source_range: [302; 302), + delete: [302; 302), + insert: "PUBLIC_CONST", + kind: Const, + detail: "pub(super) const PUBLIC_CONST: u32 = 1;", + }, + CompletionItem { + label: "PublicType", + source_range: [302; 302), + delete: [302; 302), + insert: "PublicType", + kind: TypeAlias, + detail: "pub(super) type PublicType = u32;", + }, + CompletionItem { + label: "public_method()", + source_range: [302; 302), + delete: [302; 302), + insert: "public_method()$0", + kind: Function, + lookup: "public_method", + detail: "pub(super) fn public_method()", + }, + ] + "### + ); + } + #[test] fn completes_enum_associated_method() { assert_debug_snapshot!( -- cgit v1.2.3