diff options
Diffstat (limited to 'crates/ide_assists/src')
-rw-r--r-- | crates/ide_assists/src/handlers/generate_default_from_new.rs | 64 |
1 files changed, 31 insertions, 33 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 2df5adc85..2eb0d6aad 100644 --- a/crates/ide_assists/src/handlers/generate_default_from_new.rs +++ b/crates/ide_assists/src/handlers/generate_default_from_new.rs | |||
@@ -2,7 +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 ide_db::helpers::FamousDefs; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | ast::{self, Impl, NameOwner}, | 7 | ast::{self, Impl, NameOwner}, |
8 | AstNode, | 8 | AstNode, |
@@ -53,7 +53,8 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | 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() { | 56 | let implements_default = is_default_implemented(ctx, &impl_)?; |
57 | if implements_default { | ||
57 | return None; | 58 | return None; |
58 | } | 59 | } |
59 | 60 | ||
@@ -85,29 +86,25 @@ impl Default for {} {{ | |||
85 | 86 | ||
86 | fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> Option<bool> { | 87 | fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> Option<bool> { |
87 | let db = ctx.sema.db; | 88 | let db = ctx.sema.db; |
88 | let module = impl_.syntax().parent()?; | 89 | let impl_def = ctx.sema.to_def(impl_)?; |
89 | let sema_scope = ctx.sema.scope(&module); | 90 | let ty = impl_def.target_ty(db); |
90 | let impls = sema_scope.module()?.impl_defs(db); | 91 | let krate = impl_def.module(db).krate(); |
91 | let mut name = None; | 92 | let default_trait = FamousDefs(&ctx.sema, Some(krate)).core_default_Default()?; |
92 | for i in impls { | 93 | let implements_default = ty.impls_trait(db, default_trait, &[]); |
93 | if let Some(TypeRef::Path(p)) = i.target_trait(db) { | 94 | Some(implements_default) |
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 | } | 95 | } |
100 | 96 | ||
101 | #[cfg(test)] | 97 | #[cfg(test)] |
102 | mod tests { | 98 | mod tests { |
99 | use ide_db::helpers::FamousDefs; | ||
100 | |||
103 | use crate::tests::{check_assist, check_assist_not_applicable}; | 101 | use crate::tests::{check_assist, check_assist_not_applicable}; |
104 | 102 | ||
105 | use super::*; | 103 | use super::*; |
106 | 104 | ||
107 | #[test] | 105 | #[test] |
108 | fn generate_default() { | 106 | fn generate_default() { |
109 | check_assist( | 107 | check_pass( |
110 | generate_default_from_new, | ||
111 | r#" | 108 | r#" |
112 | struct Example { _inner: () } | 109 | struct Example { _inner: () } |
113 | 110 | ||
@@ -141,8 +138,7 @@ fn main() {} | |||
141 | 138 | ||
142 | #[test] | 139 | #[test] |
143 | fn generate_default2() { | 140 | fn generate_default2() { |
144 | check_assist( | 141 | check_pass( |
145 | generate_default_from_new, | ||
146 | r#" | 142 | r#" |
147 | struct Test { value: u32 } | 143 | struct Test { value: u32 } |
148 | 144 | ||
@@ -173,8 +169,7 @@ impl Default for Test { | |||
173 | #[test] | 169 | #[test] |
174 | fn new_function_with_parameters() { | 170 | fn new_function_with_parameters() { |
175 | mark::check!(new_function_with_parameters); | 171 | mark::check!(new_function_with_parameters); |
176 | check_assist_not_applicable( | 172 | check_not_applicable( |
177 | generate_default_from_new, | ||
178 | r#" | 173 | r#" |
179 | struct Example { _inner: () } | 174 | struct Example { _inner: () } |
180 | 175 | ||
@@ -190,8 +185,7 @@ impl Example { | |||
190 | #[test] | 185 | #[test] |
191 | fn other_function_than_new() { | 186 | fn other_function_than_new() { |
192 | mark::check!(other_function_than_new); | 187 | mark::check!(other_function_than_new); |
193 | check_assist_not_applicable( | 188 | check_not_applicable( |
194 | generate_default_from_new, | ||
195 | r#" | 189 | r#" |
196 | struct Example { _inner: () } | 190 | struct Example { _inner: () } |
197 | 191 | ||
@@ -207,8 +201,7 @@ impl Exmaple { | |||
207 | 201 | ||
208 | #[test] | 202 | #[test] |
209 | fn default_block_is_already_present() { | 203 | fn default_block_is_already_present() { |
210 | check_assist_not_applicable( | 204 | check_not_applicable( |
211 | generate_default_from_new, | ||
212 | r#" | 205 | r#" |
213 | struct Example { _inner: () } | 206 | struct Example { _inner: () } |
214 | 207 | ||
@@ -229,8 +222,7 @@ impl Default for Example { | |||
229 | 222 | ||
230 | #[test] | 223 | #[test] |
231 | fn standalone_new_function() { | 224 | fn standalone_new_function() { |
232 | check_assist_not_applicable( | 225 | check_not_applicable( |
233 | generate_default_from_new, | ||
234 | r#" | 226 | r#" |
235 | fn n$0ew() -> u32 { | 227 | fn n$0ew() -> u32 { |
236 | 0 | 228 | 0 |
@@ -241,8 +233,7 @@ fn n$0ew() -> u32 { | |||
241 | 233 | ||
242 | #[test] | 234 | #[test] |
243 | fn multiple_struct_blocks() { | 235 | fn multiple_struct_blocks() { |
244 | check_assist( | 236 | check_pass( |
245 | generate_default_from_new, | ||
246 | r#" | 237 | r#" |
247 | struct Example { _inner: () } | 238 | struct Example { _inner: () } |
248 | struct Test { value: u32 } | 239 | struct Test { value: u32 } |
@@ -274,8 +265,7 @@ impl Default for Example { | |||
274 | 265 | ||
275 | #[test] | 266 | #[test] |
276 | fn when_struct_is_after_impl() { | 267 | fn when_struct_is_after_impl() { |
277 | check_assist( | 268 | check_pass( |
278 | generate_default_from_new, | ||
279 | r#" | 269 | r#" |
280 | impl Example { | 270 | impl Example { |
281 | pub fn $0new() -> Self { | 271 | pub fn $0new() -> Self { |
@@ -305,8 +295,7 @@ struct Example { _inner: () } | |||
305 | 295 | ||
306 | #[test] | 296 | #[test] |
307 | fn struct_in_module() { | 297 | fn struct_in_module() { |
308 | check_assist( | 298 | check_pass( |
309 | generate_default_from_new, | ||
310 | r#" | 299 | r#" |
311 | mod test { | 300 | mod test { |
312 | struct Example { _inner: () } | 301 | struct Example { _inner: () } |
@@ -340,8 +329,7 @@ impl Default for Example { | |||
340 | 329 | ||
341 | #[test] | 330 | #[test] |
342 | fn struct_in_module_with_default() { | 331 | fn struct_in_module_with_default() { |
343 | check_assist_not_applicable( | 332 | check_not_applicable( |
344 | generate_default_from_new, | ||
345 | r#" | 333 | r#" |
346 | mod test { | 334 | mod test { |
347 | struct Example { _inner: () } | 335 | struct Example { _inner: () } |
@@ -361,4 +349,14 @@ mod test { | |||
361 | "#, | 349 | "#, |
362 | ); | 350 | ); |
363 | } | 351 | } |
352 | |||
353 | fn check_pass(before: &str, after: &str) { | ||
354 | let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE); | ||
355 | check_assist(generate_default_from_new, before, after); | ||
356 | } | ||
357 | |||
358 | fn check_not_applicable(before: &str) { | ||
359 | let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE); | ||
360 | check_assist_not_applicable(generate_default_from_new, before); | ||
361 | } | ||
364 | } | 362 | } |