aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/replace_derive_with_manual_impl.rs32
1 files changed, 12 insertions, 20 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..7f44d752f 100644
--- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -1,20 +1,9 @@
1use ide_db::helpers::mod_path_to_ast; 1use 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::{SyntaxKind::{IDENT, WHITESPACE}, TextSize, ast::{self, AstNode, NameOwner, make}};
5 ast::{self, make, AstNode}, 5
6 Direction, 6use crate::{AssistId, AssistKind, assist_context::{AssistBuilder, AssistContext, Assists}, utils::{Cursor, DefaultMethods, add_trait_assoc_items_to_impl, filter_assoc_items, generate_trait_impl_text, render_snippet}};
7 SyntaxKind::{IDENT, WHITESPACE},
8 TextSize,
9};
10
11use crate::{
12 assist_context::{AssistBuilder, AssistContext, Assists},
13 utils::{
14 add_trait_assoc_items_to_impl, filter_assoc_items, render_snippet, Cursor, DefaultMethods,
15 },
16 AssistId, AssistKind,
17};
18 7
19// Assist: replace_derive_with_manual_impl 8// Assist: replace_derive_with_manual_impl
20// 9//
@@ -57,8 +46,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")?; 46 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()))); 47 let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_token.text())));
59 48
60 let annotated_name = attr.syntax().siblings(Direction::Next).find_map(ast::Name::cast)?; 49 let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
61 let insert_pos = annotated_name.syntax().parent()?.text_range().end(); 50 let annotated_name = adt.name()?;
51 let insert_pos = adt.syntax().text_range().end();
62 52
63 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; 53 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?;
64 let current_crate = current_module.krate(); 54 let current_crate = current_module.krate();
@@ -82,10 +72,10 @@ pub(crate) fn replace_derive_with_manual_impl(
82 72
83 let mut no_traits_found = true; 73 let mut no_traits_found = true;
84 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { 74 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)?; 75 add_assist(acc, ctx, &attr, &trait_path, Some(trait_), &adt, &annotated_name, insert_pos)?;
86 } 76 }
87 if no_traits_found { 77 if no_traits_found {
88 add_assist(acc, ctx, &attr, &trait_path, None, &annotated_name, insert_pos)?; 78 add_assist(acc, ctx, &attr, &trait_path, None, &adt, &annotated_name, insert_pos)?;
89 } 79 }
90 Some(()) 80 Some(())
91} 81}
@@ -96,6 +86,7 @@ fn add_assist(
96 attr: &ast::Attr, 86 attr: &ast::Attr,
97 trait_path: &ast::Path, 87 trait_path: &ast::Path,
98 trait_: Option<hir::Trait>, 88 trait_: Option<hir::Trait>,
89 adt: &ast::Adt,
99 annotated_name: &ast::Name, 90 annotated_name: &ast::Name,
100 insert_pos: TextSize, 91 insert_pos: TextSize,
101) -> Option<()> { 92) -> Option<()> {
@@ -112,15 +103,16 @@ fn add_assist(
112 let impl_def_with_items = 103 let impl_def_with_items =
113 impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); 104 impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path);
114 update_attribute(builder, &input, &trait_name, &attr); 105 update_attribute(builder, &input, &trait_name, &attr);
106 let trait_path = format!("{}", trait_path);
115 match (ctx.config.snippet_cap, impl_def_with_items) { 107 match (ctx.config.snippet_cap, impl_def_with_items) {
116 (None, _) => builder.insert( 108 (None, _) => builder.insert(
117 insert_pos, 109 insert_pos,
118 format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), 110 generate_trait_impl_text(adt, &trait_path, ""),
119 ), 111 ),
120 (Some(cap), None) => builder.insert_snippet( 112 (Some(cap), None) => builder.insert_snippet(
121 cap, 113 cap,
122 insert_pos, 114 insert_pos,
123 format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), 115 generate_trait_impl_text(adt, &trait_path, " $0"),
124 ), 116 ),
125 (Some(cap), Some((impl_def, first_assoc_item))) => { 117 (Some(cap), Some((impl_def, first_assoc_item))) => {
126 let mut cursor = Cursor::Before(first_assoc_item.syntax()); 118 let mut cursor = Cursor::Before(first_assoc_item.syntax());