]> git.lizzy.rs Git - rust.git/commitdiff
Handle visibility for path completion (not in all cases yet)
authorFlorian Diebold <flodiebold@gmail.com>
Sun, 8 Mar 2020 09:51:40 +0000 (10:51 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Sun, 8 Mar 2020 09:51:40 +0000 (10:51 +0100)
crates/ra_hir/src/code_model.rs
crates/ra_ide/src/completion/complete_path.rs

index f93b43fb64e1018f1d9889ca398ce3b4a00072f8..4d1e8f921eb0841a00b1acfcda50f0d6b4ef7ac0 100644 (file)
@@ -204,10 +204,20 @@ pub fn path_to_root(self, db: &impl HirDatabase) -> Vec<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<Module>) -> 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()
     }
index 1a9699466ec53c95ef1822707c7659c76ff833cd..f99b1c2c45cc0e7974a37e8a9c8b5fdf3c28c36e 100644 (file)
@@ -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 my {
         );
     }
 
+    #[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 @@ fn completes_use_item_starting_with_self() {
                 use self::m::<|>;
 
                 mod m {
-                    struct Bar;
+                    pub struct Bar;
                 }
                 "
             ),