aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-08 09:51:40 +0000
committerFlorian Diebold <[email protected]>2020-03-08 09:51:40 +0000
commitd9c77c54534fcde7c432c6e11746d636d972a20b (patch)
treecdf44c613f55bdd99ab08490b32c185e9915c7bd /crates
parent734e68da4ceb1b15b3430302f233d4700d694728 (diff)
Handle visibility for path completion (not in all cases yet)
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model.rs12
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs44
2 files changed, 51 insertions, 5 deletions
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 {
204 } 204 }
205 205
206 /// Returns a `ModuleScope`: a set of items, visible in this module. 206 /// Returns a `ModuleScope`: a set of items, visible in this module.
207 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { 207 pub fn scope(self, db: &impl HirDatabase, visible_from: Option<Module>) -> Vec<(Name, ScopeDef)> {
208 db.crate_def_map(self.id.krate)[self.id.local_id] 208 db.crate_def_map(self.id.krate)[self.id.local_id]
209 .scope 209 .scope
210 .entries() 210 .entries()
211 .filter_map(|(name, def)| if let Some(m) = visible_from {
212 let filtered = def.filter_visibility(|vis| vis.is_visible_from(db, m.id));
213 if filtered.is_none() && !def.is_none() {
214 None
215 } else {
216 Some((name, filtered))
217 }
218 } else {
219 Some((name, def))
220 })
211 .map(|(name, def)| (name.clone(), def.into())) 221 .map(|(name, def)| (name.clone(), def.into()))
212 .collect() 222 .collect()
213 } 223 }
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 @@
1//! Completion of paths, including when writing a single name. 1//! Completion of paths, including when writing a single name.
2 2
3use hir::{Adt, PathResolution, ScopeDef}; 3use hir::{Adt, PathResolution, ScopeDef, HasVisibility};
4use ra_syntax::AstNode; 4use ra_syntax::AstNode;
5use test_utils::tested_by; 5use test_utils::tested_by;
6 6
@@ -15,9 +15,10 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
15 Some(PathResolution::Def(def)) => def, 15 Some(PathResolution::Def(def)) => def,
16 _ => return, 16 _ => return,
17 }; 17 };
18 let context_module = ctx.scope().module();
18 match def { 19 match def {
19 hir::ModuleDef::Module(module) => { 20 hir::ModuleDef::Module(module) => {
20 let module_scope = module.scope(ctx.db); 21 let module_scope = module.scope(ctx.db, context_module);
21 for (name, def) in module_scope { 22 for (name, def) in module_scope {
22 if ctx.use_item_syntax.is_some() { 23 if ctx.use_item_syntax.is_some() {
23 if let ScopeDef::Unknown = def { 24 if let ScopeDef::Unknown = def {
@@ -53,7 +54,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
53 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { 54 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
54 match item { 55 match item {
55 hir::AssocItem::Function(func) => { 56 hir::AssocItem::Function(func) => {
56 if !func.has_self_param(ctx.db) { 57 if !func.has_self_param(ctx.db) && context_module.map_or(true, |m| func.is_visible_from(ctx.db, m)) {
57 acc.add_function(ctx, func); 58 acc.add_function(ctx, func);
58 } 59 }
59 } 60 }
@@ -170,6 +171,41 @@ mod tests {
170 } 171 }
171 172
172 #[test] 173 #[test]
174 fn path_visibility() {
175 assert_debug_snapshot!(
176 do_reference_completion(
177 r"
178 use self::my::<|>;
179
180 mod my {
181 struct Bar;
182 pub struct Foo;
183 pub use Bar as PublicBar;
184 }
185 "
186 ),
187 @r###"
188 [
189 CompletionItem {
190 label: "Foo",
191 source_range: [31; 31),
192 delete: [31; 31),
193 insert: "Foo",
194 kind: Struct,
195 },
196 CompletionItem {
197 label: "PublicBar",
198 source_range: [31; 31),
199 delete: [31; 31),
200 insert: "PublicBar",
201 kind: Struct,
202 },
203 ]
204 "###
205 );
206 }
207
208 #[test]
173 fn completes_use_item_starting_with_self() { 209 fn completes_use_item_starting_with_self() {
174 assert_debug_snapshot!( 210 assert_debug_snapshot!(
175 do_reference_completion( 211 do_reference_completion(
@@ -177,7 +213,7 @@ mod tests {
177 use self::m::<|>; 213 use self::m::<|>;
178 214
179 mod m { 215 mod m {
180 struct Bar; 216 pub struct Bar;
181 } 217 }
182 " 218 "
183 ), 219 ),