mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Handle visibility for path completion (not in all cases yet)
This commit is contained in:
parent
734e68da4c
commit
d9c77c5453
2 changed files with 51 additions and 5 deletions
|
@ -204,10 +204,20 @@ impl 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()
|
||||
}
|
||||
|
|
|
@ -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 tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[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 @@ mod tests {
|
|||
use self::m::<|>;
|
||||
|
||||
mod m {
|
||||
struct Bar;
|
||||
pub struct Bar;
|
||||
}
|
||||
"
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue