aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/change_visibility.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/change_visibility.rs')
-rw-r--r--crates/ra_assists/src/handlers/change_visibility.rs96
1 files changed, 55 insertions, 41 deletions
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs
index 44f6a1dae..c21d75be0 100644
--- a/crates/ra_assists/src/handlers/change_visibility.rs
+++ b/crates/ra_assists/src/handlers/change_visibility.rs
@@ -7,9 +7,9 @@ use ra_syntax::{
7 }, 7 },
8 SyntaxNode, TextSize, T, 8 SyntaxNode, TextSize, T,
9}; 9};
10use test_utils::mark;
10 11
11use crate::{Assist, AssistCtx, AssistId}; 12use crate::{AssistContext, AssistId, Assists};
12use test_utils::tested_by;
13 13
14// Assist: change_visibility 14// Assist: change_visibility
15// 15//
@@ -22,14 +22,14 @@ use test_utils::tested_by;
22// ``` 22// ```
23// pub(crate) fn frobnicate() {} 23// pub(crate) fn frobnicate() {}
24// ``` 24// ```
25pub(crate) fn change_visibility(ctx: AssistCtx) -> Option<Assist> { 25pub(crate) fn change_visibility(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
26 if let Some(vis) = ctx.find_node_at_offset::<ast::Visibility>() { 26 if let Some(vis) = ctx.find_node_at_offset::<ast::Visibility>() {
27 return change_vis(ctx, vis); 27 return change_vis(acc, vis);
28 } 28 }
29 add_vis(ctx) 29 add_vis(acc, ctx)
30} 30}
31 31
32fn add_vis(ctx: AssistCtx) -> Option<Assist> { 32fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
33 let item_keyword = ctx.token_at_offset().find(|leaf| match leaf.kind() { 33 let item_keyword = ctx.token_at_offset().find(|leaf| match leaf.kind() {
34 T![const] | T![fn] | T![mod] | T![struct] | T![enum] | T![trait] => true, 34 T![const] | T![fn] | T![mod] | T![struct] | T![enum] | T![trait] => true,
35 _ => false, 35 _ => false,
@@ -47,23 +47,27 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
47 return None; 47 return None;
48 } 48 }
49 (vis_offset(&parent), keyword.text_range()) 49 (vis_offset(&parent), keyword.text_range())
50 } else { 50 } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
51 let field_name: ast::Name = ctx.find_node_at_offset()?;
52 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?; 51 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
53 if field.name()? != field_name { 52 if field.name()? != field_name {
54 tested_by!(change_visibility_field_false_positive); 53 mark::hit!(change_visibility_field_false_positive);
55 return None; 54 return None;
56 } 55 }
57 if field.visibility().is_some() { 56 if field.visibility().is_some() {
58 return None; 57 return None;
59 } 58 }
60 (vis_offset(field.syntax()), field_name.syntax().text_range()) 59 (vis_offset(field.syntax()), field_name.syntax().text_range())
60 } else if let Some(field) = ctx.find_node_at_offset::<ast::TupleFieldDef>() {
61 if field.visibility().is_some() {
62 return None;
63 }
64 (vis_offset(field.syntax()), field.syntax().text_range())
65 } else {
66 return None;
61 }; 67 };
62 68
63 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| { 69 acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| {
64 edit.target(target);
65 edit.insert(offset, "pub(crate) "); 70 edit.insert(offset, "pub(crate) ");
66 edit.set_cursor(offset);
67 }) 71 })
68} 72}
69 73
@@ -78,49 +82,49 @@ fn vis_offset(node: &SyntaxNode) -> TextSize {
78 .unwrap_or_else(|| node.text_range().start()) 82 .unwrap_or_else(|| node.text_range().start())
79} 83}
80 84
81fn change_vis(ctx: AssistCtx, vis: ast::Visibility) -> Option<Assist> { 85fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
82 if vis.syntax().text() == "pub" { 86 if vis.syntax().text() == "pub" {
83 return ctx.add_assist( 87 let target = vis.syntax().text_range();
88 return acc.add(
84 AssistId("change_visibility"), 89 AssistId("change_visibility"),
85 "Change Visibility to pub(crate)", 90 "Change Visibility to pub(crate)",
91 target,
86 |edit| { 92 |edit| {
87 edit.target(vis.syntax().text_range());
88 edit.replace(vis.syntax().text_range(), "pub(crate)"); 93 edit.replace(vis.syntax().text_range(), "pub(crate)");
89 edit.set_cursor(vis.syntax().text_range().start())
90 }, 94 },
91 ); 95 );
92 } 96 }
93 if vis.syntax().text() == "pub(crate)" { 97 if vis.syntax().text() == "pub(crate)" {
94 return ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub", |edit| { 98 let target = vis.syntax().text_range();
95 edit.target(vis.syntax().text_range()); 99 return acc.add(
96 edit.replace(vis.syntax().text_range(), "pub"); 100 AssistId("change_visibility"),
97 edit.set_cursor(vis.syntax().text_range().start()); 101 "Change visibility to pub",
98 }); 102 target,
103 |edit| {
104 edit.replace(vis.syntax().text_range(), "pub");
105 },
106 );
99 } 107 }
100 None 108 None
101} 109}
102 110
103#[cfg(test)] 111#[cfg(test)]
104mod tests { 112mod tests {
105 use test_utils::covers; 113 use test_utils::mark;
106 114
107 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target}; 115 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
108 116
109 use super::*; 117 use super::*;
110 118
111 #[test] 119 #[test]
112 fn change_visibility_adds_pub_crate_to_items() { 120 fn change_visibility_adds_pub_crate_to_items() {
113 check_assist(change_visibility, "<|>fn foo() {}", "<|>pub(crate) fn foo() {}"); 121 check_assist(change_visibility, "<|>fn foo() {}", "pub(crate) fn foo() {}");
114 check_assist(change_visibility, "f<|>n foo() {}", "<|>pub(crate) fn foo() {}"); 122 check_assist(change_visibility, "f<|>n foo() {}", "pub(crate) fn foo() {}");
115 check_assist(change_visibility, "<|>struct Foo {}", "<|>pub(crate) struct Foo {}"); 123 check_assist(change_visibility, "<|>struct Foo {}", "pub(crate) struct Foo {}");
116 check_assist(change_visibility, "<|>mod foo {}", "<|>pub(crate) mod foo {}"); 124 check_assist(change_visibility, "<|>mod foo {}", "pub(crate) mod foo {}");
117 check_assist(change_visibility, "<|>trait Foo {}", "<|>pub(crate) trait Foo {}"); 125 check_assist(change_visibility, "<|>trait Foo {}", "pub(crate) trait Foo {}");
118 check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); 126 check_assist(change_visibility, "m<|>od {}", "pub(crate) mod {}");
119 check_assist( 127 check_assist(change_visibility, "unsafe f<|>n foo() {}", "pub(crate) unsafe fn foo() {}");
120 change_visibility,
121 "unsafe f<|>n foo() {}",
122 "<|>pub(crate) unsafe fn foo() {}",
123 );
124 } 128 }
125 129
126 #[test] 130 #[test]
@@ -128,13 +132,14 @@ mod tests {
128 check_assist( 132 check_assist(
129 change_visibility, 133 change_visibility,
130 r"struct S { <|>field: u32 }", 134 r"struct S { <|>field: u32 }",
131 r"struct S { <|>pub(crate) field: u32 }", 135 r"struct S { pub(crate) field: u32 }",
132 ) 136 );
137 check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( pub(crate) u32 )");
133 } 138 }
134 139
135 #[test] 140 #[test]
136 fn change_visibility_field_false_positive() { 141 fn change_visibility_field_false_positive() {
137 covers!(change_visibility_field_false_positive); 142 mark::check!(change_visibility_field_false_positive);
138 check_assist_not_applicable( 143 check_assist_not_applicable(
139 change_visibility, 144 change_visibility,
140 r"struct S { field: [(); { let <|>x = ();}] }", 145 r"struct S { field: [(); { let <|>x = ();}] }",
@@ -143,17 +148,17 @@ mod tests {
143 148
144 #[test] 149 #[test]
145 fn change_visibility_pub_to_pub_crate() { 150 fn change_visibility_pub_to_pub_crate() {
146 check_assist(change_visibility, "<|>pub fn foo() {}", "<|>pub(crate) fn foo() {}") 151 check_assist(change_visibility, "<|>pub fn foo() {}", "pub(crate) fn foo() {}")
147 } 152 }
148 153
149 #[test] 154 #[test]
150 fn change_visibility_pub_crate_to_pub() { 155 fn change_visibility_pub_crate_to_pub() {
151 check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "<|>pub fn foo() {}") 156 check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "pub fn foo() {}")
152 } 157 }
153 158
154 #[test] 159 #[test]
155 fn change_visibility_const() { 160 fn change_visibility_const() {
156 check_assist(change_visibility, "<|>const FOO = 3u8;", "<|>pub(crate) const FOO = 3u8;"); 161 check_assist(change_visibility, "<|>const FOO = 3u8;", "pub(crate) const FOO = 3u8;");
157 } 162 }
158 163
159 #[test] 164 #[test]
@@ -174,12 +179,21 @@ mod tests {
174 // comments 179 // comments
175 180
176 #[derive(Debug)] 181 #[derive(Debug)]
177 <|>pub(crate) struct Foo; 182 pub(crate) struct Foo;
178 ", 183 ",
179 ) 184 )
180 } 185 }
181 186
182 #[test] 187 #[test]
188 fn not_applicable_for_enum_variants() {
189 check_assist_not_applicable(
190 change_visibility,
191 r"mod foo { pub enum Foo {Foo1} }
192 fn main() { foo::Foo::Foo1<|> } ",
193 );
194 }
195
196 #[test]
183 fn change_visibility_target() { 197 fn change_visibility_target() {
184 check_assist_target(change_visibility, "<|>fn foo() {}", "fn"); 198 check_assist_target(change_visibility, "<|>fn foo() {}", "fn");
185 check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)"); 199 check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)");