aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-07 22:03:56 +0000
committerFlorian Diebold <[email protected]>2020-03-07 22:03:56 +0000
commit734e68da4ceb1b15b3430302f233d4700d694728 (patch)
treef204df2d3ce6ca801dafb4c68d0c916a7da597eb /crates
parentaff82cf7ac172f213cb5dcca637cb2c5332294c1 (diff)
Handle visibility in method call completion
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model.rs8
-rw-r--r--crates/ra_hir_def/src/data.rs12
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs38
3 files changed, 54 insertions, 4 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 2944926e6..f93b43fb6 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -571,6 +571,14 @@ impl Function {
571 } 571 }
572} 572}
573 573
574impl HasVisibility for Function {
575 fn visibility(&self, db: &impl HirDatabase) -> Visibility {
576 let function_data = db.function_data(self.id);
577 let visibility = &function_data.visibility;
578 visibility.resolve(db, &self.id.resolver(db))
579 }
580}
581
574#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
575pub struct Const { 583pub struct Const {
576 pub(crate) id: ConstId, 584 pub(crate) id: ConstId,
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 9fc43f3fb..8b343af9d 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -7,13 +7,16 @@ use hir_expand::{
7 AstId, InFile, 7 AstId, InFile,
8}; 8};
9use ra_prof::profile; 9use ra_prof::profile;
10use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner}; 10use ra_syntax::ast::{
11 self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner,
12};
11 13
12use crate::{ 14use crate::{
13 db::DefDatabase, 15 db::DefDatabase,
14 path::{path, GenericArgs, Path}, 16 path::{path, GenericArgs, Path},
15 src::HasSource, 17 src::HasSource,
16 type_ref::{Mutability, TypeBound, TypeRef}, 18 type_ref::{Mutability, TypeBound, TypeRef},
19 visibility::RawVisibility,
17 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule, 20 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule,
18 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 21 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
19}; 22};
@@ -26,6 +29,7 @@ pub struct FunctionData {
26 /// True if the first param is `self`. This is relevant to decide whether this 29 /// True if the first param is `self`. This is relevant to decide whether this
27 /// can be called as a method. 30 /// can be called as a method.
28 pub has_self_param: bool, 31 pub has_self_param: bool,
32 pub visibility: RawVisibility,
29} 33}
30 34
31impl FunctionData { 35impl FunctionData {
@@ -72,7 +76,9 @@ impl FunctionData {
72 ret_type 76 ret_type
73 }; 77 };
74 78
75 let sig = FunctionData { name, params, ret_type, has_self_param }; 79 let visibility = RawVisibility::from_ast(db, src.map(|s| s.visibility()));
80
81 let sig = FunctionData { name, params, ret_type, has_self_param, visibility };
76 Arc::new(sig) 82 Arc::new(sig)
77 } 83 }
78} 84}
@@ -230,7 +236,7 @@ impl ConstData {
230 Arc::new(ConstData::new(&node)) 236 Arc::new(ConstData::new(&node))
231 } 237 }
232 238
233 fn new<N: NameOwner + TypeAscriptionOwner>(node: &N) -> ConstData { 239 fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>(node: &N) -> ConstData {
234 let name = node.name().map(|n| n.as_name()); 240 let name = node.name().map(|n| n.as_name());
235 let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); 241 let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
236 ConstData { name, type_ref } 242 ConstData { name, type_ref }
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 9145aa183..acada48ae 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -57,7 +57,10 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
57 let mut seen_methods = FxHashSet::default(); 57 let mut seen_methods = FxHashSet::default();
58 let traits_in_scope = ctx.scope().traits_in_scope(); 58 let traits_in_scope = ctx.scope().traits_in_scope();
59 receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { 59 receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
60 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { 60 if func.has_self_param(ctx.db)
61 && ctx.scope().module().map_or(true, |m| func.is_visible_from(ctx.db, m))
62 && seen_methods.insert(func.name(ctx.db))
63 {
61 acc.add_function(ctx, func); 64 acc.add_function(ctx, func);
62 } 65 }
63 None::<()> 66 None::<()>
@@ -308,6 +311,39 @@ mod tests {
308 } 311 }
309 312
310 #[test] 313 #[test]
314 fn test_method_completion_private() {
315 assert_debug_snapshot!(
316 do_ref_completion(
317 r"
318 struct A {}
319 mod m {
320 impl super::A {
321 fn private_method(&self) {}
322 pub(super) fn the_method(&self) {}
323 }
324 }
325 fn foo(a: A) {
326 a.<|>
327 }
328 ",
329 ),
330 @r###"
331 [
332 CompletionItem {
333 label: "the_method()",
334 source_range: [256; 256),
335 delete: [256; 256),
336 insert: "the_method()$0",
337 kind: Method,
338 lookup: "the_method",
339 detail: "pub(super) fn the_method(&self)",
340 },
341 ]
342 "###
343 );
344 }
345
346 #[test]
311 fn test_trait_method_completion() { 347 fn test_trait_method_completion() {
312 assert_debug_snapshot!( 348 assert_debug_snapshot!(
313 do_ref_completion( 349 do_ref_completion(