assist_context::{AssistContext, Assists},
AssistId,
};
+use hir::TypeRef;
use syntax::{
ast::{self, Impl, NameOwner},
AstNode,
}
let impl_ = fn_node.syntax().ancestors().into_iter().find_map(ast::Impl::cast)?;
+ if is_default_implemented(ctx, &impl_).is_some() {
+ return None;
+ }
let insert_location = impl_.syntax().text_range();
)
}
+fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> Option<bool> {
+ let db = ctx.sema.db;
+ let module = impl_.syntax().parent()?;
+ let sema_scope = ctx.sema.scope(&module);
+ let impls = sema_scope.module()?.impl_defs(db);
+ let mut name = None;
+ for i in impls {
+ if let Some(TypeRef::Path(p)) = i.target_trait(db) {
+ name = p.segments().iter().map(|s| s.name.to_string()).find(|n| n == "Default");
+ }
+ }
+
+ name.map(|n| !n.is_empty())
+}
+
#[cfg(test)]
mod tests {
use crate::tests::{check_assist, check_assist_not_applicable};
);
}
- // #[test]
- // fn default_block_is_already_present() {
- // check_assist_not_applicable(generate_default_from_new,
- // r#"
- // struct Example { _inner: () }
+ #[test]
+ fn default_block_is_already_present() {
+ check_assist_not_applicable(
+ generate_default_from_new,
+ r#"
+struct Example { _inner: () }
- // impl Exmaple {
- // pub fn n$0ew() -> Self {
- // Self { _inner: () }
- // }
- // }
+impl Exmaple {
+ pub fn n$0ew() -> Self {
+ Self { _inner: () }
+ }
+}
- // impl Default for Example {
- // fn default() -> Self {
- // Self::new()
- // }
- // }
- // "#,
- // );
- // }
+impl Default for Example {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+"#,
+ );
+ }
#[test]
fn standalone_new_function() {
}
struct Example { _inner: () }
+"#,
+ );
+ }
+
+ #[test]
+ fn struct_in_module() {
+ check_assist(
+ generate_default_from_new,
+ r#"
+mod test {
+ struct Example { _inner: () }
+
+ impl Example {
+ pub fn n$0ew() -> Self {
+ Self { _inner: () }
+ }
+ }
+}
+"#,
+ r#"
+mod test {
+ struct Example { _inner: () }
+
+ impl Example {
+ pub fn new() -> Self {
+ Self { _inner: () }
+ }
+ }
+
+impl Default for Example {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn struct_in_module_with_default() {
+ check_assist_not_applicable(
+ generate_default_from_new,
+ r#"
+mod test {
+ struct Example { _inner: () }
+
+ impl Example {
+ pub fn n$0ew() -> Self {
+ Self { _inner: () }
+ }
+ }
+
+ impl Default for Example {
+ fn default() -> Self {
+ Self::new()
+ }
+ }
+}
"#,
);
}