aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r--crates/assists/src/handlers/generate_enum_match_method.rs41
-rw-r--r--crates/assists/src/handlers/generate_getter.rs40
-rw-r--r--crates/assists/src/handlers/generate_getter_mut.rs40
-rw-r--r--crates/assists/src/handlers/generate_new.rs4
-rw-r--r--crates/assists/src/handlers/generate_setter.rs40
-rw-r--r--crates/assists/src/handlers/inline_local_variable.rs109
6 files changed, 214 insertions, 60 deletions
diff --git a/crates/assists/src/handlers/generate_enum_match_method.rs b/crates/assists/src/handlers/generate_enum_match_method.rs
index c3ff38b66..aeb887e71 100644
--- a/crates/assists/src/handlers/generate_enum_match_method.rs
+++ b/crates/assists/src/handlers/generate_enum_match_method.rs
@@ -4,7 +4,7 @@ use syntax::ast::{self, AstNode, NameOwner};
4use test_utils::mark; 4use test_utils::mark;
5 5
6use crate::{ 6use crate::{
7 utils::{find_impl_block, find_struct_impl, generate_impl_text}, 7 utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
8 AssistContext, AssistId, AssistKind, Assists, 8 AssistContext, AssistId, AssistKind, Assists,
9}; 9};
10 10
@@ -80,7 +80,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
80 ); 80 );
81 81
82 let start_offset = impl_def 82 let start_offset = impl_def
83 .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) 83 .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
84 .unwrap_or_else(|| { 84 .unwrap_or_else(|| {
85 buf = generate_impl_text(&ast::Adt::Enum(parent_enum.clone()), &buf); 85 buf = generate_impl_text(&ast::Adt::Enum(parent_enum.clone()), &buf);
86 parent_enum.syntax().text_range().end() 86 parent_enum.syntax().text_range().end()
@@ -200,4 +200,41 @@ impl Variant {
200}"#, 200}"#,
201 ); 201 );
202 } 202 }
203
204 #[test]
205 fn test_multiple_generate_enum_match_from_variant() {
206 check_assist(
207 generate_enum_match_method,
208 r#"
209enum Variant {
210 Undefined,
211 Minor,
212 Major$0,
213}
214
215impl Variant {
216 /// Returns `true` if the variant is [`Minor`].
217 fn is_minor(&self) -> bool {
218 matches!(self, Self::Minor)
219 }
220}"#,
221 r#"enum Variant {
222 Undefined,
223 Minor,
224 Major,
225}
226
227impl Variant {
228 /// Returns `true` if the variant is [`Minor`].
229 fn is_minor(&self) -> bool {
230 matches!(self, Self::Minor)
231 }
232
233 /// Returns `true` if the variant is [`Major`].
234 fn is_major(&self) -> bool {
235 matches!(self, Self::Major)
236 }
237}"#,
238 );
239 }
203} 240}
diff --git a/crates/assists/src/handlers/generate_getter.rs b/crates/assists/src/handlers/generate_getter.rs
index b63dfce41..fbcf8b069 100644
--- a/crates/assists/src/handlers/generate_getter.rs
+++ b/crates/assists/src/handlers/generate_getter.rs
@@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
3use syntax::ast::{self, AstNode, NameOwner}; 3use syntax::ast::{self, AstNode, NameOwner};
4 4
5use crate::{ 5use crate::{
6 utils::{find_impl_block, find_struct_impl, generate_impl_text}, 6 utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
7 AssistContext, AssistId, AssistKind, Assists, 7 AssistContext, AssistId, AssistKind, Assists,
8}; 8};
9 9
@@ -73,7 +73,7 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
73 ); 73 );
74 74
75 let start_offset = impl_def 75 let start_offset = impl_def
76 .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) 76 .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
77 .unwrap_or_else(|| { 77 .unwrap_or_else(|| {
78 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf); 78 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
79 strukt.syntax().text_range().end() 79 strukt.syntax().text_range().end()
@@ -153,4 +153,40 @@ impl<T: Clone> Context<T> {
153}"#, 153}"#,
154 ); 154 );
155 } 155 }
156
157 #[test]
158 fn test_multiple_generate_getter() {
159 check_assist(
160 generate_getter,
161 r#"
162struct Context<T: Clone> {
163 data: T,
164 cou$0nt: usize,
165}
166
167impl<T: Clone> Context<T> {
168 /// Get a reference to the context's data.
169 fn data(&self) -> &T {
170 &self.data
171 }
172}"#,
173 r#"
174struct Context<T: Clone> {
175 data: T,
176 count: usize,
177}
178
179impl<T: Clone> Context<T> {
180 /// Get a reference to the context's data.
181 fn data(&self) -> &T {
182 &self.data
183 }
184
185 /// Get a reference to the context's count.
186 fn count(&self) -> &usize {
187 &self.count
188 }
189}"#,
190 );
191 }
156} 192}
diff --git a/crates/assists/src/handlers/generate_getter_mut.rs b/crates/assists/src/handlers/generate_getter_mut.rs
index b5085035e..bf0d99881 100644
--- a/crates/assists/src/handlers/generate_getter_mut.rs
+++ b/crates/assists/src/handlers/generate_getter_mut.rs
@@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
3use syntax::ast::{self, AstNode, NameOwner}; 3use syntax::ast::{self, AstNode, NameOwner};
4 4
5use crate::{ 5use crate::{
6 utils::{find_impl_block, find_struct_impl, generate_impl_text}, 6 utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
7 AssistContext, AssistId, AssistKind, Assists, 7 AssistContext, AssistId, AssistKind, Assists,
8}; 8};
9 9
@@ -76,7 +76,7 @@ pub(crate) fn generate_getter_mut(acc: &mut Assists, ctx: &AssistContext) -> Opt
76 ); 76 );
77 77
78 let start_offset = impl_def 78 let start_offset = impl_def
79 .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) 79 .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
80 .unwrap_or_else(|| { 80 .unwrap_or_else(|| {
81 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf); 81 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
82 strukt.syntax().text_range().end() 82 strukt.syntax().text_range().end()
@@ -156,4 +156,40 @@ impl<T: Clone> Context<T> {
156}"#, 156}"#,
157 ); 157 );
158 } 158 }
159
160 #[test]
161 fn test_multiple_generate_getter_mut() {
162 check_assist(
163 generate_getter_mut,
164 r#"
165struct Context<T: Clone> {
166 data: T,
167 cou$0nt: usize,
168}
169
170impl<T: Clone> Context<T> {
171 /// Get a mutable reference to the context's data.
172 fn data_mut(&mut self) -> &mut T {
173 &mut self.data
174 }
175}"#,
176 r#"
177struct Context<T: Clone> {
178 data: T,
179 count: usize,
180}
181
182impl<T: Clone> Context<T> {
183 /// Get a mutable reference to the context's data.
184 fn data_mut(&mut self) -> &mut T {
185 &mut self.data
186 }
187
188 /// Get a mutable reference to the context's count.
189 fn count_mut(&mut self) -> &mut usize {
190 &mut self.count
191 }
192}"#,
193 );
194 }
159} 195}
diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs
index c29077225..8ce5930b7 100644
--- a/crates/assists/src/handlers/generate_new.rs
+++ b/crates/assists/src/handlers/generate_new.rs
@@ -4,7 +4,7 @@ use stdx::format_to;
4use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner}; 4use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner};
5 5
6use crate::{ 6use crate::{
7 utils::{find_impl_block, find_struct_impl, generate_impl_text}, 7 utils::{find_impl_block_start, find_struct_impl, generate_impl_text},
8 AssistContext, AssistId, AssistKind, Assists, 8 AssistContext, AssistId, AssistKind, Assists,
9}; 9};
10 10
@@ -58,7 +58,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
58 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); 58 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
59 59
60 let start_offset = impl_def 60 let start_offset = impl_def
61 .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) 61 .and_then(|impl_def| find_impl_block_start(impl_def, &mut buf))
62 .unwrap_or_else(|| { 62 .unwrap_or_else(|| {
63 buf = generate_impl_text(&Adt::Struct(strukt.clone()), &buf); 63 buf = generate_impl_text(&Adt::Struct(strukt.clone()), &buf);
64 strukt.syntax().text_range().end() 64 strukt.syntax().text_range().end()
diff --git a/crates/assists/src/handlers/generate_setter.rs b/crates/assists/src/handlers/generate_setter.rs
index c9043a162..b655f9b9c 100644
--- a/crates/assists/src/handlers/generate_setter.rs
+++ b/crates/assists/src/handlers/generate_setter.rs
@@ -3,7 +3,7 @@ use syntax::ast::VisibilityOwner;
3use syntax::ast::{self, AstNode, NameOwner}; 3use syntax::ast::{self, AstNode, NameOwner};
4 4
5use crate::{ 5use crate::{
6 utils::{find_impl_block, find_struct_impl, generate_impl_text}, 6 utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
7 AssistContext, AssistId, AssistKind, Assists, 7 AssistContext, AssistId, AssistKind, Assists,
8}; 8};
9 9
@@ -79,7 +79,7 @@ pub(crate) fn generate_setter(acc: &mut Assists, ctx: &AssistContext) -> Option<
79 ); 79 );
80 80
81 let start_offset = impl_def 81 let start_offset = impl_def
82 .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) 82 .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
83 .unwrap_or_else(|| { 83 .unwrap_or_else(|| {
84 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf); 84 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
85 strukt.syntax().text_range().end() 85 strukt.syntax().text_range().end()
@@ -159,4 +159,40 @@ impl<T: Clone> Person<T> {
159}"#, 159}"#,
160 ); 160 );
161 } 161 }
162
163 #[test]
164 fn test_multiple_generate_setter() {
165 check_assist(
166 generate_setter,
167 r#"
168struct Context<T: Clone> {
169 data: T,
170 cou$0nt: usize,
171}
172
173impl<T: Clone> Context<T> {
174 /// Set the context's data.
175 fn set_data(&mut self, data: T) {
176 self.data = data;
177 }
178}"#,
179 r#"
180struct Context<T: Clone> {
181 data: T,
182 count: usize,
183}
184
185impl<T: Clone> Context<T> {
186 /// Set the context's data.
187 fn set_data(&mut self, data: T) {
188 self.data = data;
189 }
190
191 /// Set the context's count.
192 fn set_count(&mut self, count: usize) {
193 self.count = count;
194 }
195}"#,
196 );
197 }
162} 198}
diff --git a/crates/assists/src/handlers/inline_local_variable.rs b/crates/assists/src/handlers/inline_local_variable.rs
index 0e63a60e8..8d28431cf 100644
--- a/crates/assists/src/handlers/inline_local_variable.rs
+++ b/crates/assists/src/handlers/inline_local_variable.rs
@@ -1,7 +1,6 @@
1use ide_db::{ 1use std::collections::HashMap;
2 defs::Definition, 2
3 search::{FileReference, ReferenceKind}, 3use ide_db::{defs::Definition, search::FileReference};
4};
5use syntax::{ 4use syntax::{
6 ast::{self, AstNode, AstToken}, 5 ast::{self, AstNode, AstToken},
7 TextRange, 6 TextRange,
@@ -68,44 +67,51 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
68 67
69 let wrap_in_parens = usages 68 let wrap_in_parens = usages
70 .references 69 .references
71 .values() 70 .iter()
72 .flatten() 71 .map(|(&file_id, refs)| {
73 .map(|&FileReference { range, .. }| { 72 refs.iter()
74 let usage_node = 73 .map(|&FileReference { range, .. }| {
75 ctx.covering_node_for_range(range).ancestors().find_map(ast::PathExpr::cast)?; 74 let usage_node = ctx
76 let usage_parent_option = usage_node.syntax().parent().and_then(ast::Expr::cast); 75 .covering_node_for_range(range)
77 let usage_parent = match usage_parent_option { 76 .ancestors()
78 Some(u) => u, 77 .find_map(ast::PathExpr::cast)?;
79 None => return Ok(false), 78 let usage_parent_option =
80 }; 79 usage_node.syntax().parent().and_then(ast::Expr::cast);
81 80 let usage_parent = match usage_parent_option {
82 Ok(!matches!( 81 Some(u) => u,
83 (&initializer_expr, usage_parent), 82 None => return Ok(false),
84 (ast::Expr::CallExpr(_), _) 83 };
85 | (ast::Expr::IndexExpr(_), _) 84
86 | (ast::Expr::MethodCallExpr(_), _) 85 Ok(!matches!(
87 | (ast::Expr::FieldExpr(_), _) 86 (&initializer_expr, usage_parent),
88 | (ast::Expr::TryExpr(_), _) 87 (ast::Expr::CallExpr(_), _)
89 | (ast::Expr::RefExpr(_), _) 88 | (ast::Expr::IndexExpr(_), _)
90 | (ast::Expr::Literal(_), _) 89 | (ast::Expr::MethodCallExpr(_), _)
91 | (ast::Expr::TupleExpr(_), _) 90 | (ast::Expr::FieldExpr(_), _)
92 | (ast::Expr::ArrayExpr(_), _) 91 | (ast::Expr::TryExpr(_), _)
93 | (ast::Expr::ParenExpr(_), _) 92 | (ast::Expr::RefExpr(_), _)
94 | (ast::Expr::PathExpr(_), _) 93 | (ast::Expr::Literal(_), _)
95 | (ast::Expr::BlockExpr(_), _) 94 | (ast::Expr::TupleExpr(_), _)
96 | (ast::Expr::EffectExpr(_), _) 95 | (ast::Expr::ArrayExpr(_), _)
97 | (_, ast::Expr::CallExpr(_)) 96 | (ast::Expr::ParenExpr(_), _)
98 | (_, ast::Expr::TupleExpr(_)) 97 | (ast::Expr::PathExpr(_), _)
99 | (_, ast::Expr::ArrayExpr(_)) 98 | (ast::Expr::BlockExpr(_), _)
100 | (_, ast::Expr::ParenExpr(_)) 99 | (ast::Expr::EffectExpr(_), _)
101 | (_, ast::Expr::ForExpr(_)) 100 | (_, ast::Expr::CallExpr(_))
102 | (_, ast::Expr::WhileExpr(_)) 101 | (_, ast::Expr::TupleExpr(_))
103 | (_, ast::Expr::BreakExpr(_)) 102 | (_, ast::Expr::ArrayExpr(_))
104 | (_, ast::Expr::ReturnExpr(_)) 103 | (_, ast::Expr::ParenExpr(_))
105 | (_, ast::Expr::MatchExpr(_)) 104 | (_, ast::Expr::ForExpr(_))
106 )) 105 | (_, ast::Expr::WhileExpr(_))
106 | (_, ast::Expr::BreakExpr(_))
107 | (_, ast::Expr::ReturnExpr(_))
108 | (_, ast::Expr::MatchExpr(_))
109 ))
110 })
111 .collect::<Result<_, _>>()
112 .map(|b| (file_id, b))
107 }) 113 })
108 .collect::<Result<Vec<_>, _>>()?; 114 .collect::<Result<HashMap<_, Vec<_>>, _>>()?;
109 115
110 let init_str = initializer_expr.syntax().text().to_string(); 116 let init_str = initializer_expr.syntax().text().to_string();
111 let init_in_paren = format!("({})", &init_str); 117 let init_in_paren = format!("({})", &init_str);
@@ -117,16 +123,19 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
117 target, 123 target,
118 move |builder| { 124 move |builder| {
119 builder.delete(delete_range); 125 builder.delete(delete_range);
120 for (reference, should_wrap) in usages.references.values().flatten().zip(wrap_in_parens) 126 for (file_id, references) in usages.references {
121 { 127 for (&should_wrap, reference) in wrap_in_parens[&file_id].iter().zip(references) {
122 let replacement = 128 let replacement =
123 if should_wrap { init_in_paren.clone() } else { init_str.clone() }; 129 if should_wrap { init_in_paren.clone() } else { init_str.clone() };
124 match reference.kind { 130 match reference.name.as_name_ref() {
125 ReferenceKind::FieldShorthandForLocal => { 131 Some(name_ref)
126 mark::hit!(inline_field_shorthand); 132 if ast::RecordExprField::for_field_name(name_ref).is_some() =>
127 builder.insert(reference.range.end(), format!(": {}", replacement)) 133 {
134 mark::hit!(inline_field_shorthand);
135 builder.insert(reference.range.end(), format!(": {}", replacement));
136 }
137 _ => builder.replace(reference.range, replacement),
128 } 138 }
129 _ => builder.replace(reference.range, replacement),
130 } 139 }
131 } 140 }
132 }, 141 },