2022-11-11 04:56:47 -06:00
|
|
|
use hir::{db::HirDatabase, HasSource, HasVisibility, ModuleDef, PathResolution, ScopeDef};
|
2020-10-24 03:39:57 -05:00
|
|
|
use ide_db::base_db::FileId;
|
2020-10-18 10:04:12 -05:00
|
|
|
use syntax::{
|
2023-07-09 19:52:06 -05:00
|
|
|
ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _},
|
|
|
|
AstNode, TextRange,
|
2020-10-18 10:04:12 -05:00
|
|
|
};
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
2020-05-20 06:33:13 -05:00
|
|
|
|
|
|
|
// FIXME: this really should be a fix for diagnostic, rather than an assist.
|
|
|
|
|
|
|
|
// Assist: fix_visibility
|
|
|
|
//
|
|
|
|
// Makes inaccessible item public.
|
|
|
|
//
|
|
|
|
// ```
|
|
|
|
// mod m {
|
|
|
|
// fn frobnicate() {}
|
|
|
|
// }
|
|
|
|
// fn main() {
|
2022-11-11 04:56:47 -06:00
|
|
|
// m::frobnicate$0();
|
2020-05-20 06:33:13 -05:00
|
|
|
// }
|
|
|
|
// ```
|
|
|
|
// ->
|
|
|
|
// ```
|
|
|
|
// mod m {
|
2020-05-20 07:13:17 -05:00
|
|
|
// $0pub(crate) fn frobnicate() {}
|
2020-05-20 06:33:13 -05:00
|
|
|
// }
|
|
|
|
// fn main() {
|
2022-11-11 04:56:47 -06:00
|
|
|
// m::frobnicate();
|
2020-05-20 06:33:13 -05:00
|
|
|
// }
|
|
|
|
// ```
|
2022-07-20 08:02:08 -05:00
|
|
|
pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
2020-05-20 06:33:13 -05:00
|
|
|
add_vis_to_referenced_module_def(acc, ctx)
|
|
|
|
.or_else(|| add_vis_to_referenced_record_field(acc, ctx))
|
|
|
|
}
|
|
|
|
|
2022-07-20 08:02:08 -05:00
|
|
|
fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
2020-05-20 06:33:13 -05:00
|
|
|
let path: ast::Path = ctx.find_node_at_offset()?;
|
2022-11-11 04:56:47 -06:00
|
|
|
let qualifier = path.qualifier()?;
|
|
|
|
let name_ref = path.segment()?.name_ref()?;
|
|
|
|
let qualifier_res = ctx.sema.resolve_path(&qualifier)?;
|
2023-07-03 13:34:09 -05:00
|
|
|
let PathResolution::Def(ModuleDef::Module(module)) = qualifier_res else {
|
|
|
|
return None;
|
|
|
|
};
|
2022-11-11 04:56:47 -06:00
|
|
|
let (_, def) = module
|
|
|
|
.scope(ctx.db(), None)
|
|
|
|
.into_iter()
|
|
|
|
.find(|(name, _)| name.to_smol_str() == name_ref.text().as_str())?;
|
2023-07-03 13:34:09 -05:00
|
|
|
let ScopeDef::ModuleDef(def) = def else {
|
|
|
|
return None;
|
|
|
|
};
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2022-03-31 04:12:08 -05:00
|
|
|
let current_module = ctx.sema.scope(path.syntax())?.module();
|
2020-07-01 02:14:23 -05:00
|
|
|
let target_module = def.module(ctx.db())?;
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2021-07-20 09:49:02 -05:00
|
|
|
if def.visibility(ctx.db()).is_visible_from(ctx.db(), current_module.into()) {
|
2020-05-20 06:33:13 -05:00
|
|
|
return None;
|
|
|
|
};
|
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
let (vis_owner, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?;
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
let missing_visibility = if current_module.krate() == target_module.krate() {
|
|
|
|
make::visibility_pub_crate()
|
|
|
|
} else {
|
|
|
|
make::visibility_pub()
|
|
|
|
};
|
2020-05-20 06:33:13 -05:00
|
|
|
|
|
|
|
let assist_label = match target_name {
|
2022-10-10 10:04:38 -05:00
|
|
|
None => format!("Change visibility to {missing_visibility}"),
|
2023-05-24 11:04:29 -05:00
|
|
|
Some(name) => {
|
|
|
|
format!("Change visibility of {} to {missing_visibility}", name.display(ctx.db()))
|
|
|
|
}
|
2020-05-20 06:33:13 -05:00
|
|
|
};
|
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |edit| {
|
|
|
|
edit.edit_file(target_file);
|
|
|
|
|
|
|
|
let vis_owner = edit.make_mut(vis_owner);
|
|
|
|
vis_owner.set_visibility(missing_visibility.clone_for_update());
|
|
|
|
|
|
|
|
if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
|
|
|
|
edit.add_tabstop_before(cap, vis);
|
2020-05-20 07:13:17 -05:00
|
|
|
}
|
2020-05-20 06:33:13 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-07-20 08:02:08 -05:00
|
|
|
fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
2020-07-30 09:21:30 -05:00
|
|
|
let record_field: ast::RecordExprField = ctx.find_node_at_offset()?;
|
2021-05-23 16:54:35 -05:00
|
|
|
let (record_field_def, _, _) = ctx.sema.resolve_record_field(&record_field)?;
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2022-03-31 04:12:08 -05:00
|
|
|
let current_module = ctx.sema.scope(record_field.syntax())?.module();
|
2020-07-01 02:14:23 -05:00
|
|
|
let visibility = record_field_def.visibility(ctx.db());
|
|
|
|
if visibility.is_visible_from(ctx.db(), current_module.into()) {
|
2020-05-20 06:33:13 -05:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2020-07-01 02:14:23 -05:00
|
|
|
let parent = record_field_def.parent_def(ctx.db());
|
|
|
|
let parent_name = parent.name(ctx.db());
|
|
|
|
let target_module = parent.module(ctx.db());
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2020-12-31 22:02:39 -06:00
|
|
|
let in_file_source = record_field_def.source(ctx.db())?;
|
2023-07-11 16:29:21 -05:00
|
|
|
let (vis_owner, target) = match in_file_source.value {
|
2020-05-20 06:33:13 -05:00
|
|
|
hir::FieldSource::Named(it) => {
|
2023-07-11 16:29:21 -05:00
|
|
|
let range = it.syntax().text_range();
|
|
|
|
(ast::AnyHasVisibility::new(it), range)
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
hir::FieldSource::Pos(it) => {
|
2023-07-11 16:29:21 -05:00
|
|
|
let range = it.syntax().text_range();
|
|
|
|
(ast::AnyHasVisibility::new(it), range)
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
let missing_visibility = if current_module.krate() == target_module.krate() {
|
|
|
|
make::visibility_pub_crate()
|
|
|
|
} else {
|
|
|
|
make::visibility_pub()
|
|
|
|
};
|
2020-07-01 02:14:23 -05:00
|
|
|
let target_file = in_file_source.file_id.original_file(ctx.db());
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2020-07-01 02:14:23 -05:00
|
|
|
let target_name = record_field_def.name(ctx.db());
|
2023-05-24 11:04:29 -05:00
|
|
|
let assist_label = format!(
|
|
|
|
"Change visibility of {}.{} to {missing_visibility}",
|
|
|
|
parent_name.display(ctx.db()),
|
|
|
|
target_name.display(ctx.db())
|
|
|
|
);
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |edit| {
|
|
|
|
edit.edit_file(target_file);
|
|
|
|
|
|
|
|
let vis_owner = edit.make_mut(vis_owner);
|
|
|
|
vis_owner.set_visibility(missing_visibility.clone_for_update());
|
|
|
|
|
|
|
|
if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
|
|
|
|
edit.add_tabstop_before(cap, vis);
|
2020-05-20 07:13:17 -05:00
|
|
|
}
|
2020-05-20 06:33:13 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn target_data_for_def(
|
|
|
|
db: &dyn HirDatabase,
|
|
|
|
def: hir::ModuleDef,
|
2023-07-09 19:52:06 -05:00
|
|
|
) -> Option<(ast::AnyHasVisibility, TextRange, FileId, Option<hir::Name>)> {
|
2020-05-20 06:33:13 -05:00
|
|
|
fn offset_target_and_file_id<S, Ast>(
|
|
|
|
db: &dyn HirDatabase,
|
|
|
|
x: S,
|
2023-07-09 19:52:06 -05:00
|
|
|
) -> Option<(ast::AnyHasVisibility, TextRange, FileId)>
|
2020-05-20 06:33:13 -05:00
|
|
|
where
|
|
|
|
S: HasSource<Ast = Ast>,
|
2021-09-27 05:54:24 -05:00
|
|
|
Ast: AstNode + ast::HasVisibility,
|
2020-05-20 06:33:13 -05:00
|
|
|
{
|
2020-12-31 23:52:59 -06:00
|
|
|
let source = x.source(db)?;
|
2020-05-20 06:33:13 -05:00
|
|
|
let in_file_syntax = source.syntax();
|
|
|
|
let file_id = in_file_syntax.file_id;
|
2023-07-11 16:29:21 -05:00
|
|
|
let range = in_file_syntax.value.text_range();
|
|
|
|
Some((ast::AnyHasVisibility::new(source.value), range, file_id.original_file(db.upcast())))
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let target_name;
|
2023-07-09 19:52:06 -05:00
|
|
|
let (offset, target, target_file) = match def {
|
2020-05-20 06:33:13 -05:00
|
|
|
hir::ModuleDef::Function(f) => {
|
|
|
|
target_name = Some(f.name(db));
|
2020-12-31 23:52:59 -06:00
|
|
|
offset_target_and_file_id(db, f)?
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
hir::ModuleDef::Adt(adt) => {
|
|
|
|
target_name = Some(adt.name(db));
|
|
|
|
match adt {
|
2020-12-31 23:52:59 -06:00
|
|
|
hir::Adt::Struct(s) => offset_target_and_file_id(db, s)?,
|
|
|
|
hir::Adt::Union(u) => offset_target_and_file_id(db, u)?,
|
|
|
|
hir::Adt::Enum(e) => offset_target_and_file_id(db, e)?,
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
hir::ModuleDef::Const(c) => {
|
|
|
|
target_name = c.name(db);
|
2020-12-31 23:52:59 -06:00
|
|
|
offset_target_and_file_id(db, c)?
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
hir::ModuleDef::Static(s) => {
|
2021-11-10 15:02:50 -06:00
|
|
|
target_name = Some(s.name(db));
|
2020-12-31 23:52:59 -06:00
|
|
|
offset_target_and_file_id(db, s)?
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
hir::ModuleDef::Trait(t) => {
|
|
|
|
target_name = Some(t.name(db));
|
2020-12-31 23:52:59 -06:00
|
|
|
offset_target_and_file_id(db, t)?
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
2023-03-03 09:24:07 -06:00
|
|
|
hir::ModuleDef::TraitAlias(t) => {
|
|
|
|
target_name = Some(t.name(db));
|
|
|
|
offset_target_and_file_id(db, t)?
|
|
|
|
}
|
2020-05-20 06:33:13 -05:00
|
|
|
hir::ModuleDef::TypeAlias(t) => {
|
|
|
|
target_name = Some(t.name(db));
|
2020-12-31 23:52:59 -06:00
|
|
|
offset_target_and_file_id(db, t)?
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
hir::ModuleDef::Module(m) => {
|
|
|
|
target_name = m.name(db);
|
|
|
|
let in_file_source = m.declaration_source(db)?;
|
|
|
|
let file_id = in_file_source.file_id.original_file(db.upcast());
|
2023-07-11 16:29:21 -05:00
|
|
|
let range = in_file_source.value.syntax().text_range();
|
|
|
|
(ast::AnyHasVisibility::new(in_file_source.value), range, file_id)
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
2022-03-08 16:52:26 -06:00
|
|
|
// FIXME
|
|
|
|
hir::ModuleDef::Macro(_) => return None,
|
2020-05-20 06:33:13 -05:00
|
|
|
// Enum variants can't be private, we can't modify builtin types
|
2020-12-20 01:05:24 -06:00
|
|
|
hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
|
2020-05-20 06:33:13 -05:00
|
|
|
};
|
|
|
|
|
2023-07-09 19:52:06 -05:00
|
|
|
Some((offset, target, target_file, target_name))
|
2020-05-20 06:33:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_fn() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { fn foo() {} }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::foo$0() } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) fn foo() {} }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::foo() } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub fn foo() {} }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::foo$0() } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_adt_in_submodule() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { struct Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) struct Foo; }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::Foo } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub struct Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { enum Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) enum Foo; }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::Foo } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub enum Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { union Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) union Foo; }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::Foo } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub union Foo; }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_adt_in_other_file() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /main.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo$0 }
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
struct Foo;
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"$0pub(crate) struct Foo;
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_struct_field() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub struct Foo { bar: (), } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { pub struct Foo { $0pub(crate) bar: (), } }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::Foo { bar: () }; } ",
|
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub struct Foo { bar: () }
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"pub struct Foo { $0pub(crate) bar: () }
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub struct Foo { pub bar: (), } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub struct Foo { pub bar: () }
|
|
|
|
",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_enum_variant_field() {
|
2020-10-09 13:42:17 -05:00
|
|
|
// Enum variants, as well as their fields, always get the enum's visibility. In fact, rustc
|
|
|
|
// rejects any visibility specifiers on them, so this assist should never fire on them.
|
|
|
|
check_assist_not_applicable(
|
2020-05-20 06:33:13 -05:00
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub enum Foo { Bar { bar: () } } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo::Bar { $0bar: () }; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
2020-10-09 13:42:17 -05:00
|
|
|
check_assist_not_applicable(
|
2020-05-20 06:33:13 -05:00
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo::Bar { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub enum Foo { Bar { bar: () } }
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub struct Foo { pub bar: (), } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub struct Foo { pub bar: () }
|
|
|
|
",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_union_field() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub union Foo { bar: (), } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { pub union Foo { $0pub(crate) bar: (), } }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::Foo { bar: () }; } ",
|
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub union Foo { bar: () }
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"pub union Foo { $0pub(crate) bar: () }
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub union Foo { pub bar: (), } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /lib.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::Foo { $0bar: () }; }
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
pub union Foo { pub bar: () }
|
|
|
|
",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_const() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { const FOO: () = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::FOO$0 } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) const FOO: () = (); }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::FOO } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub const FOO: () = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::FOO$0 } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_static() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { static FOO: () = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::FOO$0 } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) static FOO: () = (); }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::FOO } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub static FOO: () = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::FOO$0 } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_trait() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { trait Foo { fn foo(&self) {} } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { let x: &dyn foo::$0Foo; } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) trait Foo { fn foo(&self) {} } }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { let x: &dyn foo::Foo; } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub trait Foo { fn foo(&self) {} } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { let x: &dyn foo::Foo$0; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_type_alias() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { type Foo = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { let x: foo::Foo$0; } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) type Foo = (); }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { let x: foo::Foo; } ",
|
|
|
|
);
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub type Foo = (); }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { let x: foo::Foo$0; } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_module() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { mod bar { fn bar() {} } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::bar$0::bar(); } ",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"mod foo { $0pub(crate) mod bar { fn bar() {} } }
|
2020-05-20 06:33:13 -05:00
|
|
|
fn main() { foo::bar::bar(); } ",
|
|
|
|
);
|
|
|
|
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /main.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::bar$0::baz(); }
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
mod bar {
|
|
|
|
pub fn baz() {}
|
|
|
|
}
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"$0pub(crate) mod bar {
|
2020-05-20 06:33:13 -05:00
|
|
|
pub fn baz() {}
|
|
|
|
}
|
|
|
|
",
|
|
|
|
);
|
|
|
|
|
|
|
|
check_assist_not_applicable(
|
|
|
|
fix_visibility,
|
|
|
|
r"mod foo { pub mod bar { pub fn bar() {} } }
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::bar$0::bar(); } ",
|
2020-05-20 06:33:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_inline_module_in_other_file() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /main.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::bar$0::baz(); }
|
2020-06-23 15:27:24 -05:00
|
|
|
|
|
|
|
//- /foo.rs
|
|
|
|
mod bar;
|
|
|
|
//- /foo/bar.rs
|
|
|
|
pub fn baz() {}
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"$0pub(crate) mod bar;
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_module_declaration_in_other_file() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /main.rs
|
|
|
|
mod foo;
|
2021-01-06 14:15:48 -06:00
|
|
|
fn main() { foo::bar$0>::baz(); }
|
2020-05-20 06:33:13 -05:00
|
|
|
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /foo.rs
|
|
|
|
mod bar {
|
|
|
|
pub fn baz() {}
|
|
|
|
}
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"$0pub(crate) mod bar {
|
2020-05-20 06:33:13 -05:00
|
|
|
pub fn baz() {}
|
|
|
|
}
|
|
|
|
",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn adds_pub_when_target_is_in_another_crate() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
2020-06-23 15:27:24 -05:00
|
|
|
r"
|
|
|
|
//- /main.rs crate:a deps:foo
|
2021-01-06 14:15:48 -06:00
|
|
|
foo::Bar$0
|
2020-06-23 15:27:24 -05:00
|
|
|
//- /lib.rs crate:foo
|
|
|
|
struct Bar;
|
|
|
|
",
|
2020-05-20 07:13:17 -05:00
|
|
|
r"$0pub struct Bar;
|
2020-05-20 06:33:13 -05:00
|
|
|
",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-07-12 05:18:42 -05:00
|
|
|
#[test]
|
|
|
|
fn replaces_pub_crate_with_pub() {
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"
|
|
|
|
//- /main.rs crate:a deps:foo
|
2021-01-06 14:15:48 -06:00
|
|
|
foo::Bar$0
|
2020-07-12 05:18:42 -05:00
|
|
|
//- /lib.rs crate:foo
|
|
|
|
pub(crate) struct Bar;
|
|
|
|
",
|
|
|
|
r"$0pub struct Bar;
|
|
|
|
",
|
|
|
|
);
|
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
|
|
|
r"
|
|
|
|
//- /main.rs crate:a deps:foo
|
|
|
|
fn main() {
|
2021-01-06 14:15:48 -06:00
|
|
|
foo::Foo { $0bar: () };
|
2020-07-12 05:18:42 -05:00
|
|
|
}
|
|
|
|
//- /lib.rs crate:foo
|
|
|
|
pub struct Foo { pub(crate) bar: () }
|
|
|
|
",
|
|
|
|
r"pub struct Foo { $0pub bar: () }
|
|
|
|
",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-05-20 06:33:13 -05:00
|
|
|
#[test]
|
|
|
|
fn fix_visibility_of_reexport() {
|
2021-06-14 14:55:05 -05:00
|
|
|
// FIXME: broken test, this should fix visibility of the re-export
|
|
|
|
// rather than the struct.
|
2020-05-20 06:33:13 -05:00
|
|
|
check_assist(
|
|
|
|
fix_visibility,
|
2021-06-14 14:55:05 -05:00
|
|
|
r#"
|
|
|
|
mod foo {
|
|
|
|
use bar::Baz;
|
|
|
|
mod bar { pub(super) struct Baz; }
|
|
|
|
}
|
|
|
|
foo::Baz$0
|
|
|
|
"#,
|
|
|
|
r#"
|
|
|
|
mod foo {
|
|
|
|
use bar::Baz;
|
|
|
|
mod bar { $0pub(crate) struct Baz; }
|
|
|
|
}
|
|
|
|
foo::Baz
|
|
|
|
"#,
|
2020-05-20 06:33:13 -05:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|