diff options
Diffstat (limited to 'crates/ra_editor/src/assists')
-rw-r--r-- | crates/ra_editor/src/assists/change_visibility.rs | 55 |
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 @@ | |||
1 | use ra_syntax::{ | 1 | use 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 | ||
5 | use crate::assists::{AssistCtx, Assist}; | 7 | use crate::assists::{AssistCtx, Assist}; |
6 | 8 | ||
7 | pub fn change_visibility(ctx: AssistCtx) -> Option<Assist> { | 9 | pub 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 | } |