aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src/assists/change_visibility.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_editor/src/assists/change_visibility.rs')
-rw-r--r--crates/ra_editor/src/assists/change_visibility.rs55
1 files changed, 37 insertions, 18 deletions
diff --git a/crates/ra_editor/src/assists/change_visibility.rs b/crates/ra_editor/src/assists/change_visibility.rs
index e2cd9ffd1..ac75f635e 100644
--- a/crates/ra_editor/src/assists/change_visibility.rs
+++ b/crates/ra_editor/src/assists/change_visibility.rs
@@ -1,29 +1,39 @@
1use ra_syntax::{ 1use ra_syntax::{
2 SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF}, 2 AstNode,
3 ast::{self, VisibilityOwner, NameOwner},
4 SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF, IDENT},
3}; 5};
4 6
5use crate::assists::{AssistCtx, Assist}; 7use crate::assists::{AssistCtx, Assist};
6 8
7pub fn change_visibility(ctx: AssistCtx) -> Option<Assist> { 9pub fn change_visibility(ctx: AssistCtx) -> Option<Assist> {
8 let keyword = ctx.leaf_at_offset().find(|leaf| match leaf.kind() { 10 let offset = if let Some(keyword) = ctx.leaf_at_offset().find(|leaf| match leaf.kind() {
9 FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true, 11 FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true,
10 _ => false, 12 _ => false,
11 })?; 13 }) {
12 let parent = keyword.parent()?; 14 let parent = keyword.parent()?;
13 let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF]; 15 let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF];
14 // Parent is not a definition, can't add visibility 16 // Parent is not a definition, can't add visibility
15 if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) { 17 if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) {
16 return None; 18 return None;
17 } 19 }
18 // Already have visibility, do nothing 20 // Already have visibility, do nothing
19 if parent.children().any(|child| child.kind() == VISIBILITY) { 21 if parent.children().any(|child| child.kind() == VISIBILITY) {
20 return None; 22 return None;
21 } 23 }
24 parent.range().start()
25 } else {
26 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?;
27 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?;
28 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() {
29 return None;
30 }
31 field.syntax().range().start()
32 };
22 33
23 let node_start = parent.range().start(); 34 ctx.build("make pub(crate)", |edit| {
24 ctx.build("make pub crate", |edit| { 35 edit.insert(offset, "pub(crate) ");
25 edit.insert(node_start, "pub(crate) "); 36 edit.set_cursor(offset);
26 edit.set_cursor(node_start);
27 }) 37 })
28} 38}
29 39
@@ -33,7 +43,7 @@ mod tests {
33 use crate::assists::check_assist; 43 use crate::assists::check_assist;
34 44
35 #[test] 45 #[test]
36 fn test_change_visibility() { 46 fn change_visibility_adds_pub_crate_to_items() {
37 check_assist( 47 check_assist(
38 change_visibility, 48 change_visibility,
39 "<|>fn foo() {}", 49 "<|>fn foo() {}",
@@ -66,4 +76,13 @@ mod tests {
66 "<|>pub(crate) unsafe fn foo() {}", 76 "<|>pub(crate) unsafe fn foo() {}",
67 ); 77 );
68 } 78 }
79
80 #[test]
81 fn change_visibility_works_with_struct_fields() {
82 check_assist(
83 change_visibility,
84 "struct S { <|>field: u32 }",
85 "struct S { <|>pub(crate) field: u32 }",
86 )
87 }
69} 88}