aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/change_visibility.rs40
-rw-r--r--crates/ra_assists/src/marks.rs1
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs44
3 files changed, 55 insertions, 30 deletions
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs
index 54e0a6c84..cd6d1ee6c 100644
--- a/crates/ra_assists/src/handlers/change_visibility.rs
+++ b/crates/ra_assists/src/handlers/change_visibility.rs
@@ -2,13 +2,14 @@ use ra_syntax::{
2 ast::{self, NameOwner, VisibilityOwner}, 2 ast::{self, NameOwner, VisibilityOwner},
3 AstNode, 3 AstNode,
4 SyntaxKind::{ 4 SyntaxKind::{
5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, IDENT, MODULE, STRUCT_DEF, TRAIT_DEF, 5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY,
6 VISIBILITY, WHITESPACE, 6 WHITESPACE,
7 }, 7 },
8 SyntaxNode, TextUnit, T, 8 SyntaxNode, TextUnit, T,
9}; 9};
10 10
11use crate::{Assist, AssistCtx, AssistId}; 11use crate::{Assist, AssistCtx, AssistId};
12use test_utils::tested_by;
12 13
13// Assist: change_visibility 14// Assist: change_visibility
14// 15//
@@ -47,13 +48,16 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
47 } 48 }
48 (vis_offset(&parent), keyword.text_range()) 49 (vis_offset(&parent), keyword.text_range())
49 } else { 50 } else {
50 let ident = ctx.token_at_offset().find(|leaf| leaf.kind() == IDENT)?; 51 let field_name: ast::Name = ctx.find_node_at_offset()?;
51 let field = ident.parent().ancestors().find_map(ast::RecordFieldDef::cast)?; 52 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
52 if field.name()?.syntax().text_range() != ident.text_range() && field.visibility().is_some() 53 if field.name()? != field_name {
53 { 54 tested_by!(change_visibility_field_false_positive);
54 return None; 55 return None;
55 } 56 }
56 (vis_offset(field.syntax()), ident.text_range()) 57 if field.visibility().is_some() {
58 return None;
59 }
60 (vis_offset(field.syntax()), field_name.syntax().text_range())
57 }; 61 };
58 62
59 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| { 63 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| {
@@ -98,8 +102,11 @@ fn change_vis(ctx: AssistCtx, vis: ast::Visibility) -> Option<Assist> {
98 102
99#[cfg(test)] 103#[cfg(test)]
100mod tests { 104mod tests {
105 use test_utils::covers;
106
107 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
108
101 use super::*; 109 use super::*;
102 use crate::helpers::{check_assist, check_assist_target};
103 110
104 #[test] 111 #[test]
105 fn change_visibility_adds_pub_crate_to_items() { 112 fn change_visibility_adds_pub_crate_to_items() {
@@ -120,8 +127,17 @@ mod tests {
120 fn change_visibility_works_with_struct_fields() { 127 fn change_visibility_works_with_struct_fields() {
121 check_assist( 128 check_assist(
122 change_visibility, 129 change_visibility,
123 "struct S { <|>field: u32 }", 130 r"struct S { <|>field: u32 }",
124 "struct S { <|>pub(crate) field: u32 }", 131 r"struct S { <|>pub(crate) field: u32 }",
132 )
133 }
134
135 #[test]
136 fn change_visibility_field_false_positive() {
137 covers!(change_visibility_field_false_positive);
138 check_assist_not_applicable(
139 change_visibility,
140 r"struct S { field: [(); { let <|>x = ();}] }",
125 ) 141 )
126 } 142 }
127 143
@@ -144,7 +160,7 @@ mod tests {
144 fn change_visibility_handles_comment_attrs() { 160 fn change_visibility_handles_comment_attrs() {
145 check_assist( 161 check_assist(
146 change_visibility, 162 change_visibility,
147 " 163 r"
148 /// docs 164 /// docs
149 165
150 // comments 166 // comments
@@ -152,7 +168,7 @@ mod tests {
152 #[derive(Debug)] 168 #[derive(Debug)]
153 <|>struct Foo; 169 <|>struct Foo;
154 ", 170 ",
155 " 171 r"
156 /// docs 172 /// docs
157 173
158 // comments 174 // comments
diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs
index 22404ee80..6c2a2b8b6 100644
--- a/crates/ra_assists/src/marks.rs
+++ b/crates/ra_assists/src/marks.rs
@@ -7,4 +7,5 @@ test_utils::marks![
7 not_applicable_outside_of_bind_pat 7 not_applicable_outside_of_bind_pat
8 test_not_inline_mut_variable 8 test_not_inline_mut_variable
9 test_not_applicable_if_variable_unused 9 test_not_applicable_if_variable_unused
10 change_visibility_field_false_positive
10]; 11];
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 1cc2f6571..1033d6de9 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -734,19 +734,29 @@ pub fn handle_code_action(
734 res.push(fix.action.clone()); 734 res.push(fix.action.clone());
735 } 735 }
736 736
737 let mut grouped_assists: FxHashMap<String, Vec<Assist>> = FxHashMap::default(); 737 let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default();
738 for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { 738 for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() {
739 match &assist.group_label { 739 match &assist.group_label {
740 Some(label) => grouped_assists.entry(label.to_owned()).or_default().push(assist), 740 Some(label) => grouped_assists
741 None => res.push(create_single_code_action(assist, &world)?.into()), 741 .entry(label.to_owned())
742 .or_insert_with(|| {
743 let idx = res.len();
744 let dummy = Command::new(String::new(), String::new(), None);
745 res.push(dummy.into());
746 (idx, Vec::new())
747 })
748 .1
749 .push(assist),
750 None => {
751 res.push(create_single_code_action(assist, &world)?.into());
752 }
742 } 753 }
743 } 754 }
744 755
745 for (group_label, assists) in grouped_assists { 756 for (group_label, (idx, assists)) in grouped_assists {
746 if assists.len() == 1 { 757 if assists.len() == 1 {
747 res.push( 758 res[idx] =
748 create_single_code_action(assists.into_iter().next().unwrap(), &world)?.into(), 759 create_single_code_action(assists.into_iter().next().unwrap(), &world)?.into();
749 );
750 } else { 760 } else {
751 let title = group_label; 761 let title = group_label;
752 762
@@ -760,17 +770,15 @@ pub fn handle_code_action(
760 command: "rust-analyzer.selectAndApplySourceChange".to_string(), 770 command: "rust-analyzer.selectAndApplySourceChange".to_string(),
761 arguments: Some(vec![serde_json::Value::Array(arguments)]), 771 arguments: Some(vec![serde_json::Value::Array(arguments)]),
762 }); 772 });
763 res.push( 773 res[idx] = CodeAction {
764 CodeAction { 774 title,
765 title, 775 kind: None,
766 kind: None, 776 diagnostics: None,
767 diagnostics: None, 777 edit: None,
768 edit: None, 778 command,
769 command, 779 is_preferred: None,
770 is_preferred: None, 780 }
771 } 781 .into();
772 .into(),
773 );
774 } 782 }
775 } 783 }
776 784