Complete editable private items

This commit is contained in:
Jonas Schievink 2021-07-23 19:57:16 +02:00
parent 75d7da196f
commit 3efdf6861f
6 changed files with 107 additions and 38 deletions

View file

@ -92,6 +92,7 @@ impl ChangeFixture {
let mut default_cfg = CfgOptions::default(); let mut default_cfg = CfgOptions::default();
let mut file_set = FileSet::default(); let mut file_set = FileSet::default();
let mut current_source_root_kind = SourceRootKind::Local;
let source_root_prefix = "/".to_string(); let source_root_prefix = "/".to_string();
let mut file_id = FileId(0); let mut file_id = FileId(0);
let mut roots = Vec::new(); let mut roots = Vec::new();
@ -118,8 +119,13 @@ impl ChangeFixture {
assert!(meta.krate.is_some(), "can't specify deps without naming the crate") assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
} }
if meta.introduce_new_source_root { if let Some(kind) = &meta.introduce_new_source_root {
roots.push(SourceRoot::new_local(mem::take(&mut file_set))); let root = match current_source_root_kind {
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
};
roots.push(root);
current_source_root_kind = *kind;
} }
if let Some(krate) = meta.krate { if let Some(krate) = meta.krate {
@ -197,7 +203,11 @@ impl ChangeFixture {
crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap(); crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap();
} }
} }
roots.push(SourceRoot::new_local(mem::take(&mut file_set))); let root = match current_source_root_kind {
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
};
roots.push(root);
change.set_roots(roots); change.set_roots(roots);
change.set_crate_graph(crate_graph); change.set_crate_graph(crate_graph);
@ -205,6 +215,12 @@ impl ChangeFixture {
} }
} }
#[derive(Debug, Clone, Copy)]
enum SourceRootKind {
Local,
Library,
}
#[derive(Debug)] #[derive(Debug)]
struct FileMeta { struct FileMeta {
path: String, path: String,
@ -213,7 +229,7 @@ struct FileMeta {
cfg: CfgOptions, cfg: CfgOptions,
edition: Edition, edition: Edition,
env: Env, env: Env,
introduce_new_source_root: bool, introduce_new_source_root: Option<SourceRootKind>,
} }
impl From<Fixture> for FileMeta { impl From<Fixture> for FileMeta {
@ -229,7 +245,11 @@ impl From<Fixture> for FileMeta {
cfg, cfg,
edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()), edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()),
env: f.env.into_iter().collect(), env: f.env.into_iter().collect(),
introduce_new_source_root: f.introduce_new_source_root, introduce_new_source_root: f.introduce_new_source_root.map(|kind| match &*kind {
"local" => SourceRootKind::Local,
"library" => SourceRootKind::Library,
invalid => panic!("invalid source root kind '{}'", invalid),
}),
} }
} }
} }

View file

@ -1375,13 +1375,13 @@ fn foo(_: bool) -> bo$0ol { true }
fn test_transitive() { fn test_transitive() {
check( check(
r#" r#"
//- /level3.rs new_source_root: crate:level3 //- /level3.rs new_source_root:local crate:level3
pub struct Fo$0o; pub struct Fo$0o;
//- /level2.rs new_source_root: crate:level2 deps:level3 //- /level2.rs new_source_root:local crate:level2 deps:level3
pub use level3::Foo; pub use level3::Foo;
//- /level1.rs new_source_root: crate:level1 deps:level2 //- /level1.rs new_source_root:local crate:level1 deps:level2
pub use level2::Foo; pub use level2::Foo;
//- /level0.rs new_source_root: crate:level0 deps:level1 //- /level0.rs new_source_root:local crate:level0 deps:level1
pub use level1::Foo; pub use level1::Foo;
"#, "#,
expect![[r#" expect![[r#"
@ -1411,7 +1411,7 @@ macro_rules! foo$0 {
} }
//- /bar.rs //- /bar.rs
foo!(); foo!();
//- /other.rs crate:other deps:lib new_source_root: //- /other.rs crate:other deps:lib new_source_root:local
lib::foo!(); lib::foo!();
"#, "#,
expect![[r#" expect![[r#"

View file

@ -174,36 +174,81 @@ fn foo(a: A) { a.$0() }
fn test_visibility_filtering() { fn test_visibility_filtering() {
check( check(
r#" r#"
mod inner { //- /lib.rs crate:lib new_source_root:local
pub mod m {
pub struct A { pub struct A {
private_field: u32, private_field: u32,
pub pub_field: u32, pub pub_field: u32,
pub(crate) crate_field: u32, pub(crate) crate_field: u32,
pub(crate) super_field: u32, pub(super) super_field: u32,
} }
} }
fn foo(a: inner::A) { a.$0 } //- /main.rs crate:main deps:lib new_source_root:local
fn foo(a: lib::m::A) { a.$0 }
"#, "#,
expect![[r#" expect![[r#"
fd pub_field u32 fd private_field u32
fd crate_field u32 fd pub_field u32
fd super_field u32 fd crate_field u32
fd super_field u32
"#]], "#]],
); );
check( check(
r#" r#"
struct A {} //- /lib.rs crate:lib new_source_root:library
pub mod m {
pub struct A {
private_field: u32,
pub pub_field: u32,
pub(crate) crate_field: u32,
pub(super) super_field: u32,
}
}
//- /main.rs crate:main deps:lib new_source_root:local
fn foo(a: lib::m::A) { a.$0 }
"#,
expect![[r#"
fd pub_field u32
"#]],
);
check(
r#"
//- /lib.rs crate:lib new_source_root:local
pub struct A {}
mod m { mod m {
impl super::A { impl super::A {
fn private_method(&self) {} fn private_method(&self) {}
pub(crate) fn the_method(&self) {} pub(crate) fn crate_method(&self) {}
pub fn pub_method(&self) {}
} }
} }
fn foo(a: A) { a.$0 } //- /main.rs crate:main deps:lib new_source_root:local
fn foo(a: lib::A) { a.$0 }
"#, "#,
expect![[r#" expect![[r#"
me the_method() fn(&self) me private_method() fn(&self)
me crate_method() fn(&self)
me pub_method() fn(&self)
"#]],
);
check(
r#"
//- /lib.rs crate:lib new_source_root:library
pub struct A {}
mod m {
impl super::A {
fn private_method(&self) {}
pub(crate) fn crate_method(&self) {}
pub fn pub_method(&self) {}
}
}
//- /main.rs crate:main deps:lib new_source_root:local
fn foo(a: lib::A) { a.$0 }
"#,
expect![[r#"
me pub_method() fn(&self)
"#]], "#]],
); );
} }

View file

@ -259,25 +259,25 @@ mod tests {
fn associated_item_visibility() { fn associated_item_visibility() {
check( check(
r#" r#"
struct S; //- /lib.rs crate:lib new_source_root:library
pub struct S;
mod m { impl S {
impl super::S { pub fn public_method() { }
pub(crate) fn public_method() { } fn private_method() { }
fn private_method() { } pub type PublicType = u32;
pub(crate) type PublicType = u32; type PrivateType = u32;
type PrivateType = u32; pub const PUBLIC_CONST: u32 = 1;
pub(crate) const PUBLIC_CONST: u32 = 1; const PRIVATE_CONST: u32 = 1;
const PRIVATE_CONST: u32 = 1;
}
} }
fn foo() { let _ = S::$0 } //- /main.rs crate:main deps:lib new_source_root:local
fn foo() { let _ = lib::S::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn public_method() fn() fn public_method() fn()
ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; ct PUBLIC_CONST pub const PUBLIC_CONST: u32 = 1;
ta PublicType pub(crate) type PublicType = u32; ta PublicType pub type PublicType = u32;
"#]], "#]],
); );
} }

View file

@ -1,5 +1,6 @@
//! See `CompletionContext` structure. //! See `CompletionContext` structure.
use base_db::SourceDatabaseExt;
use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
use ide_db::{ use ide_db::{
base_db::{FilePosition, SourceDatabase}, base_db::{FilePosition, SourceDatabase},
@ -380,8 +381,11 @@ impl<'a> CompletionContext<'a> {
None => return false, None => return false,
}; };
if !vis.is_visible_from(self.db, module.into()) { if !vis.is_visible_from(self.db, module.into()) {
// FIXME: if the definition location is editable, also show private items // If the definition location is editable, also show private items
return false; let root_file = defining_crate.root_file(self.db);
let source_root_id = self.db.file_source_root(root_file);
let is_editable = !self.db.source_root(source_root_id).is_library;
return is_editable;
} }
if module.krate() != defining_crate && attrs.has_doc_hidden() { if module.krate() != defining_crate && attrs.has_doc_hidden() {

View file

@ -74,7 +74,7 @@ pub struct Fixture {
pub cfg_key_values: Vec<(String, String)>, pub cfg_key_values: Vec<(String, String)>,
pub edition: Option<String>, pub edition: Option<String>,
pub env: FxHashMap<String, String>, pub env: FxHashMap<String, String>,
pub introduce_new_source_root: bool, pub introduce_new_source_root: Option<String>,
} }
pub struct MiniCore { pub struct MiniCore {
@ -162,7 +162,7 @@ impl Fixture {
let mut cfg_atoms = Vec::new(); let mut cfg_atoms = Vec::new();
let mut cfg_key_values = Vec::new(); let mut cfg_key_values = Vec::new();
let mut env = FxHashMap::default(); let mut env = FxHashMap::default();
let mut introduce_new_source_root = false; let mut introduce_new_source_root = None;
for component in components[1..].iter() { for component in components[1..].iter() {
let (key, value) = component let (key, value) = component
.split_once(':') .split_once(':')
@ -186,7 +186,7 @@ impl Fixture {
} }
} }
} }
"new_source_root" => introduce_new_source_root = true, "new_source_root" => introduce_new_source_root = Some(value.to_string()),
_ => panic!("bad component: {:?}", component), _ => panic!("bad component: {:?}", component),
} }
} }