Skip to content

Commit b8e6d6a

Browse files
7708: Added the logic to check is default impl is already present.
Also added test cases for code present within module.
1 parent a59a97a commit b8e6d6a

File tree

1 file changed

+97
-18
lines changed

1 file changed

+97
-18
lines changed

crates/ide_assists/src/handlers/generate_default_from_new.rs

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{
22
assist_context::{AssistContext, Assists},
33
AssistId,
44
};
5+
use hir::TypeRef;
56
use syntax::{
67
ast::{self, Impl, NameOwner},
78
AstNode,
@@ -52,6 +53,9 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext)
5253
}
5354

5455
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+
}
5559

5660
let insert_location = impl_.syntax().text_range();
5761

@@ -79,6 +83,21 @@ impl Default for {} {{
7983
)
8084
}
8185

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+
82101
#[cfg(test)]
83102
mod tests {
84103
use crate::tests::{check_assist, check_assist_not_applicable};
@@ -186,26 +205,27 @@ impl Exmaple {
186205
);
187206
}
188207

189-
// #[test]
190-
// fn default_block_is_already_present() {
191-
// check_assist_not_applicable(generate_default_from_new,
192-
// r#"
193-
// struct Example { _inner: () }
208+
#[test]
209+
fn default_block_is_already_present() {
210+
check_assist_not_applicable(
211+
generate_default_from_new,
212+
r#"
213+
struct Example { _inner: () }
194214
195-
// impl Exmaple {
196-
// pub fn n$0ew() -> Self {
197-
// Self { _inner: () }
198-
// }
199-
// }
215+
impl Exmaple {
216+
pub fn n$0ew() -> Self {
217+
Self { _inner: () }
218+
}
219+
}
200220
201-
// impl Default for Example {
202-
// fn default() -> Self {
203-
// Self::new()
204-
// }
205-
// }
206-
// "#,
207-
// );
208-
// }
221+
impl Default for Example {
222+
fn default() -> Self {
223+
Self::new()
224+
}
225+
}
226+
"#,
227+
);
228+
}
209229

210230
#[test]
211231
fn standalone_new_function() {
@@ -279,6 +299,65 @@ impl Default for Example {
279299
}
280300
281301
struct Example { _inner: () }
302+
"#,
303+
);
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+
}
282361
"#,
283362
);
284363
}

0 commit comments

Comments
 (0)