diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/handlers/replace_derive_with_manual_impl.rs | 32 |
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 @@ | |||
1 | use ide_db::helpers::mod_path_to_ast; | 1 | use ide_db::helpers::mod_path_to_ast; |
2 | use ide_db::imports_locator; | 2 | use ide_db::imports_locator; |
3 | use itertools::Itertools; | 3 | use itertools::Itertools; |
4 | use syntax::{ | 4 | use syntax::{SyntaxKind::{IDENT, WHITESPACE}, TextSize, ast::{self, AstNode, NameOwner, make}}; |
5 | ast::{self, make, AstNode}, | 5 | |
6 | Direction, | 6 | use 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 | |||
11 | use 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()); |