aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/handlers/replace_derive_with_manual_impl.rs')
-rw-r--r--crates/assists/src/handlers/replace_derive_with_manual_impl.rs26
1 files changed, 14 insertions, 12 deletions
diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
index 6aa9d2f2c..c69bc5cac 100644
--- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -2,8 +2,7 @@ use ide_db::helpers::mod_path_to_ast;
2use ide_db::imports_locator; 2use ide_db::imports_locator;
3use itertools::Itertools; 3use itertools::Itertools;
4use syntax::{ 4use syntax::{
5 ast::{self, make, AstNode}, 5 ast::{self, make, AstNode, NameOwner},
6 Direction,
7 SyntaxKind::{IDENT, WHITESPACE}, 6 SyntaxKind::{IDENT, WHITESPACE},
8 TextSize, 7 TextSize,
9}; 8};
@@ -11,7 +10,8 @@ use syntax::{
11use crate::{ 10use crate::{
12 assist_context::{AssistBuilder, AssistContext, Assists}, 11 assist_context::{AssistBuilder, AssistContext, Assists},
13 utils::{ 12 utils::{
14 add_trait_assoc_items_to_impl, filter_assoc_items, render_snippet, Cursor, DefaultMethods, 13 add_trait_assoc_items_to_impl, filter_assoc_items, generate_trait_impl_text,
14 render_snippet, Cursor, DefaultMethods,
15 }, 15 },
16 AssistId, AssistKind, 16 AssistId, AssistKind,
17}; 17};
@@ -57,8 +57,9 @@ pub(crate) fn replace_derive_with_manual_impl(
57 let trait_token = ctx.token_at_offset().find(|t| t.kind() == IDENT && t.text() != "derive")?; 57 let trait_token = ctx.token_at_offset().find(|t| t.kind() == IDENT && t.text() != "derive")?;
58 let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_token.text()))); 58 let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_token.text())));
59 59
60 let annotated_name = attr.syntax().siblings(Direction::Next).find_map(ast::Name::cast)?; 60 let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
61 let insert_pos = annotated_name.syntax().parent()?.text_range().end(); 61 let annotated_name = adt.name()?;
62 let insert_pos = adt.syntax().text_range().end();
62 63
63 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; 64 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?;
64 let current_crate = current_module.krate(); 65 let current_crate = current_module.krate();
@@ -82,10 +83,10 @@ pub(crate) fn replace_derive_with_manual_impl(
82 83
83 let mut no_traits_found = true; 84 let mut no_traits_found = true;
84 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { 85 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) {
85 add_assist(acc, ctx, &attr, &trait_path, Some(trait_), &annotated_name, insert_pos)?; 86 add_assist(acc, ctx, &attr, &trait_path, Some(trait_), &adt, &annotated_name, insert_pos)?;
86 } 87 }
87 if no_traits_found { 88 if no_traits_found {
88 add_assist(acc, ctx, &attr, &trait_path, None, &annotated_name, insert_pos)?; 89 add_assist(acc, ctx, &attr, &trait_path, None, &adt, &annotated_name, insert_pos)?;
89 } 90 }
90 Some(()) 91 Some(())
91} 92}
@@ -96,6 +97,7 @@ fn add_assist(
96 attr: &ast::Attr, 97 attr: &ast::Attr,
97 trait_path: &ast::Path, 98 trait_path: &ast::Path,
98 trait_: Option<hir::Trait>, 99 trait_: Option<hir::Trait>,
100 adt: &ast::Adt,
99 annotated_name: &ast::Name, 101 annotated_name: &ast::Name,
100 insert_pos: TextSize, 102 insert_pos: TextSize,
101) -> Option<()> { 103) -> Option<()> {
@@ -112,15 +114,15 @@ fn add_assist(
112 let impl_def_with_items = 114 let impl_def_with_items =
113 impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); 115 impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path);
114 update_attribute(builder, &input, &trait_name, &attr); 116 update_attribute(builder, &input, &trait_name, &attr);
117 let trait_path = format!("{}", trait_path);
115 match (ctx.config.snippet_cap, impl_def_with_items) { 118 match (ctx.config.snippet_cap, impl_def_with_items) {
116 (None, _) => builder.insert( 119 (None, _) => {
117 insert_pos, 120 builder.insert(insert_pos, generate_trait_impl_text(adt, &trait_path, ""))
118 format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), 121 }
119 ),
120 (Some(cap), None) => builder.insert_snippet( 122 (Some(cap), None) => builder.insert_snippet(
121 cap, 123 cap,
122 insert_pos, 124 insert_pos,
123 format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), 125 generate_trait_impl_text(adt, &trait_path, " $0"),
124 ), 126 ),
125 (Some(cap), Some((impl_def, first_assoc_item))) => { 127 (Some(cap), Some((impl_def, first_assoc_item))) => {
126 let mut cursor = Cursor::Before(first_assoc_item.syntax()); 128 let mut cursor = Cursor::Before(first_assoc_item.syntax());