diff options
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r-- | crates/assists/src/handlers/generate_enum_match_method.rs | 41 | ||||
-rw-r--r-- | crates/assists/src/handlers/generate_getter.rs | 40 | ||||
-rw-r--r-- | crates/assists/src/handlers/generate_getter_mut.rs | 40 | ||||
-rw-r--r-- | crates/assists/src/handlers/generate_new.rs | 4 | ||||
-rw-r--r-- | crates/assists/src/handlers/generate_setter.rs | 40 | ||||
-rw-r--r-- | crates/assists/src/handlers/inline_local_variable.rs | 109 |
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}; | |||
4 | use test_utils::mark; | 4 | use test_utils::mark; |
5 | 5 | ||
6 | use crate::{ | 6 | use 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#" | ||
209 | enum Variant { | ||
210 | Undefined, | ||
211 | Minor, | ||
212 | Major$0, | ||
213 | } | ||
214 | |||
215 | impl 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 | |||
227 | impl 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; | |||
3 | use syntax::ast::{self, AstNode, NameOwner}; | 3 | use syntax::ast::{self, AstNode, NameOwner}; |
4 | 4 | ||
5 | use crate::{ | 5 | use 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#" | ||
162 | struct Context<T: Clone> { | ||
163 | data: T, | ||
164 | cou$0nt: usize, | ||
165 | } | ||
166 | |||
167 | impl<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#" | ||
174 | struct Context<T: Clone> { | ||
175 | data: T, | ||
176 | count: usize, | ||
177 | } | ||
178 | |||
179 | impl<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; | |||
3 | use syntax::ast::{self, AstNode, NameOwner}; | 3 | use syntax::ast::{self, AstNode, NameOwner}; |
4 | 4 | ||
5 | use crate::{ | 5 | use 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#" | ||
165 | struct Context<T: Clone> { | ||
166 | data: T, | ||
167 | cou$0nt: usize, | ||
168 | } | ||
169 | |||
170 | impl<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#" | ||
177 | struct Context<T: Clone> { | ||
178 | data: T, | ||
179 | count: usize, | ||
180 | } | ||
181 | |||
182 | impl<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; | |||
4 | use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner}; | 4 | use syntax::ast::{self, AstNode, NameOwner, StructKind, VisibilityOwner}; |
5 | 5 | ||
6 | use crate::{ | 6 | use 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; | |||
3 | use syntax::ast::{self, AstNode, NameOwner}; | 3 | use syntax::ast::{self, AstNode, NameOwner}; |
4 | 4 | ||
5 | use crate::{ | 5 | use 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#" | ||
168 | struct Context<T: Clone> { | ||
169 | data: T, | ||
170 | cou$0nt: usize, | ||
171 | } | ||
172 | |||
173 | impl<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#" | ||
180 | struct Context<T: Clone> { | ||
181 | data: T, | ||
182 | count: usize, | ||
183 | } | ||
184 | |||
185 | impl<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 @@ | |||
1 | use ide_db::{ | 1 | use std::collections::HashMap; |
2 | defs::Definition, | 2 | |
3 | search::{FileReference, ReferenceKind}, | 3 | use ide_db::{defs::Definition, search::FileReference}; |
4 | }; | ||
5 | use syntax::{ | 4 | use 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 | }, |