mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Handle visibility in method call completion
This commit is contained in:
parent
aff82cf7ac
commit
734e68da4c
3 changed files with 54 additions and 4 deletions
|
@ -571,6 +571,14 @@ impl Function {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasVisibility for Function {
|
||||
fn visibility(&self, db: &impl HirDatabase) -> Visibility {
|
||||
let function_data = db.function_data(self.id);
|
||||
let visibility = &function_data.visibility;
|
||||
visibility.resolve(db, &self.id.resolver(db))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Const {
|
||||
pub(crate) id: ConstId,
|
||||
|
|
|
@ -7,13 +7,16 @@ use hir_expand::{
|
|||
AstId, InFile,
|
||||
};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner};
|
||||
use ra_syntax::ast::{
|
||||
self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
path::{path, GenericArgs, Path},
|
||||
src::HasSource,
|
||||
type_ref::{Mutability, TypeBound, TypeRef},
|
||||
visibility::RawVisibility,
|
||||
AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule,
|
||||
ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
|
||||
};
|
||||
|
@ -26,6 +29,7 @@ pub struct FunctionData {
|
|||
/// True if the first param is `self`. This is relevant to decide whether this
|
||||
/// can be called as a method.
|
||||
pub has_self_param: bool,
|
||||
pub visibility: RawVisibility,
|
||||
}
|
||||
|
||||
impl FunctionData {
|
||||
|
@ -72,7 +76,9 @@ impl FunctionData {
|
|||
ret_type
|
||||
};
|
||||
|
||||
let sig = FunctionData { name, params, ret_type, has_self_param };
|
||||
let visibility = RawVisibility::from_ast(db, src.map(|s| s.visibility()));
|
||||
|
||||
let sig = FunctionData { name, params, ret_type, has_self_param, visibility };
|
||||
Arc::new(sig)
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +236,7 @@ impl ConstData {
|
|||
Arc::new(ConstData::new(&node))
|
||||
}
|
||||
|
||||
fn new<N: NameOwner + TypeAscriptionOwner>(node: &N) -> ConstData {
|
||||
fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>(node: &N) -> ConstData {
|
||||
let name = node.name().map(|n| n.as_name());
|
||||
let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
|
||||
ConstData { name, type_ref }
|
||||
|
|
|
@ -57,7 +57,10 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
|
|||
let mut seen_methods = FxHashSet::default();
|
||||
let traits_in_scope = ctx.scope().traits_in_scope();
|
||||
receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
|
||||
if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
|
||||
if func.has_self_param(ctx.db)
|
||||
&& ctx.scope().module().map_or(true, |m| func.is_visible_from(ctx.db, m))
|
||||
&& seen_methods.insert(func.name(ctx.db))
|
||||
{
|
||||
acc.add_function(ctx, func);
|
||||
}
|
||||
None::<()>
|
||||
|
@ -307,6 +310,39 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_method_completion_private() {
|
||||
assert_debug_snapshot!(
|
||||
do_ref_completion(
|
||||
r"
|
||||
struct A {}
|
||||
mod m {
|
||||
impl super::A {
|
||||
fn private_method(&self) {}
|
||||
pub(super) fn the_method(&self) {}
|
||||
}
|
||||
}
|
||||
fn foo(a: A) {
|
||||
a.<|>
|
||||
}
|
||||
",
|
||||
),
|
||||
@r###"
|
||||
[
|
||||
CompletionItem {
|
||||
label: "the_method()",
|
||||
source_range: [256; 256),
|
||||
delete: [256; 256),
|
||||
insert: "the_method()$0",
|
||||
kind: Method,
|
||||
lookup: "the_method",
|
||||
detail: "pub(super) fn the_method(&self)",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trait_method_completion() {
|
||||
assert_debug_snapshot!(
|
||||
|
|
Loading…
Reference in a new issue