|
1 |
| -use ide_db::famous_defs::FamousDefs; |
| 1 | +use ide_db::{famous_defs::FamousDefs, traits::resolve_target_trait}; |
2 | 2 | use syntax::{
|
3 | 3 | AstNode,
|
4 | 4 | ast::{self, edit_in_place::Indent, make},
|
@@ -48,27 +48,19 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>
|
48 | 48 | let impl_def = ctx.find_node_at_offset::<ast::Impl>()?.clone_for_update();
|
49 | 49 | let indent = impl_def.indent_level();
|
50 | 50 |
|
51 |
| - let (apply_trait, new_apply_trait) = impl_def |
52 |
| - .syntax() |
53 |
| - .descendants() |
54 |
| - .filter_map(ast::NameRef::cast) |
55 |
| - .find_map(process_trait_name)?; |
56 |
| - |
57 |
| - let trait_ = impl_def.trait_()?; |
58 |
| - if let ast::Type::PathType(trait_path) = trait_ { |
59 |
| - let trait_type = ctx.sema.resolve_trait(&trait_path.path()?)?; |
60 |
| - let scope = ctx.sema.scope(trait_path.syntax())?; |
61 |
| - let famous_defs = FamousDefs(&ctx.sema, scope.krate()); |
62 |
| - if trait_type != get_famous(&apply_trait.text(), famous_defs)? { |
63 |
| - return None; |
64 |
| - } |
65 |
| - } |
| 51 | + let ast::Type::PathType(path) = impl_def.trait_()? else { |
| 52 | + return None; |
| 53 | + }; |
| 54 | + let trait_name = path.path()?.segment()?.name_ref()?; |
| 55 | + |
| 56 | + let scope = ctx.sema.scope(impl_def.trait_()?.syntax())?; |
| 57 | + let famous = FamousDefs(&ctx.sema, scope.krate()); |
| 58 | + |
| 59 | + let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; |
| 60 | + let trait_new = get_trait_mut(&trait_, famous)?; |
66 | 61 |
|
67 | 62 | // Index -> IndexMut
|
68 |
| - ted::replace( |
69 |
| - apply_trait.syntax(), |
70 |
| - make::path_segment(make::name_ref(new_apply_trait)).clone_for_update().syntax(), |
71 |
| - ); |
| 63 | + ted::replace(trait_name.syntax(), make::name_ref(trait_new).clone_for_update().syntax()); |
72 | 64 |
|
73 | 65 | // index -> index_mut
|
74 | 66 | let (trait_method_name, new_trait_method_name) = impl_def
|
@@ -108,31 +100,26 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>
|
108 | 100 | let target = impl_def.syntax().text_range();
|
109 | 101 | acc.add(
|
110 | 102 | AssistId::generate("generate_mut_trait_impl"),
|
111 |
| - format!("Generate `{new_apply_trait}` impl from this `{apply_trait}` trait"), |
| 103 | + format!("Generate `{trait_new}` impl from this `{trait_name}` trait"), |
112 | 104 | target,
|
113 | 105 | |edit| {
|
114 | 106 | edit.insert(target.start(), format!("$0{impl_def}\n\n{indent}"));
|
115 | 107 | },
|
116 | 108 | )
|
117 | 109 | }
|
118 | 110 |
|
119 |
| -fn get_famous(apply_trait: &str, famous: FamousDefs<'_, '_>) -> Option<hir::Trait> { |
120 |
| - match apply_trait { |
121 |
| - "Index" => famous.core_convert_Index(), |
122 |
| - "AsRef" => famous.core_convert_AsRef(), |
123 |
| - "Borrow" => famous.core_borrow_Borrow(), |
124 |
| - _ => None, |
| 111 | +fn get_trait_mut(apply_trait: &hir::Trait, famous: FamousDefs<'_, '_>) -> Option<&'static str> { |
| 112 | + let trait_ = Some(apply_trait); |
| 113 | + if trait_ == famous.core_convert_Index().as_ref() { |
| 114 | + return Some("IndexMut"); |
125 | 115 | }
|
126 |
| -} |
127 |
| - |
128 |
| -fn process_trait_name(name: ast::NameRef) -> Option<(ast::NameRef, &'static str)> { |
129 |
| - let new_name = match &*name.text() { |
130 |
| - "Index" => "IndexMut", |
131 |
| - "AsRef" => "AsMut", |
132 |
| - "Borrow" => "BorrowMut", |
133 |
| - _ => return None, |
134 |
| - }; |
135 |
| - Some((name, new_name)) |
| 116 | + if trait_ == famous.core_convert_AsRef().as_ref() { |
| 117 | + return Some("AsMut"); |
| 118 | + } |
| 119 | + if trait_ == famous.core_borrow_Borrow().as_ref() { |
| 120 | + return Some("BorrowMut"); |
| 121 | + } |
| 122 | + None |
136 | 123 | }
|
137 | 124 |
|
138 | 125 | fn process_method_name(name: ast::Name) -> Option<(ast::Name, &'static str)> {
|
|
0 commit comments