diff options
author | Chetan Khilosiya <[email protected]> | 2021-03-04 18:26:18 +0000 |
---|---|---|
committer | Chetan Khilosiya <[email protected]> | 2021-03-06 19:19:03 +0000 |
commit | b8e6d6a60674c84b1507383407cf6a88cd4200d6 (patch) | |
tree | fe0a25ff47f1a4dc0b86e094b4b1006372a85f57 | |
parent | a59a97ae04224b1de719d0f4d505f46e5e4ecb96 (diff) |
7708: Added the logic to check is default impl is already present.
Also added test cases for code present within module.
-rw-r--r-- | crates/ide_assists/src/handlers/generate_default_from_new.rs | 115 |
1 files changed, 97 insertions, 18 deletions
diff --git a/crates/ide_assists/src/handlers/generate_default_from_new.rs b/crates/ide_assists/src/handlers/generate_default_from_new.rs index 9592876b4..2df5adc85 100644 --- a/crates/ide_assists/src/handlers/generate_default_from_new.rs +++ b/crates/ide_assists/src/handlers/generate_default_from_new.rs | |||
@@ -2,6 +2,7 @@ use crate::{ | |||
2 | assist_context::{AssistContext, Assists}, | 2 | assist_context::{AssistContext, Assists}, |
3 | AssistId, | 3 | AssistId, |
4 | }; | 4 | }; |
5 | use hir::TypeRef; | ||
5 | use syntax::{ | 6 | use syntax::{ |
6 | ast::{self, Impl, NameOwner}, | 7 | ast::{self, Impl, NameOwner}, |
7 | AstNode, | 8 | AstNode, |
@@ -52,6 +53,9 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext) | |||
52 | } | 53 | } |
53 | 54 | ||
54 | let impl_ = fn_node.syntax().ancestors().into_iter().find_map(ast::Impl::cast)?; | 55 | let impl_ = fn_node.syntax().ancestors().into_iter().find_map(ast::Impl::cast)?; |
56 | if is_default_implemented(ctx, &impl_).is_some() { | ||
57 | return None; | ||
58 | } | ||
55 | 59 | ||
56 | let insert_location = impl_.syntax().text_range(); | 60 | let insert_location = impl_.syntax().text_range(); |
57 | 61 | ||
@@ -79,6 +83,21 @@ impl Default for {} {{ | |||
79 | ) | 83 | ) |
80 | } | 84 | } |
81 | 85 | ||
86 | fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> Option<bool> { | ||
87 | let db = ctx.sema.db; | ||
88 | let module = impl_.syntax().parent()?; | ||
89 | let sema_scope = ctx.sema.scope(&module); | ||
90 | let impls = sema_scope.module()?.impl_defs(db); | ||
91 | let mut name = None; | ||
92 | for i in impls { | ||
93 | if let Some(TypeRef::Path(p)) = i.target_trait(db) { | ||
94 | name = p.segments().iter().map(|s| s.name.to_string()).find(|n| n == "Default"); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | name.map(|n| !n.is_empty()) | ||
99 | } | ||
100 | |||
82 | #[cfg(test)] | 101 | #[cfg(test)] |
83 | mod tests { | 102 | mod tests { |
84 | use crate::tests::{check_assist, check_assist_not_applicable}; | 103 | use crate::tests::{check_assist, check_assist_not_applicable}; |
@@ -186,26 +205,27 @@ impl Exmaple { | |||
186 | ); | 205 | ); |
187 | } | 206 | } |
188 | 207 | ||
189 | // #[test] | 208 | #[test] |
190 | // fn default_block_is_already_present() { | 209 | fn default_block_is_already_present() { |
191 | // check_assist_not_applicable(generate_default_from_new, | 210 | check_assist_not_applicable( |
192 | // r#" | 211 | generate_default_from_new, |
193 | // struct Example { _inner: () } | 212 | r#" |
213 | struct Example { _inner: () } | ||
194 | 214 | ||
195 | // impl Exmaple { | 215 | impl Exmaple { |
196 | // pub fn n$0ew() -> Self { | 216 | pub fn n$0ew() -> Self { |
197 | // Self { _inner: () } | 217 | Self { _inner: () } |
198 | // } | 218 | } |
199 | // } | 219 | } |
200 | 220 | ||
201 | // impl Default for Example { | 221 | impl Default for Example { |
202 | // fn default() -> Self { | 222 | fn default() -> Self { |
203 | // Self::new() | 223 | Self::new() |
204 | // } | 224 | } |
205 | // } | 225 | } |
206 | // "#, | 226 | "#, |
207 | // ); | 227 | ); |
208 | // } | 228 | } |
209 | 229 | ||
210 | #[test] | 230 | #[test] |
211 | fn standalone_new_function() { | 231 | fn standalone_new_function() { |
@@ -282,4 +302,63 @@ struct Example { _inner: () } | |||
282 | "#, | 302 | "#, |
283 | ); | 303 | ); |
284 | } | 304 | } |
305 | |||
306 | #[test] | ||
307 | fn struct_in_module() { | ||
308 | check_assist( | ||
309 | generate_default_from_new, | ||
310 | r#" | ||
311 | mod test { | ||
312 | struct Example { _inner: () } | ||
313 | |||
314 | impl Example { | ||
315 | pub fn n$0ew() -> Self { | ||
316 | Self { _inner: () } | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | "#, | ||
321 | r#" | ||
322 | mod test { | ||
323 | struct Example { _inner: () } | ||
324 | |||
325 | impl Example { | ||
326 | pub fn new() -> Self { | ||
327 | Self { _inner: () } | ||
328 | } | ||
329 | } | ||
330 | |||
331 | impl Default for Example { | ||
332 | fn default() -> Self { | ||
333 | Self::new() | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | "#, | ||
338 | ); | ||
339 | } | ||
340 | |||
341 | #[test] | ||
342 | fn struct_in_module_with_default() { | ||
343 | check_assist_not_applicable( | ||
344 | generate_default_from_new, | ||
345 | r#" | ||
346 | mod test { | ||
347 | struct Example { _inner: () } | ||
348 | |||
349 | impl Example { | ||
350 | pub fn n$0ew() -> Self { | ||
351 | Self { _inner: () } | ||
352 | } | ||
353 | } | ||
354 | |||
355 | impl Default for Example { | ||
356 | fn default() -> Self { | ||
357 | Self::new() | ||
358 | } | ||
359 | } | ||
360 | } | ||
361 | "#, | ||
362 | ); | ||
363 | } | ||
285 | } | 364 | } |