diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_assists/src/handlers/add_missing_impl_members.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_assists/src/handlers/add_missing_impl_members.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/add_missing_impl_members.rs | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs index abacd4065..95a750aee 100644 --- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs | |||
@@ -12,7 +12,7 @@ use crate::{ | |||
12 | assist_context::{AssistContext, Assists}, | 12 | assist_context::{AssistContext, Assists}, |
13 | ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, | 13 | ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, |
14 | utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor}, | 14 | utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor}, |
15 | AssistId, | 15 | AssistId, AssistKind, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(PartialEq)] | 18 | #[derive(PartialEq)] |
@@ -111,16 +111,17 @@ fn add_missing_impl_members_inner( | |||
111 | label: &'static str, | 111 | label: &'static str, |
112 | ) -> Option<()> { | 112 | ) -> Option<()> { |
113 | let _p = ra_prof::profile("add_missing_impl_members_inner"); | 113 | let _p = ra_prof::profile("add_missing_impl_members_inner"); |
114 | let impl_def = ctx.find_node_at_offset::<ast::ImplDef>()?; | 114 | let impl_def = ctx.find_node_at_offset::<ast::Impl>()?; |
115 | let impl_item_list = impl_def.item_list()?; | 115 | let impl_item_list = impl_def.assoc_item_list()?; |
116 | 116 | ||
117 | let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; | 117 | let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; |
118 | 118 | ||
119 | let def_name = |item: &ast::AssocItem| -> Option<SmolStr> { | 119 | let def_name = |item: &ast::AssocItem| -> Option<SmolStr> { |
120 | match item { | 120 | match item { |
121 | ast::AssocItem::FnDef(def) => def.name(), | 121 | ast::AssocItem::Fn(def) => def.name(), |
122 | ast::AssocItem::TypeAliasDef(def) => def.name(), | 122 | ast::AssocItem::TypeAlias(def) => def.name(), |
123 | ast::AssocItem::ConstDef(def) => def.name(), | 123 | ast::AssocItem::Const(def) => def.name(), |
124 | ast::AssocItem::MacroCall(_) => None, | ||
124 | } | 125 | } |
125 | .map(|it| it.text().clone()) | 126 | .map(|it| it.text().clone()) |
126 | }; | 127 | }; |
@@ -128,13 +129,13 @@ fn add_missing_impl_members_inner( | |||
128 | let missing_items = get_missing_assoc_items(&ctx.sema, &impl_def) | 129 | let missing_items = get_missing_assoc_items(&ctx.sema, &impl_def) |
129 | .iter() | 130 | .iter() |
130 | .map(|i| match i { | 131 | .map(|i| match i { |
131 | hir::AssocItem::Function(i) => ast::AssocItem::FnDef(i.source(ctx.db).value), | 132 | hir::AssocItem::Function(i) => ast::AssocItem::Fn(i.source(ctx.db()).value), |
132 | hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAliasDef(i.source(ctx.db).value), | 133 | hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAlias(i.source(ctx.db()).value), |
133 | hir::AssocItem::Const(i) => ast::AssocItem::ConstDef(i.source(ctx.db).value), | 134 | hir::AssocItem::Const(i) => ast::AssocItem::Const(i.source(ctx.db()).value), |
134 | }) | 135 | }) |
135 | .filter(|t| def_name(&t).is_some()) | 136 | .filter(|t| def_name(&t).is_some()) |
136 | .filter(|t| match t { | 137 | .filter(|t| match t { |
137 | ast::AssocItem::FnDef(def) => match mode { | 138 | ast::AssocItem::Fn(def) => match mode { |
138 | AddMissingImplMembersMode::DefaultMethodsOnly => def.body().is_some(), | 139 | AddMissingImplMembersMode::DefaultMethodsOnly => def.body().is_some(), |
139 | AddMissingImplMembersMode::NoDefaultMethods => def.body().is_none(), | 140 | AddMissingImplMembersMode::NoDefaultMethods => def.body().is_none(), |
140 | }, | 141 | }, |
@@ -147,7 +148,7 @@ fn add_missing_impl_members_inner( | |||
147 | } | 148 | } |
148 | 149 | ||
149 | let target = impl_def.syntax().text_range(); | 150 | let target = impl_def.syntax().text_range(); |
150 | acc.add(AssistId(assist_id), label, target, |builder| { | 151 | acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| { |
151 | let n_existing_items = impl_item_list.assoc_items().count(); | 152 | let n_existing_items = impl_item_list.assoc_items().count(); |
152 | let source_scope = ctx.sema.scope_for_def(trait_); | 153 | let source_scope = ctx.sema.scope_for_def(trait_); |
153 | let target_scope = ctx.sema.scope(impl_item_list.syntax()); | 154 | let target_scope = ctx.sema.scope(impl_item_list.syntax()); |
@@ -157,7 +158,8 @@ fn add_missing_impl_members_inner( | |||
157 | .into_iter() | 158 | .into_iter() |
158 | .map(|it| ast_transform::apply(&*ast_transform, it)) | 159 | .map(|it| ast_transform::apply(&*ast_transform, it)) |
159 | .map(|it| match it { | 160 | .map(|it| match it { |
160 | ast::AssocItem::FnDef(def) => ast::AssocItem::FnDef(add_body(def)), | 161 | ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)), |
162 | ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()), | ||
161 | _ => it, | 163 | _ => it, |
162 | }) | 164 | }) |
163 | .map(|it| edit::remove_attrs_and_docs(&it)); | 165 | .map(|it| edit::remove_attrs_and_docs(&it)); |
@@ -170,7 +172,7 @@ fn add_missing_impl_members_inner( | |||
170 | Some(cap) => { | 172 | Some(cap) => { |
171 | let mut cursor = Cursor::Before(first_new_item.syntax()); | 173 | let mut cursor = Cursor::Before(first_new_item.syntax()); |
172 | let placeholder; | 174 | let placeholder; |
173 | if let ast::AssocItem::FnDef(func) = &first_new_item { | 175 | if let ast::AssocItem::Fn(func) = &first_new_item { |
174 | if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) { | 176 | if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) { |
175 | if m.syntax().text() == "todo!()" { | 177 | if m.syntax().text() == "todo!()" { |
176 | placeholder = m; | 178 | placeholder = m; |
@@ -188,7 +190,7 @@ fn add_missing_impl_members_inner( | |||
188 | }) | 190 | }) |
189 | } | 191 | } |
190 | 192 | ||
191 | fn add_body(fn_def: ast::FnDef) -> ast::FnDef { | 193 | fn add_body(fn_def: ast::Fn) -> ast::Fn { |
192 | if fn_def.body().is_some() { | 194 | if fn_def.body().is_some() { |
193 | return fn_def; | 195 | return fn_def; |
194 | } | 196 | } |
@@ -684,4 +686,26 @@ impl Foo<T> for S<T> { | |||
684 | }"#, | 686 | }"#, |
685 | ) | 687 | ) |
686 | } | 688 | } |
689 | |||
690 | #[test] | ||
691 | fn test_assoc_type_bounds_are_removed() { | ||
692 | check_assist( | ||
693 | add_missing_impl_members, | ||
694 | r#" | ||
695 | trait Tr { | ||
696 | type Ty: Copy + 'static; | ||
697 | } | ||
698 | |||
699 | impl Tr for ()<|> { | ||
700 | }"#, | ||
701 | r#" | ||
702 | trait Tr { | ||
703 | type Ty: Copy + 'static; | ||
704 | } | ||
705 | |||
706 | impl Tr for () { | ||
707 | $0type Ty; | ||
708 | }"#, | ||
709 | ) | ||
710 | } | ||
687 | } | 711 | } |