aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists')
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_new.rs64
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};
5use hir::TypeRef; 5use ide_db::helpers::FamousDefs;
6use syntax::{ 6use 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
86fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> Option<bool> { 87fn 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)]
102mod tests { 98mod 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#"
112struct Example { _inner: () } 109struct 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#"
147struct Test { value: u32 } 143struct 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#"
179struct Example { _inner: () } 174struct 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#"
196struct Example { _inner: () } 190struct 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#"
213struct Example { _inner: () } 206struct 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#"
235fn n$0ew() -> u32 { 227fn 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#"
247struct Example { _inner: () } 238struct Example { _inner: () }
248struct Test { value: u32 } 239struct 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#"
280impl Example { 270impl 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#"
311mod test { 300mod 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#"
346mod test { 334mod 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}