aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api_light/src/assists/change_visibility.rs69
1 files changed, 59 insertions, 10 deletions
diff --git a/crates/ra_ide_api_light/src/assists/change_visibility.rs b/crates/ra_ide_api_light/src/assists/change_visibility.rs
index 89729e2c2..6e8bc2632 100644
--- a/crates/ra_ide_api_light/src/assists/change_visibility.rs
+++ b/crates/ra_ide_api_light/src/assists/change_visibility.rs
@@ -1,7 +1,7 @@
1use ra_syntax::{ 1use ra_syntax::{
2 AstNode, 2 AstNode, SyntaxNode, TextUnit,
3 ast::{self, VisibilityOwner, NameOwner}, 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}, 4 SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF, IDENT, WHITESPACE, COMMENT, ATTR},
5}; 5};
6 6
7use crate::assists::{AssistCtx, Assist}; 7use crate::assists::{AssistCtx, Assist};
@@ -30,14 +30,14 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
30 if parent.children().any(|child| child.kind() == VISIBILITY) { 30 if parent.children().any(|child| child.kind() == VISIBILITY) {
31 return None; 31 return None;
32 } 32 }
33 parent.range().start() 33 vis_offset(parent)
34 } else { 34 } else {
35 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?; 35 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?;
36 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?; 36 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?;
37 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() { 37 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() {
38 return None; 38 return None;
39 } 39 }
40 field.syntax().range().start() 40 vis_offset(field.syntax())
41 }; 41 };
42 42
43 ctx.build("make pub(crate)", |edit| { 43 ctx.build("make pub(crate)", |edit| {
@@ -46,14 +46,31 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
46 }) 46 })
47} 47}
48 48
49fn vis_offset(node: &SyntaxNode) -> TextUnit {
50 node.children()
51 .skip_while(|it| match it.kind() {
52 WHITESPACE | COMMENT | ATTR => true,
53 _ => false,
54 })
55 .next()
56 .map(|it| it.range().start())
57 .unwrap_or(node.range().start())
58}
59
49fn change_vis(ctx: AssistCtx, vis: &ast::Visibility) -> Option<Assist> { 60fn change_vis(ctx: AssistCtx, vis: &ast::Visibility) -> Option<Assist> {
50 if vis.syntax().text() != "pub" { 61 if vis.syntax().text() == "pub" {
51 return None; 62 return ctx.build("chage to pub(crate)", |edit| {
63 edit.replace(vis.syntax().range(), "pub(crate)");
64 edit.set_cursor(vis.syntax().range().start());
65 });
52 } 66 }
53 ctx.build("chage to pub(crate)", |edit| { 67 if vis.syntax().text() == "pub(crate)" {
54 edit.replace(vis.syntax().range(), "pub(crate)"); 68 return ctx.build("chage to pub", |edit| {
55 edit.set_cursor(vis.syntax().range().start()); 69 edit.replace(vis.syntax().range(), "pub");
56 }) 70 edit.set_cursor(vis.syntax().range().start());
71 });
72 }
73 None
57} 74}
58 75
59#[cfg(test)] 76#[cfg(test)]
@@ -113,4 +130,36 @@ mod tests {
113 "<|>pub(crate) fn foo() {}", 130 "<|>pub(crate) fn foo() {}",
114 ) 131 )
115 } 132 }
133
134 #[test]
135 fn change_visibility_pub_crate_to_pub() {
136 check_assist(
137 change_visibility,
138 "<|>pub(crate) fn foo() {}",
139 "<|>pub fn foo() {}",
140 )
141 }
142
143 #[test]
144 fn change_visibility_handles_comment_attrs() {
145 check_assist(
146 change_visibility,
147 "
148 /// docs
149
150 // comments
151
152 #[derive(Debug)]
153 <|>struct Foo;
154 ",
155 "
156 /// docs
157
158 // comments
159
160 #[derive(Debug)]
161 <|>pub(crate) struct Foo;
162 ",
163 )
164 }
116} 165}